### Install and Run OpenResume with npm Source: https://github.com/xitanggg/open-resume/blob/main/README.md Use npm to install dependencies and start a development server. Ensure Node.js is installed. ```bash git clone https://github.com/xitanggg/open-resume.git cd open-resume npm install npm run dev ``` -------------------------------- ### Install and Run OpenResume with Docker Source: https://github.com/xitanggg/open-resume/blob/main/README.md Use Docker to build and run OpenResume as a container. Docker must be installed and running. ```bash git clone https://github.com/xitanggg/open-resume.git cd open-resume docker build -t open-resume . docker run -p 3000:3000 open-resume ``` -------------------------------- ### Manage Resume Slice Actions Source: https://context7.com/xitanggg/open-resume/llms.txt Provides examples for updating profile fields, modifying work experience sections, and loading parsed resume data into the state. ```typescript // lib/redux/resumeSlice.ts import { useAppDispatch, useAppSelector } from "lib/redux/hooks"; import { changeProfile, changeWorkExperiences, changeEducations, changeProjects, changeSkills, addSectionInForm, deleteSectionInFormByIdx, moveSectionInForm, setResume, selectResume, selectProfile, } from "lib/redux/resumeSlice"; // Update profile fields const ProfileEditor = () => { const dispatch = useAppDispatch(); const profile = useAppSelector(selectProfile); const handleNameChange = (value: string) => { dispatch(changeProfile({ field: "name", value })); }; const handleEmailChange = (value: string) => { dispatch(changeProfile({ field: "email", value })); }; return ( handleNameChange(e.target.value)} /> ); }; // Update work experience const WorkExperienceEditor = () => { const dispatch = useAppDispatch(); const updateCompany = (idx: number, company: string) => { dispatch(changeWorkExperiences({ idx, field: "company", value: company })); }; const updateDescriptions = (idx: number, descriptions: string[]) => { dispatch(changeWorkExperiences({ idx, field: "descriptions", value: descriptions })); }; const addNewExperience = () => { dispatch(addSectionInForm({ form: "workExperiences" })); }; const removeExperience = (idx: number) => { dispatch(deleteSectionInFormByIdx({ form: "workExperiences", idx })); }; const moveUp = (idx: number) => { dispatch(moveSectionInForm({ form: "workExperiences", idx, direction: "up" })); }; }; // Load parsed resume data const loadParsedResume = (parsedResume: Resume) => { dispatch(setResume(parsedResume)); }; ``` -------------------------------- ### Resume Data Structures Source: https://context7.com/xitanggg/open-resume/llms.txt Defines the core TypeScript interfaces for structuring resume data, including profile, work experience, education, projects, and skills. An example `sampleResume` object is provided. ```typescript // lib/redux/types.ts - Core resume data structures interface ResumeProfile { name: string; email: string; phone: string; url: string; summary: string; location: string; } interface ResumeWorkExperience { company: string; jobTitle: string; date: string; descriptions: string[]; } interface ResumeEducation { school: string; degree: string; date: string; gpa: string; descriptions: string[]; } interface ResumeProject { project: string; date: string; descriptions: string[]; } interface FeaturedSkill { skill: string; rating: number; } interface ResumeSkills { featuredSkills: FeaturedSkill[]; descriptions: string[]; } interface Resume { profile: ResumeProfile; workExperiences: ResumeWorkExperience[]; educations: ResumeEducation[]; projects: ResumeProject[]; skills: ResumeSkills; custom: { descriptions: string[] }; } // Example resume data const sampleResume: Resume = { profile: { name: "John Doe", email: "john@example.com", phone: "(123)456-7890", url: "linkedin.com/in/johndoe", summary: "Full-stack developer with 5 years of experience", location: "San Francisco, CA" }, workExperiences: [{ company: "Tech Corp", jobTitle: "Senior Developer", date: "Jan 2020 - Present", descriptions: [ "Led development of microservices architecture", "Mentored team of 5 junior developers" ] }], educations: [{ school: "Stanford University", degree: "B.S. Computer Science", date: "2015 - 2019", gpa: "3.8", descriptions: ["Dean's List", "CS Club President"] }], projects: [{ project: "OpenSource CMS", date: "2021", descriptions: ["Built a headless CMS with 1000+ GitHub stars"] }], skills: { featuredSkills: [ { skill: "React", rating: 4 }, { skill: "TypeScript", rating: 4 } ], descriptions: ["React", "TypeScript", "Node.js", "PostgreSQL"] }, custom: { descriptions: [] } }; ``` -------------------------------- ### Configure Redux Store and Provider Source: https://context7.com/xitanggg/open-resume/llms.txt Sets up the Redux store with resume and settings reducers and demonstrates wrapping the application with the Redux Provider. ```typescript // lib/redux/store.ts import { configureStore } from "@reduxjs/toolkit"; import resumeReducer from "lib/redux/resumeSlice"; import settingsReducer from "lib/redux/settingsSlice"; export const store = configureStore({ reducer: { resume: resumeReducer, settings: settingsReducer, }, }); export type RootState = ReturnType; export type AppDispatch = typeof store.dispatch; // Usage in components with Provider import { Provider } from "react-redux"; function App() { return ( ); } ``` -------------------------------- ### Manage Settings Slice Actions Source: https://context7.com/xitanggg/open-resume/llms.txt Defines the settings interface and demonstrates how to update theme colors, fonts, and section visibility via Redux actions. ```typescript // lib/redux/settingsSlice.ts import { changeSettings, changeShowForm, changeFormHeading, changeFormOrder, changeShowBulletPoints, selectSettings, selectThemeColor, DEFAULT_THEME_COLOR, DEFAULT_FONT_FAMILY, } from "lib/redux/settingsSlice"; // Settings interface interface Settings { themeColor: string; // e.g., "#38bdf8" fontFamily: string; // e.g., "Roboto" fontSize: string; // e.g., "11" documentSize: string; // "Letter" or "A4" formToShow: { workExperiences: boolean; educations: boolean; projects: boolean; skills: boolean; custom: boolean; }; formToHeading: { workExperiences: string; // e.g., "WORK EXPERIENCE" educations: string; projects: string; skills: string; custom: string; }; formsOrder: ShowForm[]; showBulletPoints: { educations: boolean; projects: boolean; skills: boolean; custom: boolean; }; } // Available theme colors const THEME_COLORS = [ "#f87171", // Red-400 "#fb923c", // Orange-400 "#22c55e", // Green-500 "#38bdf8", // Sky-400 (default) "#818cf8", // Indigo-400 ]; // Theme customization component const ThemeCustomizer = () => { const dispatch = useAppDispatch(); const setThemeColor = (color: string) => { dispatch(changeSettings({ field: "themeColor", value: color })); }; const setFontFamily = (font: string) => { dispatch(changeSettings({ field: "fontFamily", value: font })); }; const toggleSection = (section: ShowForm) => { const current = settings.formToShow[section]; dispatch(changeShowForm({ field: section, value: !current })); }; const reorderSection = (section: ShowForm, direction: "up" | "down") => { dispatch(changeFormOrder({ form: section, type: direction })); }; }; ``` -------------------------------- ### Handle Resume File Upload Source: https://context7.com/xitanggg/open-resume/llms.txt Manages drag-and-drop file selection and triggers PDF parsing, followed by state initialization and navigation. ```typescript // components/ResumeDropzone.tsx import { ResumeDropzone } from "components/ResumeDropzone"; import { parseResumeFromPdf } from "lib/parse-resume-from-pdf"; // File upload with drag-and-drop support const ImportResumePage = () => { const [fileUrl, setFileUrl] = useState(""); const router = useRouter(); const handleImport = async () => { // Parse the uploaded PDF const resume = await parseResumeFromPdf(fileUrl); // Initialize settings based on parsed content const settings = { ...initialSettings }; settings.formToShow = { workExperiences: resume.workExperiences.length > 0, educations: resume.educations.length > 0, projects: resume.projects.length > 0, skills: resume.skills.descriptions.length > 0, custom: false, }; // Save to localStorage and navigate to builder saveStateToLocalStorage({ resume, settings }); router.push("/resume-builder"); }; return (
{fileUrl && ( )}
); }; // Dropzone props interface interface ResumeDropzoneProps { onFileUrlChange: (fileUrl: string) => void; className?: string; playgroundView?: boolean; // Compact mode for parser playground } ``` -------------------------------- ### Render Resume PDF Document Source: https://context7.com/xitanggg/open-resume/llms.txt Uses react-pdf to define a document structure with customizable theme colors, fonts, and section visibility. ```typescript // components/Resume/ResumePDF/index.tsx import { Document, Page, View } from "@react-pdf/renderer"; import { ResumePDF } from "components/Resume/ResumePDF"; // PDF Document component const ResumePDFDocument = ({ resume, settings, isPDF = false }) => { const { profile, workExperiences, educations, projects, skills, custom } = resume; const { fontFamily, fontSize, documentSize, formToHeading, formToShow, formsOrder, themeColor } = settings; return ( {/* Theme color header bar */} {themeColor && ( )} {/* Resume content sections */} {formToShow.workExperiences && ( )} {formToShow.educations && ( )} {/* Additional sections... */} ); }; // Usage with live preview const ResumePreview = () => { const resume = useAppSelector(selectResume); const settings = useAppSelector(selectSettings); return ( ); }; ``` -------------------------------- ### Resume Builder Page Component Source: https://context7.com/xitanggg/open-resume/llms.txt Main page component for the resume builder, integrating the form editor and live PDF preview. It uses React Redux for state management and displays ResumeForm and Resume components. ```typescript "use client"; import { Provider } from "react-redux"; import { store } from "lib/redux/store"; import { ResumeForm } from "components/ResumeForm"; import { Resume } from "components/Resume"; export default function ResumeBuilderPage() { return (
{/* Left: Form editor */}
{/* Right: Live PDF preview */}
); } // Resume component with zoom controls and download const Resume = () => { const [scale, setScale] = useState(0.8); const resume = useAppSelector(selectResume); const settings = useAppSelector(selectSettings); const document = useMemo( () => , [resume, settings] ); return (
); }; ``` -------------------------------- ### Resume Parser Page Component Source: https://context7.com/xitanggg/open-resume/llms.txt Page component for the resume parser playground, demonstrating the resume parsing algorithm with visual feedback. It processes a PDF through a pipeline of parsing functions and displays the results. ```typescript "use client"; import { readPdf } from "lib/parse-resume-from-pdf/read-pdf"; import { groupTextItemsIntoLines } from "lib/parse-resume-from-pdf/group-text-items-into-lines"; import { groupLinesIntoSections } from "lib/parse-resume-from-pdf/group-lines-into-sections"; import { extractResumeFromSections } from "lib/parse-resume-from-pdf/extract-resume-from-sections"; export default function ResumeParserPage() { const [fileUrl, setFileUrl] = useState("resume-example/laverne-resume.pdf"); const [textItems, setTextItems] = useState([]); // Process PDF through parser pipeline const lines = groupTextItemsIntoLines(textItems || []); const sections = groupLinesIntoSections(lines); const resume = extractResumeFromSections(sections); useEffect(() => { async function loadPdf() { const items = await readPdf(fileUrl); setTextItems(items); } loadPdf(); }, [fileUrl]); return (
{/* PDF preview */}