mirror of
https://github.com/khairul169/code-share.git
synced 2025-04-29 00:59:37 +07:00
176 lines
4.1 KiB
TypeScript
176 lines
4.1 KiB
TypeScript
import { useStore } from "zustand";
|
|
import { settingsDialog } from "../stores/dialogs";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "~/components/ui/dialog";
|
|
import { useMemo, useState } from "react";
|
|
import { useProjectContext } from "../context/project";
|
|
import { useForm, useFormReturn } from "~/hooks/useForm";
|
|
import Input from "~/components/ui/input";
|
|
import Select from "~/components/ui/select";
|
|
import { Button } from "~/components/ui/button";
|
|
import { ProjectSettingsSchema, projectSettingsSchema } from "../lib/schema";
|
|
import {
|
|
cssPreprocessorList,
|
|
jsTranspilerList,
|
|
visibilityList,
|
|
} from "../lib/consts";
|
|
import trpc from "~/lib/trpc";
|
|
import { toast } from "~/lib/utils";
|
|
import Checkbox from "~/components/ui/checkbox";
|
|
import Tabs, { Tab } from "~/components/ui/tabs";
|
|
import { navigate } from "vike/client/router";
|
|
|
|
const defaultValues: ProjectSettingsSchema = {
|
|
title: "",
|
|
// slug: "",
|
|
visibility: "private",
|
|
|
|
settings: {
|
|
css: {
|
|
preprocessor: null,
|
|
tailwindcss: false,
|
|
},
|
|
js: {
|
|
transpiler: null,
|
|
packages: [],
|
|
},
|
|
},
|
|
};
|
|
|
|
const SettingsDialog = () => {
|
|
const { project } = useProjectContext();
|
|
const [tab, setTab] = useState(0);
|
|
const initialValues = useMemo(() => {
|
|
return Object.assign(defaultValues, {
|
|
title: project.title,
|
|
// slug: project.slug,
|
|
settings: project.settings,
|
|
});
|
|
}, [project]);
|
|
|
|
const open = useStore(settingsDialog);
|
|
const form = useForm(projectSettingsSchema, initialValues);
|
|
const save = trpc.project.update.useMutation({
|
|
onSuccess(data) {
|
|
toast.success("Project updated!");
|
|
onClose();
|
|
if (data.slug !== project.slug) {
|
|
navigate(`/${data.slug}`);
|
|
}
|
|
},
|
|
});
|
|
|
|
const onClose = () => {
|
|
settingsDialog.setState(false);
|
|
};
|
|
|
|
const onSubmit = form.handleSubmit((values) => {
|
|
save.mutate({ ...values, id: project.id });
|
|
});
|
|
|
|
const tabs: Tab[] = useMemo(
|
|
() => [
|
|
{
|
|
title: "General",
|
|
render: () => <GeneralTab form={form} />,
|
|
},
|
|
{
|
|
title: "CSS",
|
|
render: () => <CSSTab form={form} />,
|
|
},
|
|
{
|
|
title: "Javascript",
|
|
render: () => <JSTab form={form} />,
|
|
},
|
|
],
|
|
[]
|
|
);
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={settingsDialog.setState}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>Project Settings</DialogTitle>
|
|
</DialogHeader>
|
|
|
|
<form onSubmit={onSubmit} method="post">
|
|
<Tabs
|
|
tabs={tabs}
|
|
current={tab}
|
|
onChange={setTab}
|
|
containerClassName="mt-4"
|
|
/>
|
|
|
|
<div className="flex flex-col sm:flex-row items-stretch sm:items-center sm:justify-end gap-4 mt-8">
|
|
<Button variant="outline" onClick={onClose}>
|
|
Cancel
|
|
</Button>
|
|
<Button type="submit" isLoading={save.isPending}>
|
|
Save Settings
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
};
|
|
|
|
type TabProps = {
|
|
form: useFormReturn<ProjectSettingsSchema>;
|
|
};
|
|
|
|
const GeneralTab = ({ form }: TabProps) => {
|
|
return (
|
|
<div className="space-y-3">
|
|
<Input form={form} name="title" label="Title" />
|
|
{/* <Input form={form} name="slug" label="Slug" /> */}
|
|
<Select
|
|
form={form}
|
|
name="visibility"
|
|
label="Visibility"
|
|
items={visibilityList}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const CSSTab = ({ form }: TabProps) => {
|
|
return (
|
|
<div className="space-y-3">
|
|
<Select
|
|
form={form}
|
|
name="settings.css.preprocessor"
|
|
label="Preprocessor"
|
|
items={cssPreprocessorList}
|
|
/>
|
|
<Checkbox
|
|
form={form}
|
|
name="settings.css.tailwindcss"
|
|
label="Tailwindcss"
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const JSTab = ({ form }: TabProps) => {
|
|
return (
|
|
<div className="space-y-3">
|
|
<Select
|
|
form={form}
|
|
name="settings.js.transpiler"
|
|
label="Transpiler"
|
|
items={jsTranspilerList}
|
|
/>
|
|
<p className="text-sm">
|
|
* Set transpiler to <strong>SWC</strong> to use JSX
|
|
</p>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SettingsDialog;
|