mirror of
https://github.com/emailerfacu-spec/minix-front.git
synced 2026-04-01 13:10:44 -03:00
añadido pagina de Posts, una store para la api, y header para mobile
This commit is contained in:
2
src/app.d.ts
vendored
2
src/app.d.ts
vendored
@@ -9,5 +9,3 @@ declare global {
|
|||||||
// interface Platform {}
|
// interface Platform {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
|
||||||
|
|||||||
@@ -1,29 +1,27 @@
|
|||||||
<script>
|
<script>
|
||||||
import { Root } from '@/components/ui/button-group';
|
|
||||||
import { Button } from '../components/ui/button';
|
import { Button } from '../components/ui/button';
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger
|
|
||||||
} from '../components/ui/dropdown-menu';
|
|
||||||
import ButtonTheme from './ButtonTheme.svelte';
|
import ButtonTheme from './ButtonTheme.svelte';
|
||||||
import ButtonGroup from '@/components/ui/button-group/button-group.svelte';
|
import ButtonGroup from '@/components/ui/button-group/button-group.svelte';
|
||||||
|
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
|
import { slide } from 'svelte/transition';
|
||||||
|
|
||||||
|
let menuOpen = $state(false);
|
||||||
|
const toggleMenu = () => (menuOpen = !menuOpen);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header class="border-b bg-background/95 backdrop-blur">
|
<header class="border-b bg-background/95 backdrop-blur">
|
||||||
<div class="container ms-2 flex h-14 items-center">
|
<div class="mx-4 ms-2 flex h-12 items-center justify-between">
|
||||||
<div class="mr-4 hidden md:flex">
|
<div class="flex items-center">
|
||||||
<a href="/" class="mr-6 flex items-center space-x-2">
|
<a href="/" class="mr-6 flex items-center space-x-2">
|
||||||
<p class="leading-7 not-first:mt-6">Mini-X</p>
|
<p class="leading-7 not-first:mt-6">Mini-X</p>
|
||||||
</a>
|
</a>
|
||||||
<nav class="flex items-center space-x-6 text-sm font-medium">
|
<nav class="items-center space-x-6 text-sm font-medium md:flex">
|
||||||
<ButtonTheme />
|
<ButtonTheme />
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-1 items-center justify-between space-x-2 md:justify-end">
|
|
||||||
|
<!-- Desktop menu -->
|
||||||
|
<div class="hidden flex-1 items-center justify-end md:flex">
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button
|
<Button
|
||||||
variant={page.url.pathname !== '/login' ? 'outline' : 'secondary'}
|
variant={page.url.pathname !== '/login' ? 'outline' : 'secondary'}
|
||||||
@@ -38,5 +36,48 @@
|
|||||||
>
|
>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Mobile menu button -->
|
||||||
|
<button class="me-3 rounded-md md:hidden" onclick={toggleMenu} aria-label="Toggle menu">
|
||||||
|
{#if menuOpen}
|
||||||
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width={2}
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{:else}
|
||||||
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width={2}
|
||||||
|
d="M4 6h16M4 12h16M4 18h16"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Mobile menu -->
|
||||||
|
{#if menuOpen}
|
||||||
|
<div class="md:hidden" transition:slide>
|
||||||
|
<div class="space-y-1 border-t bg-background/95 px-2 pt-2 pb-3">
|
||||||
|
<Button
|
||||||
|
variant={page.url.pathname !== '/login' ? 'outline' : 'secondary'}
|
||||||
|
href="/login"
|
||||||
|
class="mb-2 w-full justify-start text-foreground/60 transition-colors hover:text-foreground/80"
|
||||||
|
onclick={() => (menuOpen = false)}>Iniciar Sesion</Button
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
variant={page.url.pathname !== '/register' ? 'outline' : 'secondary'}
|
||||||
|
href="/register"
|
||||||
|
class="w-full justify-start text-foreground/60 transition-colors hover:text-foreground/80"
|
||||||
|
onclick={() => (menuOpen = false)}>Registrarse</Button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
6
src/lib/stores/url.ts
Normal file
6
src/lib/stores/url.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { dev } from '$app/environment';
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
|
export const apiBase = writable(
|
||||||
|
dev ? 'http://localhost:5000' : 'https://minix-back-dsuk.onrender.com'
|
||||||
|
);
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Card from '@/components/ui/card/card.svelte';
|
||||||
|
import type { Post } from '../types';
|
||||||
|
import { Content } from '@/components/ui/card';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
posts: Post[];
|
||||||
|
}
|
||||||
|
|
||||||
|
let { posts = [] }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex min-h-fit w-full items-center justify-center p-6 md:p-10">
|
||||||
|
<div class="w-full max-w-sm">
|
||||||
|
{#if posts.length <= 0}
|
||||||
|
<Card>
|
||||||
|
<Content>
|
||||||
|
<p class=" text-center leading-7 not-first:mt-6">No hay Posts que mostrar</p>
|
||||||
|
</Content>
|
||||||
|
</Card>
|
||||||
|
{:else}
|
||||||
|
{#each posts as post}
|
||||||
|
<Card>
|
||||||
|
<Content>
|
||||||
|
<div class="flex flex-col space-y-2">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-sm font-medium">{post.authorId}</span>
|
||||||
|
<span class="text-xs text-muted-foreground"
|
||||||
|
>{post.createdAt.toLocaleDateString()}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<p class="text-sm">{post.content}</p>
|
||||||
|
{#if post.imageUrl}
|
||||||
|
<img src={post.imageUrl} alt="Post" class="mt-2 rounded-md" />
|
||||||
|
{/if}
|
||||||
|
<div class="flex items-center justify-between pt-2 text-xs text-muted-foreground">
|
||||||
|
<span>{post.likesCount} likes</span>
|
||||||
|
<span>{post.repliesCount} replies</span>
|
||||||
|
{#if post.isEdited}
|
||||||
|
<span>Editado</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Content>
|
||||||
|
</Card>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
16
src/routes/+page.ts
Normal file
16
src/routes/+page.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { apiBase } from '@/stores/url';
|
||||||
|
|
||||||
|
export const ssr = true;
|
||||||
|
|
||||||
|
export async function load({}) {
|
||||||
|
const { subscribe } = apiBase;
|
||||||
|
let baseUrl: string = '';
|
||||||
|
|
||||||
|
subscribe((value) => {
|
||||||
|
baseUrl = value;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const req = await fetch(`${baseUrl}/Posts`);
|
||||||
|
if (req.ok) return { posts: req };
|
||||||
|
else return { posts: [] };
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
export const ssr = true;
|
|
||||||
14
src/types.d.ts
vendored
Normal file
14
src/types.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export interface Post {
|
||||||
|
_id: string;
|
||||||
|
authorId: string;
|
||||||
|
content: string;
|
||||||
|
imageUrl?: string;
|
||||||
|
parentPostId?: string;
|
||||||
|
likesCount: number;
|
||||||
|
repliesCount: number;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt?: Date;
|
||||||
|
isEdited: boolean;
|
||||||
|
visibility: string;
|
||||||
|
hashtags?: string[];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user