From 3fbacce3fe322b6636b133e74087d49bff906324 Mon Sep 17 00:00:00 2001 From: fede Date: Sun, 23 Nov 2025 17:42:52 -0300 Subject: [PATCH] =?UTF-8?q?a=C3=B1adido=20componente=20para=20crear=20post?= =?UTF-8?q?s=20y=20modificado=20menu=20auth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/components/crear-post.svelte | 34 +++++ .../ui/avatar/avatar-fallback.svelte | 17 +++ .../components/ui/avatar/avatar-image.svelte | 17 +++ src/lib/components/ui/avatar/avatar.svelte | 19 +++ src/lib/components/ui/avatar/index.ts | 13 ++ src/lib/components/ui/input-group/index.ts | 22 +++ .../ui/input-group/input-group-addon.svelte | 55 +++++++ .../ui/input-group/input-group-button.svelte | 49 ++++++ .../ui/input-group/input-group-input.svelte | 23 +++ .../ui/input-group/input-group-text.svelte | 22 +++ .../input-group/input-group-textarea.svelte | 23 +++ .../ui/input-group/input-group.svelte | 38 +++++ src/lib/components/ui/kbd/index.ts | 10 ++ src/lib/components/ui/kbd/kbd-group.svelte | 20 +++ src/lib/components/ui/kbd/kbd.svelte | 25 +++ src/lib/components/ui/textarea/index.ts | 7 + .../components/ui/textarea/textarea.svelte | 23 +++ src/lib/head/AvatarButton.svelte | 34 +++++ src/lib/head/Header.svelte | 142 +++++++++--------- src/lib/hooks/logout.ts | 25 +++ src/lib/stores/usuario.ts | 11 +- src/routes/+page.svelte | 103 +++++++------ src/routes/[perfil]/+page.svelte | 0 src/types.d.ts | 8 +- 24 files changed, 618 insertions(+), 122 deletions(-) create mode 100644 src/lib/components/crear-post.svelte create mode 100644 src/lib/components/ui/avatar/avatar-fallback.svelte create mode 100644 src/lib/components/ui/avatar/avatar-image.svelte create mode 100644 src/lib/components/ui/avatar/avatar.svelte create mode 100644 src/lib/components/ui/avatar/index.ts create mode 100644 src/lib/components/ui/input-group/index.ts create mode 100644 src/lib/components/ui/input-group/input-group-addon.svelte create mode 100644 src/lib/components/ui/input-group/input-group-button.svelte create mode 100644 src/lib/components/ui/input-group/input-group-input.svelte create mode 100644 src/lib/components/ui/input-group/input-group-text.svelte create mode 100644 src/lib/components/ui/input-group/input-group-textarea.svelte create mode 100644 src/lib/components/ui/input-group/input-group.svelte create mode 100644 src/lib/components/ui/kbd/index.ts create mode 100644 src/lib/components/ui/kbd/kbd-group.svelte create mode 100644 src/lib/components/ui/kbd/kbd.svelte create mode 100644 src/lib/components/ui/textarea/index.ts create mode 100644 src/lib/components/ui/textarea/textarea.svelte create mode 100644 src/lib/head/AvatarButton.svelte create mode 100644 src/lib/hooks/logout.ts create mode 100644 src/routes/[perfil]/+page.svelte diff --git a/src/lib/components/crear-post.svelte b/src/lib/components/crear-post.svelte new file mode 100644 index 0000000..eb674e6 --- /dev/null +++ b/src/lib/components/crear-post.svelte @@ -0,0 +1,34 @@ + + + + + + +
+ +

229}> + {mensaje.length} +

+ / 255 +
+ +

Publicar

+ +
+
+
+
diff --git a/src/lib/components/ui/avatar/avatar-fallback.svelte b/src/lib/components/ui/avatar/avatar-fallback.svelte new file mode 100644 index 0000000..249d4a4 --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-fallback.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/avatar/avatar-image.svelte b/src/lib/components/ui/avatar/avatar-image.svelte new file mode 100644 index 0000000..2bb9db4 --- /dev/null +++ b/src/lib/components/ui/avatar/avatar-image.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/avatar/avatar.svelte b/src/lib/components/ui/avatar/avatar.svelte new file mode 100644 index 0000000..e37214d --- /dev/null +++ b/src/lib/components/ui/avatar/avatar.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/avatar/index.ts b/src/lib/components/ui/avatar/index.ts new file mode 100644 index 0000000..d06457b --- /dev/null +++ b/src/lib/components/ui/avatar/index.ts @@ -0,0 +1,13 @@ +import Root from "./avatar.svelte"; +import Image from "./avatar-image.svelte"; +import Fallback from "./avatar-fallback.svelte"; + +export { + Root, + Image, + Fallback, + // + Root as Avatar, + Image as AvatarImage, + Fallback as AvatarFallback, +}; diff --git a/src/lib/components/ui/input-group/index.ts b/src/lib/components/ui/input-group/index.ts new file mode 100644 index 0000000..fe1f55d --- /dev/null +++ b/src/lib/components/ui/input-group/index.ts @@ -0,0 +1,22 @@ +import Root from "./input-group.svelte"; +import Addon from "./input-group-addon.svelte"; +import Button from "./input-group-button.svelte"; +import Input from "./input-group-input.svelte"; +import Text from "./input-group-text.svelte"; +import Textarea from "./input-group-textarea.svelte"; + +export { + Root, + Addon, + Button, + Input, + Text, + Textarea, + // + Root as InputGroup, + Addon as InputGroupAddon, + Button as InputGroupButton, + Input as InputGroupInput, + Text as InputGroupText, + Textarea as InputGroupTextarea, +}; diff --git a/src/lib/components/ui/input-group/input-group-addon.svelte b/src/lib/components/ui/input-group/input-group-addon.svelte new file mode 100644 index 0000000..09f2b64 --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-addon.svelte @@ -0,0 +1,55 @@ + + + + +
{ + if ((e.target as HTMLElement).closest("button")) { + return; + } + e.currentTarget.parentElement?.querySelector("input")?.focus(); + }} + {...restProps} +> + {@render children?.()} +
diff --git a/src/lib/components/ui/input-group/input-group-button.svelte b/src/lib/components/ui/input-group/input-group-button.svelte new file mode 100644 index 0000000..d38a71e --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-button.svelte @@ -0,0 +1,49 @@ + + + + + diff --git a/src/lib/components/ui/input-group/input-group-input.svelte b/src/lib/components/ui/input-group/input-group-input.svelte new file mode 100644 index 0000000..ded2655 --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-input.svelte @@ -0,0 +1,23 @@ + + + diff --git a/src/lib/components/ui/input-group/input-group-text.svelte b/src/lib/components/ui/input-group/input-group-text.svelte new file mode 100644 index 0000000..332f63d --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-text.svelte @@ -0,0 +1,22 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/input-group/input-group-textarea.svelte b/src/lib/components/ui/input-group/input-group-textarea.svelte new file mode 100644 index 0000000..91850ff --- /dev/null +++ b/src/lib/components/ui/input-group/input-group-textarea.svelte @@ -0,0 +1,23 @@ + + + diff --git a/src/lib/head/AvatarButton.svelte b/src/lib/head/AvatarButton.svelte new file mode 100644 index 0000000..2d28b2c --- /dev/null +++ b/src/lib/head/AvatarButton.svelte @@ -0,0 +1,34 @@ + + + + + + + {$sesionStore?.displayName[0]} + + + + + + Mi Perfil + + + await logout(menuOpen)}>Cerrar Sesion + + + diff --git a/src/lib/head/Header.svelte b/src/lib/head/Header.svelte index 7f75a0d..1791b52 100644 --- a/src/lib/head/Header.svelte +++ b/src/lib/head/Header.svelte @@ -8,43 +8,40 @@ import { onMount } from 'svelte'; import { apiBase } from '@/stores/url'; import { goto } from '$app/navigation'; + import AvatarButton from './AvatarButton.svelte'; let menuOpen = $state(false); const toggleMenu = () => (menuOpen = !menuOpen); - let showCerrarSesion = $state(false); + let showCerrarSesion = $state(false); - onMount(()=>{ - sesionStore.subscribe((value)=>{ - showCerrarSesion = !!value?.accessToken; - }) + onMount(() => { + sesionStore.subscribe((value) => { + showCerrarSesion = !!value?.accessToken; + }); + }); - }); - - async function cerrarSesion(){ - try{ - const req = await fetch($apiBase+"/api/auth/logout", { - method: 'POST', - headers: { - "Content-Type": "application/json", - "Authorization": `Bearer ${$sesionStore?.accessToken}` - - }, - credentials: "include" - }); - if(req.ok){ - - sesionStore.reset(); - menuOpen = false; - } - }catch{ - console.log("fallo el lougout") - } finally{ - sesionStore.reset(); - goto("/"); - } - - } + async function cerrarSesion() { + try { + const req = await fetch($apiBase + '/api/auth/logout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${$sesionStore?.accessToken}` + }, + credentials: 'include' + }); + if (req.ok) { + sesionStore.reset(); + menuOpen = false; + } + } catch { + console.log('fallo el lougout'); + } finally { + sesionStore.reset(); + goto('/'); + } + }
@@ -53,31 +50,38 @@

Mini-X

-
diff --git a/src/lib/hooks/logout.ts b/src/lib/hooks/logout.ts new file mode 100644 index 0000000..9fe4b4e --- /dev/null +++ b/src/lib/hooks/logout.ts @@ -0,0 +1,25 @@ +import { goto } from '$app/navigation'; +import { apiBase } from '@/stores/url'; +import { sesionStore } from '@/stores/usuario'; + +export async function logout(menuOpen: boolean) { + try { + const req = await fetch($apiBase + '/api/auth/logout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${$sesionStore.accessToken}` + }, + credentials: 'include' + }); + if (req.ok) { + sesionStore.reset(); + menuOpen = false; + } + } catch { + console.log('fallo el lougout'); + } finally { + sesionStore.reset(); + goto('/'); + } +} diff --git a/src/lib/stores/usuario.ts b/src/lib/stores/usuario.ts index 649b18b..d109b99 100644 --- a/src/lib/stores/usuario.ts +++ b/src/lib/stores/usuario.ts @@ -1,7 +1,16 @@ import { writable } from 'svelte/store'; +import { browser } from '$app/environment'; import type { Sesion } from '../../types'; -export const currentSesion = writable(null); +const initialValue = browser ? JSON.parse(localStorage.getItem('sesion') || 'null') : null; + +export const currentSesion = writable(initialValue); + +if (browser) { + currentSesion.subscribe((value) => { + localStorage.setItem('sesion', JSON.stringify(value)); + }); +} export const sesionStore = { subscribe: currentSesion.subscribe, diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 03797f5..f7f8c0e 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -2,65 +2,72 @@ import Card from '@/components/ui/card/card.svelte'; import type { Post } from '../types'; import { Content } from '@/components/ui/card'; - import { apiBase } from '@/stores/url'; + import { apiBase } from '@/stores/url'; + import { sesionStore } from '@/stores/usuario'; + import CrearPost from '@/components/crear-post.svelte'; - $effect(()=>{ - getPosts(); - }); + $effect(() => { + getPosts(); + }); - let posts: Post[] = $state([]); + let posts: Post[] = $state([]); - async function getPosts() { - const { subscribe } = apiBase; - let baseUrl: string = ''; + async function getPosts() { + const { subscribe } = apiBase; + let baseUrl: string = ''; - subscribe((value) => { - baseUrl = value; - })(); - - const req = await fetch(`${baseUrl}/api/posts/timeline?pageSize=3`); - if (req.ok){ - posts = await req.json(); - } - - } + subscribe((value) => { + baseUrl = value; + })(); + const req = await fetch(`${baseUrl}/api/posts/timeline?pageSize=3`); + if (req.ok) { + posts = await req.json(); + } + }
-
- {#if posts.length <= 0} - - -

No hay Posts que mostrar

-
-
- {:else} - {#each posts as post} +
+
+ {#if $sesionStore !== null} + + {/if} +
+ + {#if posts.length <= 0} -
-
- {post.authorId} - {post.createdAt.toLocaleDateString()} -
-

{post.content}

- {#if post.imageUrl} - Post - {/if} -
- {post.likesCount} likes - {post.repliesCount} replies - {#if post.isEdited} - Editado - {/if} -
-
+

No hay Posts que mostrar

- {/each} - {/if} + {:else} + {#each posts as post} + + +
+
+ {post.authorId} + {post.createdAt.toLocaleDateString()} +
+

{post.content}

+ {#if post.imageUrl} + Post + {/if} +
+ {post.likesCount} likes + {post.repliesCount} replies + {#if post.isEdited} + Editado + {/if} +
+
+
+
+ {/each} + {/if} +
diff --git a/src/routes/[perfil]/+page.svelte b/src/routes/[perfil]/+page.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/types.d.ts b/src/types.d.ts index bc001ff..8f6cff6 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -27,10 +27,10 @@ export interface User { } export interface Sesion { - accessToken:string?; - message:string; - url:string; - displayname:string; + accessToken: string?; + message: string; + url: string; + displayName: string; } export interface LoginDto {