feat: golden book
This commit is contained in:
parent
9eae498ef8
commit
44fc0947bf
4 changed files with 116 additions and 16 deletions
|
|
@ -3,12 +3,23 @@ import Mdown from './Mdown'
|
||||||
interface Props {
|
interface Props {
|
||||||
author: string
|
author: string
|
||||||
content: 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 (
|
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">
|
<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="text-white text-xl font-bold">{author}</h1>
|
<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]">
|
<div className=" flex flex-col space-y-1 text-[#9e9b97]">
|
||||||
<Mdown>{content}</Mdown>
|
<Mdown>{content}</Mdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,7 @@ export default function Header() {
|
||||||
|
|
||||||
<div className="px-2">
|
<div className="px-2">
|
||||||
<Link to="/comments">
|
<Link to="/comments">
|
||||||
{lang == 'fr'
|
{lang == 'fr' ? "Livre d'Or" : 'Golden Book'}
|
||||||
? "[WIP] Livre d'Or"
|
|
||||||
: '[WIP] Golden Book'}
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
81
src/components/WriteComment.tsx
Normal file
81
src/components/WriteComment.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,35 +1,45 @@
|
||||||
import Comment from '@/components/Comment'
|
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'
|
import { createFileRoute } from '@tanstack/react-router'
|
||||||
|
|
||||||
// ===================
|
// ===================
|
||||||
// =====< UTILS >=====
|
// =====< UTILS >=====
|
||||||
// ===================
|
// ===================
|
||||||
|
|
||||||
async function fetchData(): Promise<CommentType[]> {
|
|
||||||
let data = await fetch(`${import.meta.env.VITE_API}/comments`)
|
|
||||||
return await data.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
// =======================
|
// =======================
|
||||||
// =====< COMPONENT >=====
|
// =====< COMPONENT >=====
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
export const Route = createFileRoute('/comments/')({
|
export const Route = createFileRoute('/comments/')({
|
||||||
loader: async () => fetchData(),
|
loader: () =>
|
||||||
|
fetch(`${import.meta.env.VITE_API}/comments`).then((r) => r.json()),
|
||||||
component: Comments,
|
component: Comments,
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function Comments() {
|
export default function Comments() {
|
||||||
let data = Route.useLoaderData()
|
let data = Route.useLoaderData()
|
||||||
|
let lang = loadLang()
|
||||||
|
|
||||||
const items = data.map((e, i) => (
|
const items = data.map((e: any, i: any) => (
|
||||||
<Comment author={e.author} content={e.content} key={i} />
|
<Comment
|
||||||
|
author={e.author}
|
||||||
|
content={e.content}
|
||||||
|
date_posted={e.date_posted}
|
||||||
|
key={i}
|
||||||
|
/>
|
||||||
))
|
))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-[url(/public/bg.jpeg)] bg-cover bg-no-repeat bg-center min-h-screen">
|
<div className="bg-[url(/public/bg.jpeg)] bg-cover bg-no-repeat bg-center min-h-screen">
|
||||||
<div className="flex flex-col pt-10">{items}</div>
|
<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>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue