mirror of
https://github.com/emailerfacu-spec/minix-front.git
synced 2026-04-21 16:27:32 -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 InputGroupAddon from './ui/input-group/input-group-addon.svelte';
|
||||||
import InputGroupButton from './ui/input-group/input-group-button.svelte';
|
import InputGroupButton from './ui/input-group/input-group-button.svelte';
|
||||||
import InputGroupTextarea from './ui/input-group/input-group-textarea.svelte';
|
import InputGroupTextarea from './ui/input-group/input-group-textarea.svelte';
|
||||||
@@ -6,23 +6,69 @@
|
|||||||
import ArrowUpIcon from '@lucide/svelte/icons/arrow-up';
|
import ArrowUpIcon from '@lucide/svelte/icons/arrow-up';
|
||||||
import Kbd from './ui/kbd/kbd.svelte';
|
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 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>
|
</script>
|
||||||
|
|
||||||
<InputGroup>
|
<form onsubmit={(e: Event) => handlePost(e)}>
|
||||||
<InputGroupTextarea bind:value={mensaje} maxlength="255" placeholder="Alguna novedad?"
|
<InputGroup>
|
||||||
|
<InputGroupTextarea bind:value={mensaje} maxlength="280" placeholder="Alguna novedad?"
|
||||||
></InputGroupTextarea>
|
></InputGroupTextarea>
|
||||||
<!-- <hr class="w-full" /> -->
|
|
||||||
<InputGroupAddon align="block-end" class="bg-">
|
<InputGroupAddon align="block-end" class="bg-">
|
||||||
<div class="flex w-full justify-between">
|
<div class="flex w-full justify-between">
|
||||||
<Kbd class="text-sm leading-none font-medium italic">
|
<Kbd class="text-sm leading-none font-medium italic">
|
||||||
<p class:text-red-500={mensaje.length > 229}>
|
<p class:text-red-500={mensaje.length > 239}>
|
||||||
{mensaje.length}
|
{mensaje.length}
|
||||||
</p>
|
</p>
|
||||||
/ 255
|
/ 280
|
||||||
</Kbd>
|
</Kbd>
|
||||||
<InputGroupButton
|
<InputGroupButton
|
||||||
variant="default"
|
variant="default"
|
||||||
|
type="submit"
|
||||||
class="transform rounded-full transition-transform ease-in hover:scale-120"
|
class="transform rounded-full transition-transform ease-in hover:scale-120"
|
||||||
size="xs"
|
size="xs"
|
||||||
>
|
>
|
||||||
@@ -31,4 +77,5 @@
|
|||||||
</InputGroupButton>
|
</InputGroupButton>
|
||||||
</div>
|
</div>
|
||||||
</InputGroupAddon>
|
</InputGroupAddon>
|
||||||
</InputGroup>
|
</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 { apiBase } from '@/stores/url';
|
||||||
import { sesionStore } from '@/stores/usuario';
|
import { sesionStore } from '@/stores/usuario';
|
||||||
import CrearPost from '@/components/crear-post.svelte';
|
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() {
|
async function getPosts() {
|
||||||
const { subscribe } = apiBase;
|
const { subscribe } = apiBase;
|
||||||
let baseUrl: string = '';
|
let baseUrl: string = '';
|
||||||
@@ -20,9 +22,9 @@
|
|||||||
baseUrl = value;
|
baseUrl = value;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const req = await fetch(`${baseUrl}/api/posts/timeline?pageSize=3`);
|
const req = await fetch(`${baseUrl}/timeline?pageSize=20`);
|
||||||
if (req.ok) {
|
if (req.ok) {
|
||||||
posts = await req.json();
|
return await req.json();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -35,36 +37,40 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
{#if posts.length <= 0}
|
{#if $posts.length <= 0}
|
||||||
<Card>
|
<Card>
|
||||||
<Content>
|
<Content>
|
||||||
<p class=" text-center leading-7 not-first:mt-6">No hay Posts que mostrar</p>
|
<p class=" text-center leading-7 not-first:mt-6">No hay Posts que mostrar</p>
|
||||||
</Content>
|
</Content>
|
||||||
</Card>
|
</Card>
|
||||||
{:else}
|
{:else}
|
||||||
{#each posts as post}
|
{#each $posts as post}
|
||||||
<Card>
|
<Card>
|
||||||
<Content>
|
<CardHeader>
|
||||||
<div class="flex flex-col space-y-2">
|
<div class="flex flex-col space-y-2">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<span class="text-sm font-medium">{post.authorId}</span>
|
<span class="text-sm font-medium">{post.authorId}</span>
|
||||||
<span class="text-xs text-muted-foreground"
|
<span class="text-xs text-muted-foreground"
|
||||||
>{post.createdAt.toLocaleDateString()}</span
|
>{post.createdAt.replace("T", " ").split(".")[0]}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<Content>
|
||||||
<p class="text-sm">{post.content}</p>
|
<p class="text-sm">{post.content}</p>
|
||||||
{#if post.imageUrl}
|
{#if post.imageUrl}
|
||||||
<img src={post.imageUrl} alt="Post" class="mt-2 rounded-md" />
|
<img src={post.imageUrl} alt="Post" class="mt-2 rounded-md" />
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex items-center justify-between pt-2 text-xs text-muted-foreground">
|
</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.likesCount} likes</span>
|
||||||
<span>{post.repliesCount} replies</span>
|
<span>{post.repliesCount} replies</span>
|
||||||
{#if post.isEdited}
|
{#if post.isEdited}
|
||||||
<span>Editado</span>
|
<span>Editado</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</CardFooter>
|
||||||
</Content>
|
|
||||||
</Card>
|
</Card>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
9
src/types.d.ts
vendored
9
src/types.d.ts
vendored
@@ -6,12 +6,13 @@ export interface Post {
|
|||||||
parentPostId?: string;
|
parentPostId?: string;
|
||||||
likesCount: number;
|
likesCount: number;
|
||||||
repliesCount: number;
|
repliesCount: number;
|
||||||
createdAt: Date;
|
createdAt: string;
|
||||||
updatedAt?: Date;
|
updatedAt?: Date;
|
||||||
isEdited: boolean;
|
isEdited: boolean;
|
||||||
visibility: string;
|
visibility: string;
|
||||||
hashtags?: string[];
|
hashtags?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
_id: string;
|
_id: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
@@ -44,3 +45,9 @@ export interface RegisterDto {
|
|||||||
password: string?;
|
password: string?;
|
||||||
displayName: string?;
|
displayName: string?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreatePostDto {
|
||||||
|
content: string;
|
||||||
|
imageUrl: string?;
|
||||||
|
parentPostId: string?;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user