Cv project (#17)

* feat: updated component

* feat: added components

* feat: fixed

* refactor(feat): added button, renamed variables

* feat: updated education info component

* feat: experience component added

* refactor: modular

* feat: new components, style, etc

* refactor: remove unneccessary divs

* feat(styling): yep

* feat(style): new font added for resume

* feat(styling): colors, btns, etc

* feat: basically done
This commit is contained in:
Smigz 2024-06-23 20:10:32 -04:00 committed by GitHub
parent 940deff071
commit 592ddc4c1f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 5621 additions and 0 deletions

View file

@ -0,0 +1,9 @@
import "../styles/button.css";
export default function Button(props) {
return (
<button className={`${props.className} + btn`} onClick={props.onClick}>
{props.text}
</button>
);
}

View file

@ -0,0 +1,49 @@
export default function EducationInfoDisplay(props) {
return (
<div className="education-info">
<h2>Education</h2>
<EducationDisplay
educationInfo={props.educationInfo}
setEducationInfo={props.setEducationInfo}
setEditEducation={props.setEditEducation}
/>
</div>
);
}
function EducationDisplay(props) {
return (
<>
{props.educationInfo.map((item) => {
return (
<div key={item.schoolName} className="education-item">
<h2>{item.schoolName}</h2>
<p>
Graduation: {item.graduationDate + " "}
{item.fieldOfStudy}
</p>
<button onClick={() => props.setEditEducation(item)}>edit</button>
<button
onClick={() =>
deleteEducationItem(
props.educationInfo,
item.schoolName,
props.setEducationInfo,
)
}
>
remove
</button>
</div>
);
})}
</>
);
}
function deleteEducationItem(educationInfo, item, setEducationInfo) {
const filteredSchools = educationInfo.filter(
(school) => school.schoolName !== item,
);
setEducationInfo(filteredSchools);
}

View file

@ -0,0 +1,136 @@
import { useState, useEffect } from "react";
import Input from "./input";
import Button from "./button";
export default function EducationInfoForm(props) {
return (
<>
<EducationForm
isActive={props.educationItemActive}
educationInfo={props.educationInfo}
setEducationInfo={props.setEducationInfo}
editSchool={props.editEducation}
/>
</>
);
}
function EducationForm({
isActive,
educationInfo,
setEducationInfo,
editSchool,
}) {
const [graduationDate, setGraduationDate] = useState("");
const [schoolName, setSchoolName] = useState("");
const [fieldOfStudy, setFieldOfStudy] = useState("");
useEffect(() => {
if (editSchool) {
setGraduationDate(editSchool.graduationDate);
setSchoolName(editSchool.schoolName);
setFieldOfStudy(editSchool.fieldOfStudy);
} else {
setGraduationDate("");
setSchoolName("");
setFieldOfStudy("");
}
}, [editSchool]);
let schoolId = editSchool
? educationInfo.findIndex((school) => school.id === editSchool.id)
: null;
const contactFormStyle = {
display: "flex",
flexDirection: "column",
};
return (
<>
{isActive ? (
<div className="education-info-form">
<h2 className="general-info-header">Education History</h2>
<form
action=""
style={contactFormStyle}
onSubmit={(e) => console.log(e.target)}
>
<Input
label={true}
labelName="School"
name="School"
type="text"
placeholder=""
value={schoolName}
onChange={(e) => setSchoolName(e.target.value)}
/>
<Input
label={true}
labelName="Graduation date"
name="graduationDate"
type="text"
placeholder=""
value={graduationDate}
onChange={(e) => setGraduationDate(e.target.value)}
/>
<Input
label={true}
labelName="Degree/Field of study"
name="degree"
type="text"
placeholder=""
value={fieldOfStudy}
onChange={(e) => setFieldOfStudy(e.target.value)}
/>
<div className="btn-group">
<Button
autoFocus={true}
type="submit"
className="submit-btn"
onClick={(e) => {
e.preventDefault();
console.log(schoolName, graduationDate, fieldOfStudy);
const updatedSchools = [...educationInfo];
if (schoolId !== -1 && schoolId !== null) {
updatedSchools[schoolId] = {
schoolName: schoolName,
graduationDate: graduationDate,
fieldOfStudy: fieldOfStudy,
};
setEducationInfo(updatedSchools);
} else {
setEducationInfo([
...educationInfo,
{
schoolName: schoolName,
fieldOfStudy: fieldOfStudy,
graduationDate: graduationDate,
id: crypto.randomUUID(),
},
]);
}
setGraduationDate("");
setSchoolName("");
setFieldOfStudy("");
}}
text="Submit"
/>
<Button
onClick={(e) => {
e.preventDefault();
setGraduationDate("");
setSchoolName("");
setFieldOfStudy("");
schoolId = null;
}}
text="Clear"
/>
</div>
</form>
</div>
) : null}
</>
);
}

View file

@ -0,0 +1,29 @@
export default function ExperienceDisplay(props) {
return (
<div className="job-info">
<h2>Experience</h2>
<JobList jobs={props.employmentHistory} />
</div>
);
}
function JobList(props) {
return (
<>
{props.jobs.map((item) => {
return (
<div className="job" key={item.id}>
<div className="job-details">
<h2 className="job-employer">{item.employer}</h2>
<p className="job-dates">
{item.employmentStart} - {item.employmentEnd}
</p>
</div>
<h3 className="job-title">{item.jobTitle}</h3>
<p>{item.jobDescription}</p>
</div>
);
})}
</>
);
}

View file

@ -0,0 +1,128 @@
import { useState } from "react";
import Input from "./input";
import Button from "./button";
export default function ExperienceForm(props) {
return (
<>
<JobForm
setJobs={props.setEmploymentHistory}
jobs={props.employmentHistory}
isActive={props.showJobForm}
/>
</>
);
}
function JobForm({ isActive, jobs, setJobs }) {
const [employer, setEmployer] = useState("");
const [jobTitle, setJobTitle] = useState("");
const [jobDescription, setJobDescription] = useState([]);
const [employmentStart, setEmploymentStart] = useState("");
const [employmentEnd, setEmploymentEnd] = useState("");
const formStyle = {
display: "flex",
flexDirection: "column",
};
function clear() {
setEmployer("");
setJobTitle("");
setJobDescription("");
setEmploymentEnd("");
setEmploymentStart("");
}
function handleSubmit(event, stuff) {
event.preventDefault();
const key = crypto.randomUUID();
const newJob = { ...stuff, id: key };
setJobs([...jobs, newJob]);
clear();
}
return (
<>
{isActive ? (
<div className="job-info-form">
<h2 className="general-info-header">Employment History</h2>
<form action="" style={formStyle}>
<Input
name="employer"
label={true}
labelName="Employer"
type="text"
placeholder=""
value={employer}
onChange={(e) => setEmployer(e.target.value)}
/>
<Input
name="jobTitle"
label={true}
labelName="Job title"
type="text"
placeholder=""
value={jobTitle}
onChange={(e) => setJobTitle(e.target.value)}
/>
<Input
name="startDate"
label={true}
labelName="Start date"
type="text"
placeholder=""
value={employmentStart}
onChange={(e) => setEmploymentStart(e.target.value)}
/>
<Input
name="endDate"
label={true}
labelName="End date"
type="text"
placeholder=""
value={employmentEnd}
onChange={(e) => setEmploymentEnd(e.target.value)}
/>
<div className="input">
<label>Description</label>
<textarea
name="jobDescription"
value={jobDescription}
onChange={(e) => setJobDescription(e.target.value)}
rows="5"
maxLength="400"
/>
</div>
<div className="btn-group">
<Button
onClick={(e) =>
handleSubmit(e, {
employer,
jobTitle,
jobDescription,
employmentStart,
employmentEnd,
})
}
className="submit-btn"
text="Submit"
/>
<Button
onClick={(e) => {
e.preventDefault();
clear();
}}
className="clear-btn"
text="Clear"
/>
</div>
</form>
</div>
) : null}
</>
);
}

View file

@ -0,0 +1,17 @@
export default function GeneralInfoDisplay(props) {
const basicInfo = props.basicInfo;
return (
<>
{basicInfo ? (
<div className="basic-info">
<h1>{basicInfo.fullName}</h1>
<div className="basic-info-details">
<p>{basicInfo.location}</p>
<p>{basicInfo.email}</p>
<p>{basicInfo.phone}</p>
</div>
</div>
) : null}
</>
);
}

View file

@ -0,0 +1,83 @@
import { useState } from "react";
import Input from "./input";
export default function GeneralInfoForm(props) {
const [fullName, setFullName] = useState(props.basicInfo.fullName);
const [location, setLocation] = useState(props.basicInfo.location);
const [phone, setPhone] = useState(props.basicInfo.phone);
const [email, setEmail] = useState(props.basicInfo.email);
const contactFormStyle = {
display: "flex",
flexDirection: "column",
};
return (
<>
<div className="general-info-form">
<form action="">
<div style={contactFormStyle}>
<h2 className="general-info-header">Personal Details</h2>
<Input
label={true}
name="fullName"
labelName="Full name"
value={fullName}
placeholder=""
onChange={(e) => {
setFullName(e.target.value);
props.setBasicInfo({
...props.basicInfo,
fullName: e.target.value,
});
}}
/>
<Input
label={true}
name="location"
labelName="Location"
placeholder=""
value={location}
onChange={(e) => {
setLocation(e.target.value);
props.setBasicInfo({
...props.basicInfo,
location: e.target.value,
});
}}
/>
<Input
label={true}
type="email"
name="email"
labelName="Email"
placeholder=""
value={email}
onChange={(e) => {
setEmail(e.target.value);
props.setBasicInfo({
...props.basicInfo,
email: e.target.value,
});
}}
/>
<Input
type="text"
label={true}
labelName="Phone"
placeholder=""
value={phone}
onChange={(e) => {
setPhone(e.target.value);
props.setBasicInfo({
...props.basicInfo,
phone: e.target.value,
});
}}
/>
</div>
</form>
</div>
</>
);
}

View file

@ -0,0 +1,19 @@
import "../styles/input.css";
export default function Input(props) {
return (
<div className="input">
{props.label ? (
<label htmlFor={props.name}>{props.labelName}</label>
) : null}
<input
name={props.name}
id={props.name}
type={props.type}
value={props.value}
onChange={props.onChange}
placeholder={props.placeholder}
/>
</div>
);
}