mirror of
https://github.com/khairul169/code-share.git
synced 2026-10-24 11:53:58 +07:00
feat: add homepage & auth
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
import { Button } from "~/components/ui/button";
|
||||
import Card, { CardTitle } from "~/components/ui/card";
|
||||
import { FormLabel } from "~/components/ui/form-field";
|
||||
import Input from "~/components/ui/input";
|
||||
import { useData } from "~/renderer/hooks";
|
||||
import { Data } from "./+data";
|
||||
import { useForm } from "~/hooks/useForm";
|
||||
import { z } from "zod";
|
||||
import { Controller } from "react-hook-form";
|
||||
import { navigate } from "vike/client/router";
|
||||
import Divider from "~/components/ui/divider";
|
||||
import trpc from "~/lib/trpc";
|
||||
import { useAuth } from "~/hooks/useAuth";
|
||||
import { usePageContext } from "~/renderer/context";
|
||||
|
||||
const schema = z.object({
|
||||
forkFromId: z.number(),
|
||||
title: z.string(),
|
||||
user: z
|
||||
.object({
|
||||
name: z.string().min(3),
|
||||
email: z.string().email(),
|
||||
password: z.string().min(6),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
const initialValue: z.infer<typeof schema> = {
|
||||
forkFromId: 0,
|
||||
title: "",
|
||||
};
|
||||
|
||||
const GetStartedPage = () => {
|
||||
const { presets } = useData<Data>();
|
||||
const { isLoggedIn } = useAuth();
|
||||
const ctx = usePageContext();
|
||||
|
||||
const form = useForm(schema, initialValue);
|
||||
const create = trpc.project.create.useMutation({
|
||||
onSuccess(data) {
|
||||
navigate(`/${data.slug}`);
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = form.handleSubmit((values) => {
|
||||
create.mutate(values);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="container max-w-3xl min-h-[80dvh] flex flex-col items-center justify-center py-8 md:py-16">
|
||||
<Card className="w-full md:p-8">
|
||||
<CardTitle>Create New Project</CardTitle>
|
||||
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormLabel>Select Preset</FormLabel>
|
||||
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="forkFromId"
|
||||
render={({ field }) => (
|
||||
<div className="flex md:grid md:grid-cols-3 gap-4 overflow-x-auto md:overflow-x-hidden">
|
||||
{presets.map((preset) => (
|
||||
<Button
|
||||
key={preset.projectId}
|
||||
variant={
|
||||
field.value === preset.projectId ? "default" : "outline"
|
||||
}
|
||||
className="flex py-16 border border-white/40 shrink-0 w-[160px] md:w-auto"
|
||||
onClick={() => field.onChange(preset.projectId)}
|
||||
>
|
||||
<p className="text-wrap">{preset.title}</p>
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Input
|
||||
form={form}
|
||||
name="title"
|
||||
label="Title"
|
||||
placeholder="Optional"
|
||||
className="mt-4"
|
||||
/>
|
||||
|
||||
{!isLoggedIn ? (
|
||||
<div className="mt-8">
|
||||
<p className="text-lg">Account detail</p>
|
||||
<Divider className="mt-2 mb-4" />
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-x-2 gap-y-4">
|
||||
<div className="order-1 md:order-2 flex flex-col items-center justify-center gap-3 py-4">
|
||||
<p className="text-center">Already have an account?</p>
|
||||
<Button
|
||||
href={`/auth/login?return=${encodeURI(ctx.urlPathname)}`}
|
||||
variant="outline"
|
||||
>
|
||||
Log in now
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="order-2 md:order-1 space-y-3">
|
||||
<Input
|
||||
form={form}
|
||||
name="user.name"
|
||||
label="Full Name"
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
<Input
|
||||
form={form}
|
||||
name="user.email"
|
||||
label="Email Address"
|
||||
placeholder="[email protected]"
|
||||
/>
|
||||
<Input
|
||||
form={form}
|
||||
type="password"
|
||||
name="user.password"
|
||||
label="Password"
|
||||
placeholder="P@ssw0rd123!"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<Divider className="my-6" />
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
size="lg"
|
||||
isLoading={create.isPending}
|
||||
className="w-full md:w-[160px]"
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
</form>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GetStartedPage;
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PageContext } from "vike/types";
|
||||
import trpcServer from "~/server/api/trpc/trpc";
|
||||
|
||||
export const data = async (ctx: PageContext) => {
|
||||
const trpc = await trpcServer(ctx);
|
||||
const presets = await trpc.project.getTemplates();
|
||||
|
||||
return { presets };
|
||||
};
|
||||
|
||||
export type Data = Awaited<ReturnType<typeof data>>;
|
||||
Reference in New Issue
Block a user