feat: golden book

This commit is contained in:
Alzalia 2025-09-26 21:28:32 +02:00
parent 9eae498ef8
commit 44fc0947bf
4 changed files with 116 additions and 16 deletions

View file

@ -3,12 +3,23 @@ import Mdown from './Mdown'
interface Props {
author: string
content: string
date_posted: number
}
export default function Comment({ author, content }: Props) {
export default function Comment({ author, content, date_posted }: Props) {
let date = new Date(date_posted * 1000)
return (
<div className="bg-[#161718] w-xl max-w-4/5 p-5 flex flex-col gap-5 rounded-xl self-center hover:shadow-xl/20 hover:shadow-white transition-shadow mb-5">
<h1 className="text-white text-xl font-bold">{author}</h1>
<div className="bg-[#161718] w-xl max-w-4/5 p-5 flex flex-col gap-2 rounded-xl self-center hover:shadow-xl/20 hover:shadow-white transition-shadow mb-5">
<h1 className="font-bold">
<span className="text-white text-xl">{author}</span>
<span className="text-[#9e9b97] pl-3 text-lg">
{date.toLocaleDateString('fr-FR', {
day: 'numeric',
month: 'long',
year: 'numeric',
})}
</span>
</h1>
<div className=" flex flex-col space-y-1 text-[#9e9b97]">
<Mdown>{content}</Mdown>
</div>

View file

@ -34,9 +34,7 @@ export default function Header() {
<div className="px-2">
<Link to="/comments">
{lang == 'fr'
? "[WIP] Livre d'Or"
: '[WIP] Golden Book'}
{lang == 'fr' ? "Livre d'Or" : 'Golden Book'}
</Link>
</div>
</div>

View file

@ -0,0 +1,81 @@
import { useRouter } from '@tanstack/react-router'
import { useState } from 'react'
import Mdown from './Mdown'
import { loadLang } from '@/integrations/lang/lang'
export default function WriteComment() {
const router = useRouter()
const [pseudo, setPseudo] = useState<string>('')
const [content, setContent] = useState<string>('')
const [preview, setPreview] = useState<boolean>(false)
const lang = loadLang()
function sendComment() {
if (content.trim() == '') {
alert('Attention, un contenu doit être précisé !')
return
}
fetch(`${import.meta.env.VITE_API}/comment/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
author: pseudo.trim() == '' ? 'Inconnu·e' : pseudo.trim(),
content: content,
}),
}).then(() => {
router.invalidate()
setPseudo('')
setContent('')
})
}
return (
<div className="bg-[#161718] w-xl max-w-4/5 p-5 flex flex-col gap-5 rounded-xl self-center hover:shadow-xl/20 hover:shadow-white transition-shadow mb-5">
<p className="text-gray-400">
{lang == 'fr'
? 'Écrivez un commentaire (Markdown supporté)'
: 'Write a comment (Markdown supported)'}
</p>
<div className="border-1 border-white rounded-md p-3 flex flex-col gap-5">
<h1 className="text-white text-xl font-bold">
<input
placeholder="Pseudo"
value={pseudo}
onChange={(e) => setPseudo(e.target.value)}
className="w-full"
/>
</h1>
<div className=" flex flex-col space-y-1 text-[#9e9b97]">
{preview ? (
<Mdown>{content}</Mdown>
) : (
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder={
lang == 'fr' ? 'Commentaire' : 'Comment'
}
className="h-30"
/>
)}
</div>
</div>
<div className="flex flex-row gap-5 justify-end">
<button
onClick={() => setPreview((prev) => !prev)}
className="text-white bg-gray-800 w-fit p-2 pr-5 pl-5 rounded-xl self-end cursor-pointer"
>
{lang == 'fr' ? 'Prévisualiser' : 'Preview'}
</button>
<button
onClick={sendComment}
className="text-white bg-gray-700 w-fit p-2 pr-5 pl-5 rounded-xl self-end cursor-pointer"
>
{lang == 'fr' ? 'Envoyer' : 'Send'}
</button>
</div>
</div>
)
}

View file

@ -1,35 +1,45 @@
import Comment from '@/components/Comment'
import type { CommentType } from '@/types/comments'
import WriteComment from '@/components/WriteComment'
import { loadLang } from '@/integrations/lang/lang'
import { queryOptions } from '@tanstack/react-query'
import { createFileRoute } from '@tanstack/react-router'
// ===================
// =====< UTILS >=====
// ===================
async function fetchData(): Promise<CommentType[]> {
let data = await fetch(`${import.meta.env.VITE_API}/comments`)
return await data.json()
}
// =======================
// =====< COMPONENT >=====
// =======================
export const Route = createFileRoute('/comments/')({
loader: async () => fetchData(),
loader: () =>
fetch(`${import.meta.env.VITE_API}/comments`).then((r) => r.json()),
component: Comments,
})
export default function Comments() {
let data = Route.useLoaderData()
let lang = loadLang()
const items = data.map((e, i) => (
<Comment author={e.author} content={e.content} key={i} />
const items = data.map((e: any, i: any) => (
<Comment
author={e.author}
content={e.content}
date_posted={e.date_posted}
key={i}
/>
))
return (
<div className="bg-[url(/public/bg.jpeg)] bg-cover bg-no-repeat bg-center min-h-screen">
<div className="flex flex-col pt-10">
<h1 className="text-5xl text-white text-center mb-10">
{lang == 'fr' ? "Livre d'Or" : 'Golden Book'}
</h1>
<WriteComment />
<div className="flex flex-col pt-10">{items}</div>
</div>
</div>
)
}