init commit,

This commit is contained in:
louiscklaw
2025-05-28 09:55:51 +08:00
commit efe70ceb69
8042 changed files with 951668 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
"use client";
import { useState } from "react";
const CopyIcon = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
);
const CheckIcon = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
);
export default function Code({ code }: { code: string }) {
const [icon, setIcon] = useState(CopyIcon);
const copy = async () => {
await navigator?.clipboard?.writeText(code);
setIcon(CheckIcon);
setTimeout(() => setIcon(CopyIcon), 2000);
};
return (
<pre className="bg-foreground/5 rounded-md p-8 my-8 relative">
<button
onClick={copy}
className="absolute top-4 right-4 p-2 rounded-md bg-foreground/5 hover:bg-foreground/10"
>
{icon}
</button>
<code>{code}</code>
</pre>
);
}

View File

@@ -0,0 +1,62 @@
import Step from "./Step";
export default function ConnectSupabaseSteps() {
return (
<ol className="flex flex-col gap-6">
<Step title="Create Supabase project">
<p>
Head over to{" "}
<a
href="https://app.supabase.com/project/_/settings/api"
target="_blank"
className="font-bold hover:underline text-foreground/80"
rel="noreferrer"
>
database.new
</a>{" "}
and create a new Supabase project.
</p>
</Step>
<Step title="Declare environment variables">
<p>
Rename the{" "}
<span className="px-2 py-1 rounded-md bg-foreground/20 text-foreground/80">
.env.example
</span>{" "}
file in your Next.js app to{" "}
<span className="px-2 py-1 rounded-md bg-foreground/20 text-foreground/80">
.env.local
</span>{" "}
and populate with values from{" "}
<a
href="https://app.supabase.com/project/_/settings/api"
target="_blank"
className="font-bold hover:underline text-foreground/80"
rel="noreferrer"
>
your Supabase project's API Settings
</a>
.
</p>
</Step>
<Step title="Restart your Next.js development server">
<p>
You may need to quit your Next.js development server and run{" "}
<span className="px-2 py-1 rounded-md bg-foreground/20 text-foreground/80">
npm run dev
</span>{" "}
again to load the new environment variables.
</p>
</Step>
<Step title="Refresh the page">
<p>
You may need to refresh the page for Next.js to load the new
environment variables.
</p>
</Step>
</ol>
);
}

View File

@@ -0,0 +1,98 @@
import Step from './Step'
import Code from './Code'
const create = `
create table notes (
id bigserial primary key,
title text
);
insert into notes(title)
values
('Today I created a Supabase project.'),
('I added some data and queried it from Next.js.'),
('It was awesome!');
`.trim()
const server = `
import { createClient } from '@/utils/supabase/server'
export default async function Page() {
const supabase = createClient()
const { data: notes } = await supabase.from('notes').select()
return <pre>{JSON.stringify(notes, null, 2)}</pre>
}
`.trim()
const client = `
'use client'
import { createClient } from '@/utils/supabase/client'
import { useEffect, useState } from 'react'
export default function Page() {
const [notes, setNotes] = useState<any[] | null>(null)
const supabase = createClient()
useEffect(() => {
const getData = async () => {
const { data } = await supabase.from('notes').select()
setNotes(data)
}
getData()
}, [])
return <pre>{JSON.stringify(notes, null, 2)}</pre>
}
`.trim()
export default function FetchDataSteps() {
return (
<ol className="flex flex-col gap-6">
<Step title="Create some tables and insert some data">
<p>
Head over to the{' '}
<a
href="https://supabase.com/dashboard/project/_/editor"
className="font-bold hover:underline text-foreground/80"
target="_blank"
rel="noreferrer"
>
Table Editor
</a>{' '}
for your Supabase project to create a table and insert some example data. If you're stuck
for creativity, you can copy and paste the following into the{' '}
<a
href="https://supabase.com/dashboard/project/_/sql/new"
className="font-bold hover:underline text-foreground/80"
target="_blank"
rel="noreferrer"
>
SQL Editor
</a>{' '}
and click RUN!
</p>
<Code code={create} />
</Step>
<Step title="Query Supabase data from Next.js">
<p>
To create a Supabase client and query data from an Async Server Component, create a new
page.tsx file at{' '}
<span className="px-2 py-1 rounded-md bg-foreground/20 text-foreground/80">
/app/notes/page.tsx
</span>{' '}
and add the following.
</p>
<Code code={server} />
<p>Alternatively, you can use a Client Component.</p>
<Code code={client} />
</Step>
<Step title="Build in a weekend and scale to billions!">
<p>You're ready to launch your product to the world! 🚀</p>
</Step>
</ol>
)
}

View File

@@ -0,0 +1,22 @@
import Link from "next/link";
import Step from "./Step";
export default function SignUpUserSteps() {
return (
<ol className="flex flex-col gap-6">
<Step title="Sign up your first user">
<p>
Head over to the{" "}
<Link
href="/login"
className="font-bold hover:underline text-foreground/80"
>
Login
</Link>{" "}
page and sign up your first user. It's okay if this is just you for
now. Your awesome idea will have plenty of users later!
</p>
</Step>
</ol>
);
}

View File

@@ -0,0 +1,24 @@
export default function Step({
title,
children,
}: {
title: string;
children: React.ReactNode;
}) {
return (
<li className="mx-4">
<input type="checkbox" id={title} className={`mr-2 peer`} />
<label
htmlFor={title}
className={`text-lg text-foreground/90 peer-checked:line-through font-semibold hover:cursor-pointer`}
>
{title}
</label>
<div
className={`mx-6 text-foreground/80 text-sm peer-checked:line-through`}
>
{children}
</div>
</li>
);
}