mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-12 05:55:02 +10:00
v5.0.12 (#2814)
* refactor to @base-ui/react * fix all * fixes to accordion * more updates * switch to chat/completions api from openai * update version to v5.0.12
This commit is contained in:
@@ -90,9 +90,7 @@ const CreateApiKeyForm = ({ setApiKey }: CreateApiKeyFormProps) => {
|
||||
<FormLabel>
|
||||
<Trans>Name</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input min={1} max={64} {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input min={1} max={64} {...field} />} />
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
<Trans>
|
||||
@@ -112,34 +110,36 @@ const CreateApiKeyForm = ({ setApiKey }: CreateApiKeyFormProps) => {
|
||||
<FormLabel>
|
||||
<Trans>Expires in</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Combobox
|
||||
value={field.value}
|
||||
onValueChange={(value) => value && field.onChange(Number(value))}
|
||||
options={[
|
||||
{
|
||||
// 1 month = 30 days
|
||||
value: 3600 * 24 * 30,
|
||||
label: t`1 month`,
|
||||
},
|
||||
{
|
||||
// 3 months = 90 days
|
||||
value: 3600 * 24 * 90,
|
||||
label: t`3 months`,
|
||||
},
|
||||
{
|
||||
// 6 months = 180 days
|
||||
value: 3600 * 24 * 180,
|
||||
label: t`6 months`,
|
||||
},
|
||||
{
|
||||
// 1 year = 365 days
|
||||
value: 3600 * 24 * 365,
|
||||
label: t`1 year`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Combobox
|
||||
value={field.value}
|
||||
onValueChange={(value) => value && field.onChange(Number(value))}
|
||||
options={[
|
||||
{
|
||||
// 1 month = 30 days
|
||||
value: 3600 * 24 * 30,
|
||||
label: t`1 month`,
|
||||
},
|
||||
{
|
||||
// 3 months = 90 days
|
||||
value: 3600 * 24 * 90,
|
||||
label: t`3 months`,
|
||||
},
|
||||
{
|
||||
// 6 months = 180 days
|
||||
value: 3600 * 24 * 180,
|
||||
label: t`6 months`,
|
||||
},
|
||||
{
|
||||
// 1 year = 365 days
|
||||
value: 3600 * 24 * 365,
|
||||
label: t`1 year`,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -85,15 +85,17 @@ export function ChangePasswordDialog(_: DialogProps<"auth.change-password">) {
|
||||
<Trans>Current Password</Trans>
|
||||
</FormLabel>
|
||||
<div className="flex items-center gap-x-1.5">
|
||||
<FormControl>
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showCurrentPassword ? "text" : "password"}
|
||||
autoComplete="current-password"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showCurrentPassword ? "text" : "password"}
|
||||
autoComplete="current-password"
|
||||
{...field}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Button size="icon" variant="ghost" type="button" onClick={toggleShowCurrentPassword}>
|
||||
{showCurrentPassword ? <EyeIcon /> : <EyeSlashIcon />}
|
||||
@@ -113,15 +115,17 @@ export function ChangePasswordDialog(_: DialogProps<"auth.change-password">) {
|
||||
<Trans>New Password</Trans>
|
||||
</FormLabel>
|
||||
<div className="flex items-center gap-x-1.5">
|
||||
<FormControl>
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showNewPassword ? "text" : "password"}
|
||||
autoComplete="new-password"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showNewPassword ? "text" : "password"}
|
||||
autoComplete="new-password"
|
||||
{...field}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Button size="icon" variant="ghost" type="button" onClick={toggleShowNewPassword}>
|
||||
{showNewPassword ? <EyeIcon /> : <EyeSlashIcon />}
|
||||
|
||||
@@ -77,15 +77,17 @@ export function DisableTwoFactorDialog(_: DialogProps<"auth.two-factor.disable">
|
||||
<Trans>Password</Trans>
|
||||
</FormLabel>
|
||||
<div className="flex items-center gap-x-1.5">
|
||||
<FormControl>
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showPassword ? "text" : "password"}
|
||||
autoComplete="current-password"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showPassword ? "text" : "password"}
|
||||
autoComplete="current-password"
|
||||
{...field}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Button size="icon" variant="ghost" type="button" onClick={toggleShowPassword}>
|
||||
{showPassword ? <EyeIcon /> : <EyeSlashIcon />}
|
||||
|
||||
@@ -189,15 +189,17 @@ export function EnableTwoFactorDialog(_: DialogProps<"auth.two-factor.enable">)
|
||||
<Trans>Password</Trans>
|
||||
</FormLabel>
|
||||
<div className="flex items-center gap-x-1.5">
|
||||
<FormControl>
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showPassword ? "text" : "password"}
|
||||
autoComplete="current-password"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Input
|
||||
min={6}
|
||||
max={64}
|
||||
type={showPassword ? "text" : "password"}
|
||||
autoComplete="current-password"
|
||||
{...field}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Button size="icon" variant="ghost" type="button" onClick={toggleShowPassword}>
|
||||
{showPassword ? <EyeIcon /> : <EyeSlashIcon />}
|
||||
@@ -244,25 +246,27 @@ export function EnableTwoFactorDialog(_: DialogProps<"auth.two-factor.enable">)
|
||||
name="code"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<InputOTP
|
||||
maxLength={6}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
pattern={REGEXP_ONLY_DIGITS}
|
||||
onComplete={verifyForm.handleSubmit(onVerifySubmit)}
|
||||
pasteTransformer={(pasted) => pasted.replaceAll("-", "")}
|
||||
>
|
||||
<InputOTPGroup>
|
||||
<InputOTPSlot index={0} className="size-12" />
|
||||
<InputOTPSlot index={1} className="size-12" />
|
||||
<InputOTPSlot index={2} className="size-12" />
|
||||
<InputOTPSlot index={3} className="size-12" />
|
||||
<InputOTPSlot index={4} className="size-12" />
|
||||
<InputOTPSlot index={5} className="size-12" />
|
||||
</InputOTPGroup>
|
||||
</InputOTP>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<InputOTP
|
||||
maxLength={6}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
pattern={REGEXP_ONLY_DIGITS}
|
||||
onComplete={verifyForm.handleSubmit(onVerifySubmit)}
|
||||
pasteTransformer={(pasted) => pasted.replaceAll("-", "")}
|
||||
>
|
||||
<InputOTPGroup>
|
||||
<InputOTPSlot index={0} className="size-12" />
|
||||
<InputOTPSlot index={1} className="size-12" />
|
||||
<InputOTPSlot index={2} className="size-12" />
|
||||
<InputOTPSlot index={3} className="size-12" />
|
||||
<InputOTPSlot index={4} className="size-12" />
|
||||
<InputOTPSlot index={5} className="size-12" />
|
||||
</InputOTPGroup>
|
||||
</InputOTP>
|
||||
}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -27,7 +27,7 @@ import { useDialogStore } from "./store";
|
||||
export function DialogManager() {
|
||||
const { open, activeDialog, onOpenChange } = useDialogStore();
|
||||
|
||||
const dialogContent = match(activeDialog)
|
||||
const DialogContent = match(activeDialog)
|
||||
.with({ type: "auth.change-password" }, () => <ChangePasswordDialog />)
|
||||
.with({ type: "auth.two-factor.enable" }, () => <EnableTwoFactorDialog />)
|
||||
.with({ type: "auth.two-factor.disable" }, () => <DisableTwoFactorDialog />)
|
||||
@@ -71,7 +71,7 @@ export function DialogManager() {
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
{dialogContent}
|
||||
{DialogContent}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -226,34 +226,36 @@ export function ImportResumeDialog(_: DialogProps<"resume.import">) {
|
||||
<FormLabel>
|
||||
<Trans>Type</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Combobox
|
||||
clearable={false}
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
options={[
|
||||
{ value: "reactive-resume-json", label: "Reactive Resume (JSON)" },
|
||||
{ value: "reactive-resume-v4-json", label: "Reactive Resume v4 (JSON)" },
|
||||
{ value: "json-resume-json", label: "JSON Resume" },
|
||||
{
|
||||
value: "pdf",
|
||||
label: (
|
||||
<div className="flex items-center gap-x-2">
|
||||
PDF <Badge>{t`AI`}</Badge>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: "docx",
|
||||
label: (
|
||||
<div className="flex items-center gap-x-2">
|
||||
Microsoft Word <Badge>{t`AI`}</Badge>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Combobox
|
||||
showClear={false}
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
options={[
|
||||
{ value: "reactive-resume-json", label: "Reactive Resume (JSON)" },
|
||||
{ value: "reactive-resume-v4-json", label: "Reactive Resume v4 (JSON)" },
|
||||
{ value: "json-resume-json", label: "JSON Resume" },
|
||||
{
|
||||
value: "pdf",
|
||||
label: (
|
||||
<div className="flex items-center gap-x-2">
|
||||
PDF <Badge>{t`AI`}</Badge>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: "docx",
|
||||
label: (
|
||||
<div className="flex items-center gap-x-2">
|
||||
Microsoft Word <Badge>{t`AI`}</Badge>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -266,27 +268,25 @@ export function ImportResumeDialog(_: DialogProps<"resume.import">) {
|
||||
render={({ field }) => (
|
||||
<FormItem className={cn(!type && "hidden")}>
|
||||
<FormControl>
|
||||
<div>
|
||||
<Input type="file" className="hidden" ref={inputRef} onChange={onUploadFile} />
|
||||
<Input type="file" className="hidden" ref={inputRef} onChange={onUploadFile} />
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-auto w-full flex-col border-dashed py-8 font-normal"
|
||||
onClick={onSelectFile}
|
||||
>
|
||||
{field.value ? (
|
||||
<>
|
||||
<FileIcon weight="thin" size={32} />
|
||||
<p>{field.value.name}</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<UploadSimpleIcon weight="thin" size={32} />
|
||||
<Trans>Click here to select a file to import</Trans>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="h-auto w-full flex-col border-dashed py-8 font-normal"
|
||||
onClick={onSelectFile}
|
||||
>
|
||||
{field.value ? (
|
||||
<>
|
||||
<FileIcon weight="thin" size={32} />
|
||||
<p>{field.value.name}</p>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<UploadSimpleIcon weight="thin" size={32} />
|
||||
<Trans>Click here to select a file to import</Trans>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
||||
@@ -125,14 +125,16 @@ export function CreateResumeDialog(_: DialogProps<"resume.create">) {
|
||||
</Button>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button size="icon" disabled={isPending}>
|
||||
<CaretDownIcon />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button size="icon" disabled={isPending}>
|
||||
<CaretDownIcon />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<DropdownMenuContent align="end" className="w-fit">
|
||||
<DropdownMenuItem onSelect={onCreateSampleResume}>
|
||||
<DropdownMenuItem onClick={onCreateSampleResume}>
|
||||
<TestTubeIcon />
|
||||
<Trans>Create a Sample Resume</Trans>
|
||||
</DropdownMenuItem>
|
||||
@@ -309,9 +311,7 @@ function ResumeForm() {
|
||||
<Trans>Name</Trans>
|
||||
</FormLabel>
|
||||
<div className="flex items-center gap-x-2">
|
||||
<FormControl>
|
||||
<Input min={1} max={64} {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input min={1} max={64} {...field} />} />
|
||||
|
||||
<Button size="icon" variant="outline" title={t`Generate a random name`} onClick={onGenerateName}>
|
||||
<MagicWandIcon />
|
||||
@@ -333,14 +333,16 @@ function ResumeForm() {
|
||||
<FormLabel>
|
||||
<Trans>Slug</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-start" className="hidden sm:flex">
|
||||
<InputGroupText>{slugPrefix}</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput min={1} max={64} className="ps-0!" {...field} />
|
||||
</InputGroup>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<InputGroup>
|
||||
<InputGroupAddon align="inline-start" className="hidden sm:flex">
|
||||
<InputGroupText>{slugPrefix}</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupInput min={1} max={64} className="ps-0!" {...field} />
|
||||
</InputGroup>
|
||||
}
|
||||
/>
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
<Trans>This is a URL-friendly name for your resume.</Trans>
|
||||
@@ -357,9 +359,7 @@ function ResumeForm() {
|
||||
<FormLabel>
|
||||
<Trans>Tags</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<ChipInput {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<ChipInput {...field} />} />
|
||||
<FormMessage />
|
||||
<FormDescription>
|
||||
<Trans>Tags can be used to categorize your resume by keywords.</Trans>
|
||||
|
||||
@@ -159,9 +159,7 @@ function AwardForm() {
|
||||
<FormLabel>
|
||||
<Trans>Title</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -175,9 +173,7 @@ function AwardForm() {
|
||||
<FormLabel>
|
||||
<Trans context="(noun) person, organization, or entity that gives an award">Awarder</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -191,9 +187,7 @@ function AwardForm() {
|
||||
<FormLabel>
|
||||
<Trans>Date</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -207,14 +201,12 @@ function AwardForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -225,10 +217,8 @@ function AwardForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
@@ -243,9 +233,7 @@ function AwardForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -159,9 +159,7 @@ function CertificationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Title</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -175,9 +173,7 @@ function CertificationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Issuer</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -191,9 +187,7 @@ function CertificationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Date</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -207,14 +201,12 @@ function CertificationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -225,10 +217,8 @@ function CertificationForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
@@ -243,9 +233,7 @@ function CertificationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -143,9 +143,7 @@ function CoverLetterForm() {
|
||||
<FormLabel>
|
||||
<Trans>Recipient</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -159,9 +157,7 @@ function CoverLetterForm() {
|
||||
<FormLabel>
|
||||
<Trans>Content</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -167,9 +167,7 @@ function CustomSectionForm({ isUpdate = false }: { isUpdate?: boolean }) {
|
||||
<FormLabel>
|
||||
<Trans>Title</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -183,18 +181,20 @@ function CustomSectionForm({ isUpdate = false }: { isUpdate?: boolean }) {
|
||||
<FormLabel>
|
||||
<Trans>Section Type</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Combobox
|
||||
{...field}
|
||||
value={field.value}
|
||||
disabled={isUpdate}
|
||||
onValueChange={field.onChange}
|
||||
options={SECTION_TYPE_OPTIONS.map((option) => ({
|
||||
value: option.value,
|
||||
label: i18n.t(option.label),
|
||||
}))}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Combobox
|
||||
{...field}
|
||||
value={field.value}
|
||||
disabled={isUpdate}
|
||||
onValueChange={field.onChange}
|
||||
options={SECTION_TYPE_OPTIONS.map((option) => ({
|
||||
value: option.value,
|
||||
label: i18n.t(option.label),
|
||||
}))}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -165,9 +165,7 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>School</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -181,9 +179,7 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Degree</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -197,9 +193,7 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Area of Study</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -213,9 +207,7 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Grade</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -229,9 +221,7 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Location</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -245,9 +235,7 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Period</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -261,14 +249,12 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -279,10 +265,8 @@ function EducationForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2 sm:col-span-full">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
@@ -297,9 +281,7 @@ function EducationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -204,9 +204,7 @@ function RoleFields({ role, index, onRemove }: RoleFieldsProps) {
|
||||
<FormLabel>
|
||||
<Trans>Position</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -220,9 +218,7 @@ function RoleFields({ role, index, onRemove }: RoleFieldsProps) {
|
||||
<FormLabel>
|
||||
<Trans>Period</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -236,9 +232,7 @@ function RoleFields({ role, index, onRemove }: RoleFieldsProps) {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -273,9 +267,7 @@ function ExperienceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Company</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -287,9 +279,9 @@ function ExperienceForm() {
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{hasRoles ? <Trans>Overall Title (optional)</Trans> : <Trans>Position</Trans>}</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} placeholder={hasRoles ? "e.g. Software Engineer → Senior Engineer" : ""} />
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={<Input {...field} placeholder={hasRoles ? "e.g. Software Engineer → Senior Engineer" : ""} />}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -303,9 +295,7 @@ function ExperienceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Location</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -317,9 +307,7 @@ function ExperienceForm() {
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{hasRoles ? <Trans>Overall Period</Trans> : <Trans>Period</Trans>}</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} placeholder={hasRoles ? "e.g. 2018 – Present" : ""} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} placeholder={hasRoles ? "e.g. 2018 – Present" : ""} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -333,14 +321,12 @@ function ExperienceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -351,9 +337,7 @@ function ExperienceForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2 sm:col-span-full">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel>
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
@@ -408,9 +392,7 @@ function ExperienceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -157,9 +157,11 @@ function InterestForm() {
|
||||
name={"icon"}
|
||||
render={({ field }) => (
|
||||
<FormItem className="shrink-0">
|
||||
<FormControl>
|
||||
<IconPicker {...field} popoverProps={{ modal: true }} className="rounded-r-none! border-e-0!" />
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<IconPicker {...field} popoverProps={{ modal: true }} className="rounded-r-none! border-e-0!" />
|
||||
}
|
||||
/>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
@@ -172,9 +174,7 @@ function InterestForm() {
|
||||
<FormLabel>
|
||||
<Trans>Name</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input className="rounded-l-none!" {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input className="rounded-l-none!" {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -189,9 +189,7 @@ function InterestForm() {
|
||||
<FormLabel>
|
||||
<Trans>Keywords</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<ChipInput {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<ChipInput {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -152,9 +152,7 @@ function LanguageForm() {
|
||||
<FormLabel>
|
||||
<Trans>Language</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -168,9 +166,7 @@ function LanguageForm() {
|
||||
<FormLabel>
|
||||
<Trans>Fluency</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -184,15 +180,17 @@ function LanguageForm() {
|
||||
<FormLabel>
|
||||
<Trans>Level</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Slider
|
||||
min={0}
|
||||
max={5}
|
||||
step={1}
|
||||
value={[field.value]}
|
||||
onValueChange={(value) => field.onChange(value[0])}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Slider
|
||||
min={0}
|
||||
max={5}
|
||||
step={1}
|
||||
value={[field.value]}
|
||||
onValueChange={(value) => field.onChange(Array.isArray(value) ? value[0] : value)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<FormMessage />
|
||||
<FormDescription>{Number(field.value) === 0 ? t`Hidden` : `${field.value} / 5`}</FormDescription>
|
||||
</FormItem>
|
||||
|
||||
@@ -162,9 +162,11 @@ function ProfileForm() {
|
||||
name={"icon"}
|
||||
render={({ field }) => (
|
||||
<FormItem className="shrink-0">
|
||||
<FormControl>
|
||||
<IconPicker {...field} popoverProps={{ modal: true }} className="rounded-r-none! border-e-0!" />
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<IconPicker {...field} popoverProps={{ modal: true }} className="rounded-r-none! border-e-0!" />
|
||||
}
|
||||
/>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
@@ -177,9 +179,7 @@ function ProfileForm() {
|
||||
<FormLabel>
|
||||
<Trans>Network</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input className="rounded-l-none!" {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input className="rounded-l-none!" {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -201,9 +201,7 @@ function ProfileForm() {
|
||||
</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
|
||||
<FormControl>
|
||||
<InputGroupInput {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<InputGroupInput {...field} />} />
|
||||
</InputGroup>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
@@ -218,14 +216,12 @@ function ProfileForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -236,10 +232,8 @@ function ProfileForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2 sm:col-span-full">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
|
||||
@@ -157,9 +157,7 @@ function ProjectForm() {
|
||||
<FormLabel>
|
||||
<Trans>Name</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -173,9 +171,7 @@ function ProjectForm() {
|
||||
<FormLabel>
|
||||
<Trans>Period</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -189,14 +185,12 @@ function ProjectForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -207,10 +201,8 @@ function ProjectForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2 sm:col-span-full">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
@@ -225,9 +217,7 @@ function ProjectForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -159,9 +159,7 @@ function PublicationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Title</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -175,9 +173,7 @@ function PublicationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Publisher</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -191,9 +187,7 @@ function PublicationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Date</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -207,14 +201,12 @@ function PublicationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -225,10 +217,8 @@ function PublicationForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
@@ -243,9 +233,7 @@ function PublicationForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -159,9 +159,7 @@ function ReferenceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Name</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -175,9 +173,7 @@ function ReferenceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Position</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -191,9 +187,7 @@ function ReferenceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Phone</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -207,14 +201,12 @@ function ReferenceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -225,10 +217,8 @@ function ReferenceForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
@@ -243,9 +233,7 @@ function ReferenceForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -163,9 +163,11 @@ function SkillForm() {
|
||||
name={"icon"}
|
||||
render={({ field }) => (
|
||||
<FormItem className="shrink-0">
|
||||
<FormControl>
|
||||
<IconPicker {...field} popoverProps={{ modal: true }} className="rounded-r-none! border-e-0!" />
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<IconPicker {...field} popoverProps={{ modal: true }} className="rounded-r-none! border-e-0!" />
|
||||
}
|
||||
/>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
@@ -178,9 +180,7 @@ function SkillForm() {
|
||||
<FormLabel>
|
||||
<Trans>Name</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input className="rounded-l-none!" {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input className="rounded-l-none!" {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -195,9 +195,7 @@ function SkillForm() {
|
||||
<FormLabel>
|
||||
<Trans>Proficiency</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -211,15 +209,17 @@ function SkillForm() {
|
||||
<FormLabel>
|
||||
<Trans>Level</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Slider
|
||||
min={0}
|
||||
max={5}
|
||||
step={1}
|
||||
value={[field.value]}
|
||||
onValueChange={(value) => field.onChange(value[0])}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
render={
|
||||
<Slider
|
||||
min={0}
|
||||
max={5}
|
||||
step={1}
|
||||
value={[field.value]}
|
||||
onValueChange={(value) => field.onChange(Array.isArray(value) ? value[0] : value)}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<FormMessage />
|
||||
<FormDescription>{Number(field.value) === 0 ? t`Hidden` : `${field.value} / 5`}</FormDescription>
|
||||
</FormItem>
|
||||
@@ -234,9 +234,7 @@ function SkillForm() {
|
||||
<FormLabel>
|
||||
<Trans>Keywords</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<ChipInput {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<ChipInput {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -140,9 +140,7 @@ function SummaryItemForm() {
|
||||
<FormLabel>
|
||||
<Trans>Content</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -159,9 +159,7 @@ function VolunteerForm() {
|
||||
<FormLabel>
|
||||
<Trans>Organization</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -175,9 +173,7 @@ function VolunteerForm() {
|
||||
<FormLabel>
|
||||
<Trans>Location</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -191,9 +187,7 @@ function VolunteerForm() {
|
||||
<FormLabel>
|
||||
<Trans>Period</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} />
|
||||
</FormControl>
|
||||
<FormControl render={<Input {...field} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -207,14 +201,12 @@ function VolunteerForm() {
|
||||
<FormLabel>
|
||||
<Trans>Website</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
</FormControl>
|
||||
<URLInput
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
hideLabelButton={form.watch("options.showLinkInTitle")}
|
||||
/>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
@@ -225,10 +217,8 @@ function VolunteerForm() {
|
||||
name="options.showLinkInTitle"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center gap-x-2">
|
||||
<FormControl>
|
||||
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormLabel className="!mt-0">
|
||||
<FormControl render={<Switch checked={field.value} onCheckedChange={field.onChange} />} />
|
||||
<FormLabel className="mt-0!">
|
||||
<Trans>Show link in title</Trans>
|
||||
</FormLabel>
|
||||
</FormItem>
|
||||
@@ -243,9 +233,7 @@ function VolunteerForm() {
|
||||
<FormLabel>
|
||||
<Trans>Description</Trans>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<RichInput {...field} value={field.value} onChange={field.onChange} />
|
||||
</FormControl>
|
||||
<FormControl render={<RichInput {...field} value={field.value} onChange={field.onChange} />} />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { useLingui } from "@lingui/react";
|
||||
import { Trans } from "@lingui/react/macro";
|
||||
import { SlideshowIcon } from "@phosphor-icons/react";
|
||||
import { type RefObject, useRef } from "react";
|
||||
import { CometCard } from "@/components/animation/comet-card";
|
||||
import { useResumeStore } from "@/components/resume/store/resume";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -14,8 +13,6 @@ import { cn } from "@/utils/style";
|
||||
import { type TemplateMetadata, templates } from "./data";
|
||||
|
||||
export function TemplateGalleryDialog(_: DialogProps<"resume.template.gallery">) {
|
||||
const scrollAreaRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const closeDialog = useDialogStore((state) => state.closeDialog);
|
||||
const selectedTemplate = useResumeStore((state) => state.resume.data.metadata.template);
|
||||
const updateResumeData = useResumeStore((state) => state.updateResumeData);
|
||||
@@ -44,14 +41,13 @@ export function TemplateGalleryDialog(_: DialogProps<"resume.template.gallery">)
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<ScrollArea ref={scrollAreaRef} className="max-h-[80svh] pb-8">
|
||||
<ScrollArea className="max-h-[80svh] pb-8">
|
||||
<div className="grid grid-cols-2 gap-6 p-4 md:grid-cols-3 lg:grid-cols-4">
|
||||
{Object.entries(templates).map(([template, metadata]) => (
|
||||
<TemplateCard
|
||||
key={template}
|
||||
metadata={metadata}
|
||||
id={template as Template}
|
||||
collisionBoundary={scrollAreaRef}
|
||||
isActive={template === selectedTemplate}
|
||||
onSelect={onSelectTemplate}
|
||||
/>
|
||||
@@ -66,28 +62,29 @@ type TemplateCardProps = {
|
||||
id: Template;
|
||||
isActive?: boolean;
|
||||
metadata: TemplateMetadata;
|
||||
collisionBoundary: RefObject<HTMLDivElement | null>;
|
||||
onSelect: (template: Template) => void;
|
||||
};
|
||||
|
||||
function TemplateCard({ id, metadata, isActive, collisionBoundary, onSelect }: TemplateCardProps) {
|
||||
function TemplateCard({ id, metadata, isActive, onSelect }: TemplateCardProps) {
|
||||
const { i18n } = useLingui();
|
||||
|
||||
return (
|
||||
<HoverCard openDelay={0} closeDelay={0}>
|
||||
<HoverCard>
|
||||
<CometCard translateDepth={3} rotateDepth={6} glareOpacity={0}>
|
||||
<HoverCardTrigger asChild>
|
||||
<button
|
||||
tabIndex={-1}
|
||||
onClick={() => onSelect(id)}
|
||||
className={cn(
|
||||
"relative block aspect-page size-full cursor-pointer overflow-hidden rounded-md bg-popover outline-none",
|
||||
isActive && "ring-2 ring-ring ring-offset-4 ring-offset-background",
|
||||
)}
|
||||
>
|
||||
<img src={metadata.imageUrl} alt={metadata.name} className="size-full object-cover" />
|
||||
</button>
|
||||
</HoverCardTrigger>
|
||||
<HoverCardTrigger
|
||||
render={
|
||||
<button
|
||||
tabIndex={-1}
|
||||
onClick={() => onSelect(id)}
|
||||
className={cn(
|
||||
"relative block aspect-page size-full cursor-pointer overflow-hidden rounded-md bg-popover outline-none",
|
||||
isActive && "ring-2 ring-ring ring-offset-4 ring-offset-background",
|
||||
)}
|
||||
>
|
||||
<img src={metadata.imageUrl} alt={metadata.name} className="size-full object-cover" />
|
||||
</button>
|
||||
}
|
||||
/>
|
||||
|
||||
<div className="flex items-center justify-center">
|
||||
<span className="font-bold leading-loose tracking-tight">{metadata.name}</span>
|
||||
@@ -98,7 +95,6 @@ function TemplateCard({ id, metadata, isActive, collisionBoundary, onSelect }: T
|
||||
sideOffset={-32}
|
||||
align="start"
|
||||
alignOffset={32}
|
||||
collisionBoundary={collisionBoundary.current}
|
||||
className="pointer-events-none! flex w-80 flex-col justify-between space-y-6 rounded-md bg-background/80 p-4 pb-6"
|
||||
>
|
||||
<div className="space-y-1">
|
||||
|
||||
Reference in New Issue
Block a user