├── .env.exampe ├── preview.png ├── preview2.png ├── public └── assets │ ├── logo.png │ └── resume.jpg ├── next.config.mjs ├── pages ├── _app.jsx ├── _document.jsx ├── index.jsx ├── api │ ├── hello.ts │ └── suggestions.js ├── templates.jsx └── builder.jsx ├── postcss.config.mjs ├── lib └── utils.ts ├── components ├── preview │ ├── Language.jsx │ ├── Certification.jsx │ ├── ContactInfo.jsx │ ├── Skills.jsx │ ├── TemplateTwo.jsx │ └── Preview.jsx ├── utility │ ├── DateRange.jsx │ ├── WinPrint.js │ └── DefaultResumeData.jsx ├── form │ ├── FormButton.jsx │ ├── FormCP.jsx │ ├── Summary.jsx │ ├── Language.jsx │ ├── PersonalInformation.jsx │ ├── certification.jsx │ ├── SocialMedia.jsx │ ├── LoadUnload.jsx │ ├── Skill.jsx │ ├── Education.jsx │ ├── Projects.jsx │ └── WorkExperience.jsx ├── ai │ ├── AIAnalysis.jsx │ └── AISuggestionButton.jsx ├── meta │ └── Meta.js ├── hero │ └── Hero.jsx └── ui │ └── sparkles.tsx ├── .gitignore ├── tsconfig.json ├── tailwind.config.ts ├── package.json ├── styles └── globals.css ├── utils └── gemini.js ├── README.md └── LICENSE /.env.exampe: -------------------------------------------------------------------------------- 1 | GEMINI_API_KEY=AIzaSyB0000000000000000000000000000000 -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HOTHEAD01TH/free-resume-maker/HEAD/preview.png -------------------------------------------------------------------------------- /preview2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HOTHEAD01TH/free-resume-maker/HEAD/preview2.png -------------------------------------------------------------------------------- /public/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HOTHEAD01TH/free-resume-maker/HEAD/public/assets/logo.png -------------------------------------------------------------------------------- /public/assets/resume.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HOTHEAD01TH/free-resume-maker/HEAD/public/assets/resume.jpg -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /pages/_app.jsx: -------------------------------------------------------------------------------- 1 | import '/styles/globals.css' 2 | 3 | export default function App({ Component, pageProps }) { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { ClassValue, clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /pages/_document.jsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from 'next/document' 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ) 13 | } -------------------------------------------------------------------------------- /pages/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { } from "react"; 2 | // import Builder from "./builder"; 3 | import Hero from "../components/hero/Hero"; 4 | 5 | const ResumeBuilder = () => { 6 | return ( 7 | <> 8 | 9 | 10 | ); 11 | }; 12 | 13 | export default ResumeBuilder; 14 | 15 | -------------------------------------------------------------------------------- /pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from 'next' 3 | 4 | type Data = { 5 | name: string 6 | } 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse 11 | ) { 12 | res.status(200).json({ name: 'John Doe' }) 13 | } 14 | -------------------------------------------------------------------------------- /components/preview/Language.jsx: -------------------------------------------------------------------------------- 1 | const Language = ({ title, languages }) => { 2 | return ( 3 | languages.length > 0 && ( 4 |
5 |

6 | {title} 7 |

8 |

{languages.join(", ")}

9 |
10 | ) 11 | ); 12 | }; 13 | 14 | export default Language; -------------------------------------------------------------------------------- /components/utility/DateRange.jsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | const DateRange = ({ startYear, endYear, id }) => { 4 | const start = new Date(startYear); 5 | const end = new Date(endYear); 6 | return ( 7 |

8 | {start.toLocaleString('default', { month: 'short' })}, {start.getFullYear()} - {end != "Invalid Date" ? end.toLocaleString('default', { month: 'short' }) + ', ' + end.getFullYear() : 'Present'} 9 |

10 | ); 11 | }; 12 | 13 | export default DateRange; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | .env 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /components/utility/WinPrint.js: -------------------------------------------------------------------------------- 1 | import { MdPictureAsPdf } from "react-icons/md"; 2 | 3 | const WinPrint = () => { 4 | 5 | const print = () => { 6 | window.print(); 7 | }; 8 | 9 | return ( 10 | 17 | ); 18 | }; 19 | 20 | export default WinPrint; 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /components/preview/Certification.jsx: -------------------------------------------------------------------------------- 1 | const Certification = ({ title, certifications }) => { 2 | if (!certifications || certifications.length === 0) { 3 | return null; 4 | } 5 | 6 | return ( 7 |
8 |

{title}

9 |
    10 | {certifications.map((certification, index) => ( 11 |
  • 12 | {certification.name} 13 | {certification.issuer && ( 14 | - {certification.issuer} 15 | )} 16 |
  • 17 | ))} 18 |
19 |
20 | ); 21 | }; 22 | 23 | export default Certification; -------------------------------------------------------------------------------- /components/form/FormButton.jsx: -------------------------------------------------------------------------------- 1 | import { MdAddCircle, MdRemoveCircle } from "react-icons/md"; 2 | 3 | const FormButton = ({ size, remove, add }) => { 4 | 5 | return ( 6 |
7 | 12 | { 13 | size > 0 && 14 | 19 | } 20 |
21 | ) 22 | } 23 | 24 | export default FormButton; -------------------------------------------------------------------------------- /components/form/FormCP.jsx: -------------------------------------------------------------------------------- 1 | import React, { } from "react"; 2 | import { BsFillArrowRightCircleFill, BsFillArrowLeftCircleFill } from "react-icons/bs" 3 | 4 | const FormCP = ({ formClose, setFormClose }) => { 5 | return ( 6 | 13 | ) 14 | } 15 | 16 | export default FormCP; 17 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | 3 | const config: Config = { 4 | content: [ 5 | "./pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | extend: { 11 | colors: { 12 | background: "var(--background)", 13 | foreground: "var(--foreground)", 14 | }, 15 | animation: { 16 | shimmer: "shimmer 2s linear infinite" 17 | }, 18 | keyframes: { 19 | shimmer: { 20 | from: { 21 | backgroundPosition: "0 0" 22 | }, 23 | to: { 24 | backgroundPosition: "-200% 0" 25 | } 26 | } 27 | } 28 | }, 29 | }, 30 | plugins: [], 31 | }; 32 | export default config; 33 | -------------------------------------------------------------------------------- /components/preview/ContactInfo.jsx: -------------------------------------------------------------------------------- 1 | import React, { } from "react"; 2 | 3 | const ContactInfo = ({ mainclass, linkclass, teldata, emaildata, addressdata, telicon, emailicon, addressicon }) => { 4 | return ( 5 |
6 | 9 | {telicon} {teldata} 10 | 11 | 14 | {emailicon} {emaildata} 15 | 16 |
19 | {addressicon} {addressdata} 20 |
21 |
22 | ); 23 | } 24 | 25 | export default ContactInfo; -------------------------------------------------------------------------------- /components/preview/Skills.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { ResumeContext } from "../../pages/builder"; 3 | 4 | const Skills = ({ title, skills }) => { 5 | const { resumeData, setResumeData } = useContext(ResumeContext); 6 | 7 | const handleTitleChange = (e) => { 8 | const newSkills = [...resumeData.skills]; 9 | newSkills.find((skillType) => skillType.title === title).title = e.target.innerText; 10 | setResumeData({ ...resumeData, skills: newSkills }); 11 | }; 12 | 13 | return ( 14 | skills.length > 0 && ( 15 | <> 16 |

17 | {title} 18 |

19 |

{skills.join(", ")}

20 | 21 | ) 22 | ); 23 | }; 24 | 25 | export default Skills; -------------------------------------------------------------------------------- /components/form/Summary.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { ResumeContext } from "../../pages/builder"; 3 | import AISuggestionButton from '../ai/AISuggestionButton'; 4 | 5 | const Summary = () => { 6 | const { resumeData, handleChange } = useContext(ResumeContext); 7 | 8 | return ( 9 |
10 |
11 |

Summary

12 | 16 |
17 |
18 |