Skip to content

Commit

Permalink
refactor: highlight component into sections
Browse files Browse the repository at this point in the history
  • Loading branch information
vickonrails committed Nov 3, 2023
1 parent ac73da5 commit 7fbfa8d
Show file tree
Hide file tree
Showing 13 changed files with 316 additions and 140 deletions.
Binary file added public/patterns.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/resume-sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 54 additions & 10 deletions src/components/form-sections/education.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { SectionItemContainer } from "@/pages/builder"
import { GraduationCap } from "lucide-react"
import { useFieldArray, useFormContext } from "react-hook-form"
import { createRef, forwardRef, useImperativeHandle } from "react"
import { UseFieldArrayAppend, useFieldArray, useFormContext } from "react-hook-form"
import { AddSectionBtn } from "../ui/add-section-btn"
import { FormFields } from "../ui/basic-information-dialog"
import { Button } from "../ui/button"
import { Input } from "../ui/input"
import { Textarea } from "../ui/textarea"
import { HighlightForm, HighlightPropTypes } from "./highlight"
import SectionContainer from "./section-container"
import { SectionItemFooter } from "./section-item-footer"

export interface RefTypeEducation {
append: UseFieldArrayAppend<FormFields, `education.${number}.highlights`>
}

export function Education() {
const { control, register } = useFormContext<FormFields>()
Expand All @@ -15,6 +20,8 @@ export function Education() {
control
})

const highlightRef = createRef<RefTypeEducation>()

return (
<SectionContainer
title="Education"
Expand Down Expand Up @@ -47,18 +54,55 @@ export function Education() {
type="date"
{...register(`education.${idx}.endDate`)}
/>
<Textarea
label="Short Summary"
wrapperClassName="col-span-2"
{...register(`education.${idx}.summary`)}
/>
</article>

<Button onClick={() => remove(idx)} variant='default'>Remove</Button>
<EducationHighlights
ref={highlightRef}
index={idx}
/>

<SectionItemFooter
onRemoveBlock={() => remove(idx)}
onAddHighlight={() => highlightRef.current?.append({ text: '' })}
/>
</SectionItemContainer>

))}

<AddSectionBtn title="Add Education" onClick={() => append({})} />
<AddSectionBtn title="Add Education" onClick={() => append({ highlights: [{ text: '' }] })} />
</SectionContainer>
)
}


const EducationHighlights = forwardRef<RefTypeWorkExperience, HighlightPropTypes>(({ index }, ref) => {
const { control, register } = useFormContext<FormFields>()
const { append, fields, remove } = useFieldArray({
name: `education.${index}.highlights`,
control
});

useImperativeHandle(ref, () => {
return {
append
}
}, [append])

return (
<section>
<section className="flex flex-col gap-2">
{fields.map((field, idx) => {
const isFirst = idx === 0
const formProps = register(`education.${index}.highlights.${idx}.text`)
return (
<HighlightForm isFirst={isFirst} id={field.id} formProps={formProps} remove={() => remove(idx)} />
)
})}
</section>
</section >
)
});

export interface RefTypeWorkExperience {
append: UseFieldArrayAppend<FormFields, `education.${number}.highlights`>
}
32 changes: 32 additions & 0 deletions src/components/form-sections/highlight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { UseFieldArrayRemove } from "react-hook-form";
import { Button } from "../ui/button";
import { Textarea } from "../ui/textarea";

export interface HighlightPropTypes {
index: number
}

export function HighlightForm({ isFirst, id, formProps, remove }: { isFirst: boolean, id: string, formProps: any, remove: UseFieldArrayRemove }) {
return (
<>
<Textarea
rows={2}
className="min-h-fit"
key={id}
label={isFirst ? 'Highlight (Impact)' : ''}
placeholder={isFirst ? 'Enter your impact during this period' : ''}
{...formProps}
/>
<div className="flex justify-end">
<Button
variant='link'
onClick={() => remove()}
className="p-0 h-auto text-xs text-muted-foreground"
type="button"
>
Remove
</Button>
</div >
</>
)
}
65 changes: 50 additions & 15 deletions src/components/form-sections/projects.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { SectionItemContainer } from "@/pages/builder"
import { FolderOpenDot } from "lucide-react"
import { useFieldArray, useFormContext } from "react-hook-form"
import { createRef, forwardRef, useImperativeHandle } from "react"
import { UseFieldArrayAppend, useFieldArray, useFormContext } from "react-hook-form"
import { AddSectionBtn } from "../ui/add-section-btn"
import { FormFields } from "../ui/basic-information-dialog"
import { Button } from "../ui/button"
import { Input } from "../ui/input"
import { Textarea } from "../ui/textarea"
import { HighlightForm, HighlightPropTypes } from "./highlight"
import SectionContainer from "./section-container"
import { SectionItemFooter } from "./section-item-footer"

export function OtherProjects() {
const { register, control } = useFormContext<FormFields>()
Expand All @@ -15,6 +16,8 @@ export function OtherProjects() {
control
})

const highlightRef = createRef<RefTypeOtherProjects>()

return (
<SectionContainer
title="Other Projects"
Expand All @@ -32,22 +35,54 @@ export function OtherProjects() {
label="Project URL" {
...register(`otherProjects.${idx}.url`)}
/>
<Textarea
label="Project Description"
wrapperClassName="col-span-2"
{...register(`otherProjects.${idx}.description`)}
/>
<Textarea
label="Impact"
wrapperClassName="col-span-2"
{...register(`otherProjects.${idx}.impact`)}
/>
</article>
<Button onClick={() => remove(idx)}>Remove</Button>

<OtherProjectsHighlights
ref={highlightRef}
index={idx}
/>

<SectionItemFooter
onRemoveBlock={() => remove(idx)}
onAddHighlight={() => highlightRef.current?.append({ text: '' })}
/>
</SectionItemContainer>
))}

<AddSectionBtn title="Add Project" onClick={() => append({})} />
<AddSectionBtn title="Add Project" onClick={() => append({ highlights: [{ text: '' }] })} />
</SectionContainer>
)
}

const OtherProjectsHighlights = forwardRef<RefTypeOtherProjects, HighlightPropTypes>(({ index }, ref) => {
const { control, register } = useFormContext<FormFields>()
const { append, fields, remove } = useFieldArray({
name: `otherProjects.${index}.highlights`,
control
});

useImperativeHandle(ref, () => {
return {
append
}
}, [append])

return (
<section>
<section className="flex flex-col gap-2">
{fields.map((field, idx) => {
const isFirst = idx === 0
const formProps = register(`otherProjects.${index}.highlights.${idx}.text`)
return (
<HighlightForm isFirst={isFirst} id={field.id} formProps={formProps} remove={() => remove(idx)} />
)
})}
</section>
</section >
)
});


export interface RefTypeOtherProjects {
append: UseFieldArrayAppend<FormFields, `otherProjects.${number}.highlights`>
}
19 changes: 19 additions & 0 deletions src/components/form-sections/section-item-footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Trash2 } from "lucide-react"
import { Button } from "../ui/button"

interface SectionItemFooterProps {
onRemoveBlock: () => void
onAddHighlight: () => void
}

export function SectionItemFooter({ onRemoveBlock, onAddHighlight }: SectionItemFooterProps) {
return (
<div className="flex gap-2">
<Button type="button" onClick={onAddHighlight}>Add Highlight</Button>
<Button variant='outline' className="text-destructive hover:text-red-600" onClick={onRemoveBlock}>
<Trash2 size={18} className="mr-2" />
<span>Remove Block</span>
</Button>
</div>
)
}
Loading

0 comments on commit 7fbfa8d

Please sign in to comment.