Skip to content

Commit

Permalink
add supbase db demo
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Zuniga Cuellar committed Oct 16, 2023
1 parent 1dd58d0 commit 6e0f1eb
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 1 deletion.
108 changes: 108 additions & 0 deletions src/components/Reviews.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {
createResource,
For,
ErrorBoundary,
type ResourceFetcher,
} from "solid-js";

export interface GuestbookEntry {
name: string;
message: string;
}

const fetcher: ResourceFetcher<true, GuestbookEntry[], GuestbookEntry> = async (
_,
{ refetching, value },
) => {
const res = await fetch("/api/guestbook", {
method: refetching ? "POST" : "GET",
body: refetching ? JSON.stringify(refetching) : null,
});

const data = await res.json();

if (!res.ok) {
throw new Error(data.message);
}

const prev = value ?? [];
return [...data, ...prev];
};

export function Reviews({ reviews }: { reviews: GuestbookEntry[] }) {
const [data, { refetch }] = createResource(fetcher, {
initialValue: reviews,
ssrLoadFrom: "initial",
});

const onSubmitHandler = (e: Event) => {
e.preventDefault();
const formData = new FormData(e.currentTarget as HTMLFormElement);
const name = formData.get("name")?.toString();
const message = formData.get("message")?.toString();

if (!name || !message) return;
refetch({ name, message });
};

return (
<div class="max-w-3xl w-full">
<ErrorBoundary fallback={<div>Something went wrong</div>}>
<form
onsubmit={onSubmitHandler}
class="block border bg-blue-100 border-blue-300 rounded-md p-6 dark:bg-blue-950 dark:border-blue-800"
>
<div>
<label
class="block mb-1 font-medium dark:text-zinc-300 text-zinc-900 text-sm"
for="name"
>
Name
</label>
<input
id="name"
type="text"
placeholder="Sam"
required
name="name"
class="w-full block rounded-md py-1 px-3 dark:bg-zinc-800 dark:text-zinc-300 border bg-zinc-50 border-zinc-300 dark:border-zinc-700 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-600 dark:focus:bg-zinc-900 focus:bg-white focus:ring-opacity-60"
/>
</div>
<div class="mt-3">
<label
class="block mb-1 font-medium dark:text-zinc-300 text-zinc-900 text-sm"
for="message"
>
Message
</label>
<input
id="message"
type="text"
class="w-full block rounded-md py-1 px-3 dark:bg-zinc-800 dark:text-zinc-300 border bg-zinc-50 border-zinc-300 dark:border-zinc-700 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-600 dark:focus:bg-zinc-900 focus:bg-white focus:ring-opacity-60"
placeholder="A friendly message"
required
name="message"
/>
</div>
<button
class="w-full dark:bg-zinc-100 bg-zinc-900 border-zinc-900 py-1.5 border dark:border-zinc-100 rounded-md mt-4 dark:text-zinc-900 text-zinc-100 font-medium text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:focus:ring-offset-zinc-900 disabled:opacity-50 disabled:cursor-not-allowed"
type="submit"
disabled={data.loading}
>
Submit
</button>
</form>
<ul class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4">
<For each={data()}>
{(review) => (
<li class="p-4 border rounded-md bg-white dark:bg-zinc-800 dark:border-zinc-700">
<p class="text-sm font-medium text-zinc-500 dark:text-zinc-400">{review.name}</p>
<p class="mt-1">{review.message}</p>
</li>
)}
</For>
</ul>
</ErrorBoundary>
</div>
);
}
2 changes: 1 addition & 1 deletion src/layout/Base.astro
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const { title } = Astro.props;
</div>
</div>
</nav>
<main class="flex-1 flex flex-col gap-4 items-center px-4 justify-center">
<main class="flex-1 flex flex-col gap-4 items-center p-4 justify-center">
<slot />
</main>
</body>
Expand Down
33 changes: 33 additions & 0 deletions src/pages/api/guestbook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { APIRoute } from "astro";
import { supabase } from "../../lib/supabase";

export const GET: APIRoute = async () => {
const { data, error } = await supabase
.from("guestbook")
.select("*")
.order("created_at", { ascending: true });

if (error) {
return new Response(JSON.stringify({
error: error.message,
}), { status: 500 });
}

return new Response(JSON.stringify(data));
};

export const POST: APIRoute = async ({ request }) => {
const { name, message } = await request.json();
const { data, error } = await supabase
.from("guestbook")
.insert({ name, message })
.select();

if (error) {
return new Response(JSON.stringify({
error: error.message,
}), { status: 500 });
}

return new Response(JSON.stringify(data));
};
9 changes: 9 additions & 0 deletions src/pages/dashboard.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
---
import Base from "../layout/Base.astro";
import { supabase } from "../lib/supabase";
import { Reviews, type GuestbookEntry } from "../components/Reviews";
const { email } = Astro.locals;
const { data } = (await supabase
.from("guestbook")
.select("name, message")
.order("created_at", { ascending: false })) as { data: GuestbookEntry[] };
---

<Base title="Dashboard">
Expand All @@ -17,4 +25,5 @@ const { email } = Astro.locals;
class="bg-zinc-900 dark:bg-zinc-100 text-zinc-100 dark:text-zinc-900 px-3 py-1 rounded-md"
>Sign out</a
>
<Reviews reviews={data} client:idle />
</Base>

0 comments on commit 6e0f1eb

Please sign in to comment.