mirror of
https://github.com/emailerfacu-spec/minix-front.git
synced 2026-04-01 13:10:44 -03:00
arreglado path /timeline y añadida logica crearpost al fetch
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import InputGroupAddon from './ui/input-group/input-group-addon.svelte';
|
||||
import InputGroupButton from './ui/input-group/input-group-button.svelte';
|
||||
import InputGroupTextarea from './ui/input-group/input-group-textarea.svelte';
|
||||
@@ -6,29 +6,76 @@
|
||||
import ArrowUpIcon from '@lucide/svelte/icons/arrow-up';
|
||||
import Kbd from './ui/kbd/kbd.svelte';
|
||||
|
||||
import { apiBase } from '@/stores/url';
|
||||
import { sesionStore } from '@/stores/usuario';
|
||||
import type { CreatePostDto } from '../../types';
|
||||
import { addPost } from '@/stores/posts';
|
||||
|
||||
let mensaje = $state('');
|
||||
|
||||
let cargando = $state(false);
|
||||
let mostrarError = $state('');
|
||||
|
||||
async function handlePost(e: Event) {
|
||||
e.preventDefault();
|
||||
try {
|
||||
const data: CreatePostDto = {
|
||||
content: mensaje,
|
||||
imageUrl: null,
|
||||
parentPostId: null
|
||||
};
|
||||
|
||||
const req = fetch($apiBase + '/api/posts', {
|
||||
method: 'POST',
|
||||
//credentials: 'include',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"Authorization": `Bearer ${$sesionStore?.accessToken}`
|
||||
},
|
||||
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
cargando = true;
|
||||
|
||||
const res = await req;
|
||||
if (res.ok) {
|
||||
mensaje = '';
|
||||
const post = await res.json();
|
||||
addPost(post);
|
||||
return;
|
||||
}
|
||||
mostrarError = 'No se pudo crear el post.';
|
||||
} catch {
|
||||
mostrarError = 'Fallo al alcanzar el servidor';
|
||||
} finally {
|
||||
cargando = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<InputGroup>
|
||||
<InputGroupTextarea bind:value={mensaje} maxlength="255" placeholder="Alguna novedad?"
|
||||
></InputGroupTextarea>
|
||||
<!-- <hr class="w-full" /> -->
|
||||
<InputGroupAddon align="block-end" class="bg-">
|
||||
<div class="flex w-full justify-between">
|
||||
<Kbd class="text-sm leading-none font-medium italic">
|
||||
<p class:text-red-500={mensaje.length > 229}>
|
||||
{mensaje.length}
|
||||
</p>
|
||||
/ 255
|
||||
</Kbd>
|
||||
<InputGroupButton
|
||||
variant="default"
|
||||
class="transform rounded-full transition-transform ease-in hover:scale-120"
|
||||
size="xs"
|
||||
>
|
||||
<p>Publicar</p>
|
||||
<ArrowUpIcon />
|
||||
</InputGroupButton>
|
||||
</div>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<form onsubmit={(e: Event) => handlePost(e)}>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea bind:value={mensaje} maxlength="280" placeholder="Alguna novedad?"
|
||||
></InputGroupTextarea>
|
||||
|
||||
<InputGroupAddon align="block-end" class="bg-">
|
||||
<div class="flex w-full justify-between">
|
||||
<Kbd class="text-sm leading-none font-medium italic">
|
||||
<p class:text-red-500={mensaje.length > 239}>
|
||||
{mensaje.length}
|
||||
</p>
|
||||
/ 280
|
||||
</Kbd>
|
||||
<InputGroupButton
|
||||
variant="default"
|
||||
type="submit"
|
||||
class="transform rounded-full transition-transform ease-in hover:scale-120"
|
||||
size="xs"
|
||||
>
|
||||
<p>Publicar</p>
|
||||
<ArrowUpIcon />
|
||||
</InputGroupButton>
|
||||
</div>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</form>
|
||||
|
||||
22
src/lib/stores/posts.ts
Normal file
22
src/lib/stores/posts.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import type { Post } from '../../types';
|
||||
|
||||
export const posts = writable<Post[]>([]);
|
||||
|
||||
export const setPosts = (newPosts: Post[]) => {
|
||||
posts.set(newPosts);
|
||||
};
|
||||
|
||||
export const addPost = (post: Post) => {
|
||||
posts.update((currentPosts) => [post, ...currentPosts]);
|
||||
};
|
||||
|
||||
export const updatePost = (postId: string, updatedData: Partial<Post>) => {
|
||||
posts.update((currentPosts) =>
|
||||
currentPosts.map((post) => (post._id === postId ? { ...post, ...updatedData } : post))
|
||||
);
|
||||
};
|
||||
|
||||
export const removePost = (postId: string) => {
|
||||
posts.update((currentPosts) => currentPosts.filter((post) => post._id !== postId));
|
||||
};
|
||||
@@ -5,13 +5,15 @@
|
||||
import { apiBase } from '@/stores/url';
|
||||
import { sesionStore } from '@/stores/usuario';
|
||||
import CrearPost from '@/components/crear-post.svelte';
|
||||
import CardHeader from '@/components/ui/card/card-header.svelte';
|
||||
import CardFooter from '@/components/ui/card/card-footer.svelte';
|
||||
import { posts, setPosts } from '@/stores/posts';
|
||||
|
||||
$effect(async () => {
|
||||
setPosts(await getPosts());
|
||||
|
||||
$effect(() => {
|
||||
getPosts();
|
||||
});
|
||||
|
||||
let posts: Post[] = $state([]);
|
||||
|
||||
async function getPosts() {
|
||||
const { subscribe } = apiBase;
|
||||
let baseUrl: string = '';
|
||||
@@ -20,9 +22,9 @@
|
||||
baseUrl = value;
|
||||
})();
|
||||
|
||||
const req = await fetch(`${baseUrl}/api/posts/timeline?pageSize=3`);
|
||||
const req = await fetch(`${baseUrl}/timeline?pageSize=20`);
|
||||
if (req.ok) {
|
||||
posts = await req.json();
|
||||
return await req.json();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -35,36 +37,40 @@
|
||||
{/if}
|
||||
<hr />
|
||||
|
||||
{#if posts.length <= 0}
|
||||
{#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}
|
||||
{#each $posts as post}
|
||||
<Card>
|
||||
<Content>
|
||||
<CardHeader>
|
||||
<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
|
||||
>{post.createdAt.replace("T", " ").split(".")[0]}</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>
|
||||
</CardHeader>
|
||||
<Content>
|
||||
<p class="text-sm">{post.content}</p>
|
||||
{#if post.imageUrl}
|
||||
<img src={post.imageUrl} alt="Post" class="mt-2 rounded-md" />
|
||||
{/if}
|
||||
</Content>
|
||||
<CardFooter>
|
||||
<div class="flex items-center justify-between pt-2 gap-2 text-xs text-muted-foreground">
|
||||
<span>{post.likesCount} likes</span>
|
||||
<span>{post.repliesCount} replies</span>
|
||||
{#if post.isEdited}
|
||||
<span>Editado</span>
|
||||
{/if}
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
21
src/types.d.ts
vendored
21
src/types.d.ts
vendored
@@ -6,12 +6,13 @@ export interface Post {
|
||||
parentPostId?: string;
|
||||
likesCount: number;
|
||||
repliesCount: number;
|
||||
createdAt: Date;
|
||||
createdAt: string;
|
||||
updatedAt?: Date;
|
||||
isEdited: boolean;
|
||||
visibility: string;
|
||||
hashtags?: string[];
|
||||
}
|
||||
|
||||
export interface User {
|
||||
_id: string;
|
||||
displayName: string;
|
||||
@@ -34,13 +35,19 @@ export interface Sesion {
|
||||
}
|
||||
|
||||
export interface LoginDto {
|
||||
username: string?;
|
||||
password: string?;
|
||||
username: string?;
|
||||
password: string?;
|
||||
}
|
||||
|
||||
export interface RegisterDto {
|
||||
username: string?;
|
||||
email: string?;
|
||||
password: string?;
|
||||
displayName: string?;
|
||||
username: string?;
|
||||
email: string?;
|
||||
password: string?;
|
||||
displayName: string?;
|
||||
}
|
||||
|
||||
export interface CreatePostDto {
|
||||
content: string;
|
||||
imageUrl: string?;
|
||||
parentPostId: string?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user