empece a armar la ui para la pagina de perfil

This commit is contained in:
2025-11-24 19:45:08 -03:00
parent a8dc380d03
commit dd49f853b4
5 changed files with 112 additions and 3 deletions

View File

@@ -0,0 +1 @@
export { default as Spinner } from "./spinner.svelte";

View File

@@ -0,0 +1,14 @@
<script lang="ts">
import { cn } from "$lib/utils.js";
import Loader2Icon from "@lucide/svelte/icons/loader-2";
import type { ComponentProps } from "svelte";
let { class: className, ...restProps }: ComponentProps<typeof Loader2Icon> = $props();
</script>
<Loader2Icon
role="status"
aria-label="Loading"
class={cn("size-4 animate-spin", className)}
{...restProps}
/>

View File

@@ -1,4 +1,5 @@
<script>
import { goto } from '$app/navigation';
import AvatarFallback from '@/components/ui/avatar/avatar-fallback.svelte';
import AvatarImage from '@/components/ui/avatar/avatar-image.svelte';
import Avatar from '@/components/ui/avatar/avatar.svelte';
@@ -23,9 +24,9 @@
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem>
<a href={'/'}> Mi Perfil </a>
</DropdownMenuItem>
<DropdownMenuItem onclick={() => goto('/' + $sesionStore?.username)}
>Mi Perfil</DropdownMenuItem
>
<DropdownMenuSeparator />
<DropdownMenuItem onclick={async () => await logout(menuOpen)}>Cerrar Sesion</DropdownMenuItem
>

View File

@@ -0,0 +1,92 @@
<script lang="ts">
import { apiBase } from '@/stores/url';
import Ban from '@lucide/svelte/icons/ban';
import Card from '@/components/ui/card/card.svelte';
import Avatar from '@/components/ui/avatar/avatar.svelte';
import AvatarImage from '@/components/ui/avatar/avatar-image.svelte';
import AvatarFallback from '@/components/ui/avatar/avatar-fallback.svelte';
import { CardContent } from '@/components/ui/card';
import type { Post } from '../../types.js';
import Spinner from '@/components/ui/spinner/spinner.svelte';
import { fade, slide } from 'svelte/transition';
let { params } = $props();
let posts: Post[] = $state([]);
let cargando = $state(true);
let mensajeError = $state('');
const { subscribe } = apiBase;
let baseUrl: string = '';
subscribe((value) => {
baseUrl = value;
})();
$effect(() => {
obtenerPosts();
});
async function obtenerPosts() {
try {
const req = await fetch(baseUrl + '/api/posts/user/' + params.perfil, {
method: 'GET'
});
if (req.ok) {
posts = await req.json();
return;
}
mensajeError = 'Fallo al obtener los datos';
} catch {
mensajeError = 'No se alcanzo el servidor';
} finally {
cargando = false;
}
}
</script>
<div class="flex min-h-fit w-full items-center justify-center p-6 md:p-10">
<div class="w-full max-w-2xl">
<Card class="mb-2 overflow-hidden">
<CardContent>
<div class="flex justify-center">
<Avatar class="mt-2 scale-250 border-2 border-slate-950">
<AvatarImage></AvatarImage>
<AvatarFallback>{params.perfil[0].toUpperCase()}</AvatarFallback>
</Avatar>
</div>
<h1
class="mt-10 scroll-m-20 text-center text-2xl font-extrabold tracking-tight lg:text-5xl"
>
{'test'}
</h1>
<h3 class="scroll-m-20 text-center text-2xl tracking-tight text-muted-foreground">
@{params.perfil}
</h3>
</CardContent>
</Card>
<h1 class="mt-10 scroll-m-20 text-3xl font-extrabold tracking-tight lg:text-3xl">Posts:</h1>
<hr class="mb-8" />
{#if cargando}
<div out:slide>
<Card>
<CardContent class="flex w-full flex-col items-center justify-center">
<Spinner class="size-9" />
<p class="leading-7 not-first:mt-6">Cargando</p>
</CardContent>
</Card>
</div>
{:else if mensajeError !== ''}
<div in:fade>
<Card class="border-red-500">
<CardContent class="flex w-full flex-col items-center justify-center">
<Ban class="scale-120 text-red-500"></Ban>
<p class="mt-2 text-lg leading-7 text-red-500">
{mensajeError}
</p>
</CardContent>
</Card>
</div>
{/if}
</div>
</div>

1
src/types.d.ts vendored
View File

@@ -32,6 +32,7 @@ export interface Sesion {
message: string;
url: string;
displayName: string;
username: string;
}
export interface LoginDto {