fingers crossed lol
4da42760
4 file(s) · +154 −12
Binary file — no preview.
| 50 | 50 | "@astrojs/rss": "^4.0.7", |
|
| 51 | 51 | "@astrojs/ts-plugin": "^1.10.2", |
|
| 52 | 52 | "@clerk/astro": "^1.3.6", |
|
| 53 | + | "@nanostores/react": "^0.7.3", |
|
| 53 | 54 | "@types/react": "^18.3.8", |
|
| 54 | 55 | "@types/react-dom": "^18.3.0", |
|
| 55 | 56 | "@vercel/analytics": "^0.1.10", |
| 1 | + | import { useStore } from "@nanostores/react"; |
|
| 2 | + | import { $sessionStore, $userStore } from "@clerk/astro/client"; |
|
| 3 | + | import { useState, useEffect } from "react"; |
|
| 4 | + | import { |
|
| 5 | + | SignedIn, |
|
| 6 | + | SignedOut, |
|
| 7 | + | UserButton, |
|
| 8 | + | SignInButton, |
|
| 9 | + | } from "@clerk/astro/react"; |
|
| 10 | + | ||
| 11 | + | type Message = { |
|
| 12 | + | id: number; |
|
| 13 | + | note: string; |
|
| 14 | + | author: string; |
|
| 15 | + | user_id: string; |
|
| 16 | + | pfp_url: string; |
|
| 17 | + | }; |
|
| 18 | + | ||
| 19 | + | export function GuestbookFeed() { |
|
| 20 | + | const [messages, setMessages] = useState<Message[]>([]); |
|
| 21 | + | const [isLoading, setIsLoading] = useState(true); |
|
| 22 | + | const [inputText, setInputText] = useState(""); |
|
| 23 | + | const session = useStore($sessionStore); |
|
| 24 | + | const user = useStore($userStore); |
|
| 25 | + | ||
| 26 | + | async function fetchMessages() { |
|
| 27 | + | setIsLoading(true); |
|
| 28 | + | try { |
|
| 29 | + | const req = await fetch(`${import.meta.env.PUBLIC_API_URL}/messages`); |
|
| 30 | + | const res = await req.json(); |
|
| 31 | + | console.log(res); |
|
| 32 | + | setMessages(res); |
|
| 33 | + | } catch (error) { |
|
| 34 | + | console.log(error); |
|
| 35 | + | } finally { |
|
| 36 | + | setIsLoading(false); |
|
| 37 | + | } |
|
| 38 | + | } |
|
| 39 | + | ||
| 40 | + | function inputHandeler(e) { |
|
| 41 | + | setInputText(e.target.value); |
|
| 42 | + | } |
|
| 43 | + | ||
| 44 | + | async function sendMessage() { |
|
| 45 | + | try { |
|
| 46 | + | const req = await fetch(`${import.meta.env.PUBLIC_API_URL}/messages`, { |
|
| 47 | + | method: "POST", |
|
| 48 | + | headers: { |
|
| 49 | + | Authorization: `Bearer ${await session.getToken()}`, |
|
| 50 | + | }, |
|
| 51 | + | body: JSON.stringify({ note: inputText }), |
|
| 52 | + | }); |
|
| 53 | + | const res = await req.json(); |
|
| 54 | + | console.log(res); |
|
| 55 | + | setInputText(""); |
|
| 56 | + | await fetchMessages(); |
|
| 57 | + | } catch (error) { |
|
| 58 | + | console.log(error); |
|
| 59 | + | } |
|
| 60 | + | } |
|
| 61 | + | ||
| 62 | + | async function deleteMessage(id: number) { |
|
| 63 | + | try { |
|
| 64 | + | const req = await fetch( |
|
| 65 | + | `${import.meta.env.PUBLIC_API_URL}/messages/${id}`, |
|
| 66 | + | { |
|
| 67 | + | method: "DELETE", |
|
| 68 | + | headers: { |
|
| 69 | + | Authorization: `Bearer ${await session.getToken()}`, |
|
| 70 | + | }, |
|
| 71 | + | }, |
|
| 72 | + | ); |
|
| 73 | + | const res = await req.json(); |
|
| 74 | + | console.log(res); |
|
| 75 | + | await fetchMessages(); |
|
| 76 | + | } catch (error) { |
|
| 77 | + | console.log(error); |
|
| 78 | + | } |
|
| 79 | + | } |
|
| 80 | + | ||
| 81 | + | useEffect(() => { |
|
| 82 | + | fetchMessages(); |
|
| 83 | + | }, []); |
|
| 84 | + | ||
| 85 | + | return ( |
|
| 86 | + | <div className="flex flex-col gap-6"> |
|
| 87 | + | <div className=""> |
|
| 88 | + | <SignedOut> |
|
| 89 | + | <SignInButton |
|
| 90 | + | as="button" |
|
| 91 | + | mode="modal" |
|
| 92 | + | className="border-2 border-current rounded-md p-1 cursor-pointer" |
|
| 93 | + | > |
|
| 94 | + | Sign in with Github |
|
| 95 | + | </SignInButton> |
|
| 96 | + | </SignedOut> |
|
| 97 | + | <SignedIn> |
|
| 98 | + | <div className="flex items-center gap-4 w-full"> |
|
| 99 | + | <UserButton /> |
|
| 100 | + | <input |
|
| 101 | + | className="p-1 border-current border-2 rounded-md w-96" |
|
| 102 | + | type="text" |
|
| 103 | + | onChange={inputHandeler} |
|
| 104 | + | value={inputText} |
|
| 105 | + | /> |
|
| 106 | + | <button |
|
| 107 | + | className="border-2 border-current rounded-md py-1 px-2 cursor-pointer" |
|
| 108 | + | onClick={sendMessage} |
|
| 109 | + | type="button" |
|
| 110 | + | > |
|
| 111 | + | Send |
|
| 112 | + | </button> |
|
| 113 | + | </div> |
|
| 114 | + | </SignedIn> |
|
| 115 | + | </div> |
|
| 116 | + | {isLoading ? ( |
|
| 117 | + | <p>Loading...</p> |
|
| 118 | + | ) : ( |
|
| 119 | + | <div className="flex flex-col gap-6"> |
|
| 120 | + | {messages.map((note: Message) => ( |
|
| 121 | + | <div className="flex flex-row justify-between" key={note.id}> |
|
| 122 | + | <div className="flex flex-row gap-2 items-center"> |
|
| 123 | + | <img |
|
| 124 | + | className="h-7 w-7 rounded-full" |
|
| 125 | + | src={note.pfp_url} |
|
| 126 | + | alt={note.author} |
|
| 127 | + | /> |
|
| 128 | + | <div className="flex flex-col justify-between"> |
|
| 129 | + | <p className="font-bold text-gray-400">{note.author}</p> |
|
| 130 | + | <p>{note.note}</p> |
|
| 131 | + | </div> |
|
| 132 | + | </div> |
|
| 133 | + | {user.id === note.user_id && ( |
|
| 134 | + | <button |
|
| 135 | + | onClick={async () => deleteMessage(note.id)} |
|
| 136 | + | type="button" |
|
| 137 | + | > |
|
| 138 | + | x |
|
| 139 | + | </button> |
|
| 140 | + | )} |
|
| 141 | + | </div> |
|
| 142 | + | ))} |
|
| 143 | + | </div> |
|
| 144 | + | )} |
|
| 145 | + | </div> |
|
| 146 | + | ); |
|
| 147 | + | } |
| 1 | 1 | --- |
|
| 2 | 2 | export const prerender = false; |
|
| 3 | 3 | import PageLayout from "@/layouts/Base"; |
|
| 4 | - | import { |
|
| 5 | - | SignedIn, |
|
| 6 | - | SignedOut, |
|
| 7 | - | UserButton, |
|
| 8 | - | SignInButton, |
|
| 9 | - | } from "@clerk/astro/components"; |
|
| 4 | + | import { GuestbookFeed } from "src/components/GuestbookFeed"; |
|
| 10 | 5 | ||
| 11 | 6 | const meta = { |
|
| 12 | 7 | title: "Log", |
|
| 15 | 10 | --- |
|
| 16 | 11 | <PageLayout meta={meta}> |
|
| 17 | 12 | <div class="space-y-6"> |
|
| 18 | - | <SignedOut isStatic={false}> |
|
| 19 | - | <SignInButton path="/log" as="button" mode="modal" class="border-2 border-current rounded-md p-2 cursor-pointer">Sign in with Github</SignInButton> |
|
| 20 | - | </SignedOut> |
|
| 21 | - | <SignedIn isStatic={false}> |
|
| 22 | - | <UserButton /> |
|
| 23 | - | </SignedIn> |
|
| 13 | + | <div class="flex flex-col gap-2 mb-6"> |
|
| 14 | + | <h1 class="font-bold text-2xl">Guest Log</h1> |
|
| 15 | + | <p>Come say hello!</p> |
|
| 16 | + | </div> |
|
| 17 | + | <GuestbookFeed client:load /> |
|
| 24 | 18 | </div> |
|
| 25 | 19 | </PageLayout> |
|