now will get all messages for a user
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import "./App.css";
|
||||
import { ArrowUpIcon } from "lucide-react";
|
||||
import { ArrowUpIcon, Trash2Icon } from "lucide-react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
|
||||
import {
|
||||
InputGroup,
|
||||
@@ -9,22 +11,19 @@ import {
|
||||
InputGroupTextarea,
|
||||
} from "@/components/ui/input-group";
|
||||
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { CardFooter, CardHeader } from "./components/ui/card";
|
||||
import { Button } from "./components/ui/button";
|
||||
|
||||
const baseUrl = "http://localhost:8080";
|
||||
const baseUrl = "http://192.168.1.101:8080";
|
||||
const username = "ratludu";
|
||||
|
||||
type Note = {
|
||||
id: string;
|
||||
content: string;
|
||||
title: string;
|
||||
created_at: string;
|
||||
modified_at: string;
|
||||
};
|
||||
|
||||
export function InputGroupDemo({ onSent }): {
|
||||
@@ -58,10 +57,22 @@ export function InputGroupDemo({ onSent }): {
|
||||
throw new Error(msg || "Unknown error");
|
||||
}
|
||||
|
||||
const created = {
|
||||
let createdFromServer: Note | null = null;
|
||||
try {
|
||||
const json = await resp.json();
|
||||
if (json && (json.id || json.content)) {
|
||||
createdFromServer = json as Note;
|
||||
}
|
||||
} catch {
|
||||
// Ignore parsing error
|
||||
}
|
||||
|
||||
const created: Note = createdFromServer ?? {
|
||||
id: crypto.randomUUID(),
|
||||
content: String(value),
|
||||
title: "Note",
|
||||
created_at: new Date().toISOString(),
|
||||
modified_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
onSent?.(created);
|
||||
@@ -94,7 +105,7 @@ export function InputGroupDemo({ onSent }): {
|
||||
}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupAddon align="block-end" className="justify-end">
|
||||
<InputGroupButton
|
||||
variant="default"
|
||||
className="rounded-full"
|
||||
@@ -122,10 +133,24 @@ function NotesList({ notes }: { notes: Note[] }) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{notes.map((note) => (
|
||||
<Card>
|
||||
<CardContent key={note.id}>
|
||||
<p>{note.content}</p>
|
||||
<Card key={note.id}>
|
||||
<CardHeader className="justify-end-safe">
|
||||
<Button size="icon-sm" aria-label="Delete note" title="Delete note">
|
||||
<Trash2Icon />
|
||||
</Button>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]}>
|
||||
{note.content}
|
||||
</ReactMarkdown>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{note.created_at
|
||||
? new Date(note.created_at).toLocaleString()
|
||||
: "Unknown"}
|
||||
</p>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
@@ -134,15 +159,65 @@ function NotesList({ notes }: { notes: Note[] }) {
|
||||
|
||||
function App() {
|
||||
const [notes, setNotes] = useState<Note[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [loadError, setLoadError] = useState<string | null>(null);
|
||||
|
||||
async function fetchUserNotes() {
|
||||
const resp = await fetch(`${baseUrl}/content/${username}`);
|
||||
if (!resp.ok) {
|
||||
const msg = await resp.text().catch(() => "Failed to load notes");
|
||||
throw new Error(msg || "Failedo load notes");
|
||||
}
|
||||
|
||||
const json = await resp.json();
|
||||
const list = Array.isArray(json) ? json : json?.notes;
|
||||
return (list ?? []) as Note[];
|
||||
}
|
||||
|
||||
const loadNotes = async () => {
|
||||
setLoading(true);
|
||||
setLoadError(null);
|
||||
try {
|
||||
const data = await fetchUserNotes();
|
||||
setNotes(data);
|
||||
} catch (e) {
|
||||
const msg = e instanceof Error ? e.message : "Unknown error";
|
||||
setLoadError(msg);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
function handleSend(newNote: Note) {
|
||||
setNotes((prev) => [newNote, ...prev]);
|
||||
loadNotes();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadNotes();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="w-150 fixed top-10 left-0 right-0 mx-auto space-y-4">
|
||||
<InputGroupDemo onSent={handleSend} />
|
||||
<NotesList notes={notes} />
|
||||
<div className="min-h-screen flex flex-col">
|
||||
<div className="w-150 mx-auto space-y-4">
|
||||
<div className="w-full mx-auto px-4">
|
||||
<InputGroupDemo onSent={handleSend} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-150 flex-1 overflow-y-auto">
|
||||
<div className="w-full mx-auto px-4 py-6 space-y-4">
|
||||
{loading ? (
|
||||
<div className="text-center text-sm text-muted-foreground">
|
||||
Loading...
|
||||
</div>
|
||||
) : loadError ? (
|
||||
<div className="text-center text-sm text-red-500">
|
||||
Failed to load notes: {loadError}
|
||||
</div>
|
||||
) : null}
|
||||
<NotesList notes={notes} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user