mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-10 04:22:27 +10:00
Merge pull request #1721 from CorreyL/bugfix/save-pending-keyword-input
[Bugfix] Save Pending Keyword Input
This commit is contained in:
@ -15,6 +15,7 @@ import {
|
||||
RichInput,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
@ -36,6 +37,8 @@ export const CustomSectionDialog = () => {
|
||||
resolver: zodResolver(formSchema),
|
||||
});
|
||||
|
||||
const [pendingKeyword, setPendingKeyword] = useState("");
|
||||
|
||||
if (!payload) return null;
|
||||
|
||||
return (
|
||||
@ -43,6 +46,7 @@ export const CustomSectionDialog = () => {
|
||||
form={form}
|
||||
id={payload.id as DialogName}
|
||||
defaultValues={defaultCustomSection}
|
||||
pendingKeyword={pendingKeyword}
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<FormField
|
||||
@ -144,7 +148,7 @@ export const CustomSectionDialog = () => {
|
||||
<FormItem>
|
||||
<FormLabel>{t`Keywords`}</FormLabel>
|
||||
<FormControl>
|
||||
<BadgeInput {...field} />
|
||||
<BadgeInput {...field} setPendingKeyword={setPendingKeyword} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{t`You can add multiple keywords by separating them with a comma or pressing enter.`}
|
||||
|
||||
@ -14,6 +14,7 @@ import {
|
||||
Input,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
@ -29,8 +30,15 @@ export const InterestsDialog = () => {
|
||||
resolver: zodResolver(formSchema),
|
||||
});
|
||||
|
||||
const [pendingKeyword, setPendingKeyword] = useState("");
|
||||
|
||||
return (
|
||||
<SectionDialog<FormValues> id="interests" form={form} defaultValues={defaultInterest}>
|
||||
<SectionDialog<FormValues>
|
||||
id="interests"
|
||||
form={form}
|
||||
defaultValues={defaultInterest}
|
||||
pendingKeyword={pendingKeyword}
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<FormField
|
||||
name="name"
|
||||
@ -54,7 +62,7 @@ export const InterestsDialog = () => {
|
||||
<FormItem>
|
||||
<FormLabel>{t`Keywords`}</FormLabel>
|
||||
<FormControl>
|
||||
<BadgeInput {...field} />
|
||||
<BadgeInput {...field} setPendingKeyword={setPendingKeyword} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{t`You can add multiple keywords by separating them with a comma or pressing enter.`}
|
||||
|
||||
@ -15,6 +15,7 @@ import {
|
||||
RichInput,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
@ -33,8 +34,15 @@ export const ProjectsDialog = () => {
|
||||
resolver: zodResolver(formSchema),
|
||||
});
|
||||
|
||||
const [pendingKeyword, setPendingKeyword] = useState("");
|
||||
|
||||
return (
|
||||
<SectionDialog<FormValues> id="projects" form={form} defaultValues={defaultProject}>
|
||||
<SectionDialog<FormValues>
|
||||
id="projects"
|
||||
form={form}
|
||||
defaultValues={defaultProject}
|
||||
pendingKeyword={pendingKeyword}
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<FormField
|
||||
name="name"
|
||||
@ -121,7 +129,7 @@ export const ProjectsDialog = () => {
|
||||
<FormItem>
|
||||
<FormLabel>{t`Keywords`}</FormLabel>
|
||||
<FormControl>
|
||||
<BadgeInput {...field} />
|
||||
<BadgeInput {...field} setPendingKeyword={setPendingKeyword} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{t`You can add multiple keywords by separating them with a comma or pressing enter.`}
|
||||
|
||||
@ -15,6 +15,7 @@ import {
|
||||
Slider,
|
||||
} from "@reactive-resume/ui";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
@ -30,8 +31,15 @@ export const SkillsDialog = () => {
|
||||
resolver: zodResolver(formSchema),
|
||||
});
|
||||
|
||||
const [pendingKeyword, setPendingKeyword] = useState("");
|
||||
|
||||
return (
|
||||
<SectionDialog<FormValues> id="skills" form={form} defaultValues={defaultSkill}>
|
||||
<SectionDialog<FormValues>
|
||||
id="skills"
|
||||
form={form}
|
||||
defaultValues={defaultSkill}
|
||||
pendingKeyword={pendingKeyword}
|
||||
>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<FormField
|
||||
name="name"
|
||||
@ -98,7 +106,7 @@ export const SkillsDialog = () => {
|
||||
<FormItem>
|
||||
<FormLabel>{t`Keywords`}</FormLabel>
|
||||
<FormControl>
|
||||
<BadgeInput {...field} />
|
||||
<BadgeInput {...field} setPendingKeyword={setPendingKeyword} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{t`You can add multiple keywords by separating them with a comma or pressing enter.`}
|
||||
|
||||
@ -31,6 +31,7 @@ type Props<T extends SectionItem> = {
|
||||
id: DialogName;
|
||||
form: UseFormReturn<T>;
|
||||
defaultValues: T;
|
||||
pendingKeyword?: string;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
@ -38,6 +39,7 @@ export const SectionDialog = <T extends SectionItem>({
|
||||
id,
|
||||
form,
|
||||
defaultValues,
|
||||
pendingKeyword,
|
||||
children,
|
||||
}: Props<T>) => {
|
||||
const { isOpen, mode, close, payload } = useDialog<T>(id);
|
||||
@ -61,6 +63,9 @@ export const SectionDialog = <T extends SectionItem>({
|
||||
if (!section) return;
|
||||
|
||||
if (isCreate || isDuplicate) {
|
||||
if (pendingKeyword && values.keywords) {
|
||||
values.keywords.push(pendingKeyword);
|
||||
}
|
||||
setValue(
|
||||
`sections.${id}.items`,
|
||||
produce(section.items, (draft: T[]): void => {
|
||||
@ -72,6 +77,10 @@ export const SectionDialog = <T extends SectionItem>({
|
||||
if (isUpdate) {
|
||||
if (!payload.item?.id) return;
|
||||
|
||||
if (pendingKeyword && values.keywords) {
|
||||
values.keywords.push(pendingKeyword);
|
||||
}
|
||||
|
||||
setValue(
|
||||
`sections.${id}.items`,
|
||||
produce(section.items, (draft: T[]): void => {
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
import { forwardRef, useCallback, useEffect, useState } from "react";
|
||||
import { Dispatch, forwardRef, SetStateAction, useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { Input, InputProps } from "./input";
|
||||
|
||||
type BadgeInputProps = Omit<InputProps, "value" | "onChange"> & {
|
||||
value: string[];
|
||||
onChange: (value: string[]) => void;
|
||||
setPendingKeyword?: Dispatch<SetStateAction<string>>;
|
||||
};
|
||||
|
||||
export const BadgeInput = forwardRef<HTMLInputElement, BadgeInputProps>(
|
||||
({ value, onChange, ...props }, ref) => {
|
||||
({ value, onChange, setPendingKeyword, ...props }, ref) => {
|
||||
const [label, setLabel] = useState("");
|
||||
|
||||
const processInput = useCallback(() => {
|
||||
@ -27,6 +28,10 @@ export const BadgeInput = forwardRef<HTMLInputElement, BadgeInputProps>(
|
||||
}
|
||||
}, [label, processInput]);
|
||||
|
||||
useEffect(() => {
|
||||
if (setPendingKeyword) setPendingKeyword(label);
|
||||
}, [label, setPendingKeyword]);
|
||||
|
||||
const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user