mirror of
https://github.com/khairul169/code-share.git
synced 2025-04-29 00:59:37 +07:00
156 lines
4.7 KiB
TypeScript
156 lines
4.7 KiB
TypeScript
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";
|
|
import { useMemo } from "react";
|
|
|
|
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(),
|
|
});
|
|
|
|
type Schema = z.infer<typeof schema>;
|
|
|
|
const GetStartedPage = () => {
|
|
const { presets, forkFrom } = useData<Data>();
|
|
const { isLoggedIn } = useAuth();
|
|
const ctx = usePageContext();
|
|
|
|
const initialValue: Schema = useMemo(
|
|
() => ({
|
|
forkFromId: forkFrom?.id || 0,
|
|
title: forkFrom?.title || "",
|
|
}),
|
|
[forkFrom]
|
|
);
|
|
|
|
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>{(forkFrom ? "Fork" : "Create New") + " Project"}</CardTitle>
|
|
|
|
<form onSubmit={onSubmit}>
|
|
{!forkFrom ? (
|
|
<>
|
|
<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>
|
|
)}
|
|
/>
|
|
</>
|
|
) : null}
|
|
|
|
<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="john.doe@mail.com"
|
|
/>
|
|
<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;
|