feat: new components, style, etc

This commit is contained in:
Mike 2024-06-22 13:17:36 -04:00
parent c3184ad970
commit 148d037942
11 changed files with 235 additions and 121 deletions

View file

@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<title>CV-Creator</title>
</head>
<body>
<div id="root"></div>

View file

@ -0,0 +1,68 @@
:root {
--font-size: 16px;
--default-border-radius: 0.5rem;
/* Shadows */
--default-shadow: 0 4px 6px hsla(0, 0%, 0%, 0.2);
--small-shadow: 0 1px 3px hsla(0, 0%, 0%, 0.2);
--large-shadow: 0 15px 35px hsla(0, 0%, 0%, 0.2);
--tight-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
--wide-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
/* Grays */
--lightest-gray: 208, 21%, 93%;
--lighter-gray: 210, 16%, 76%;
--light-gray: 208, 12%, 58%;
--dark-gray: 207, 12%, 43%;
--darker-gray: 209, 15%, 28%;
--white-color: 360, 100%, 100%;
}
html,
body {
padding: 0;
margin: 0;
font-size: var(--font-size);
background: hsl(var(--lightest-gray));
}
.container {
display: flex;
justify-content: center;
padding: 24px;
gap: 30px;
}
.resume {
min-width: 800px;
/* background: gray; */
}
.form {
max-width: 450px;
min-width: 400px;
}
.general-info-form {
padding: 20px;
margin-bottom: 1rem;
border-radius: var(--default-border-radius);
box-shadow: var(--tight-shadow), var(--wide-shadow);
background: hsl(var(--white-color));
}
.basic-info {
display: flex;
flex-direction: column;
align-items: center;
}
.basic-info p {
padding: 0;
margin: 0;
}
.basic-info-details {
display: flex;
gap: 1rem;
}

View file

@ -3,18 +3,21 @@ import GeneralInfoDisplay from "./components/generalInfoDisplay";
import EducationInfoDisplay from "./components/educationInfoDisplay";
import EducationInfoForm from "./components/educationInfoForm";
import ExperienceForm from "./components/experienceForm";
import ExperienceDisplay from "./components/experienceDisplay";
import "./App.css";
import { useState } from "react";
function App() {
const [basicInfo, setBasicInfo] = useState({
firstName: "",
lastName: "",
phone: "",
email: "",
fullName: "Marvin Gaye",
phone: "301-240-5555",
email: "mgaye@motown.com",
location: "Detriot, MI",
});
const [educationInfo, setEducationInfo] = useState([]);
const [editEducation, setEditEducation] = useState(null);
const [employmentHistory, setEmploymentHistory] = useState([]);
return (
<div className="container">
@ -26,7 +29,10 @@ function App() {
setEditEducation={setEditEducation}
editEducation={editEducation}
/>
<ExperienceForm />
<ExperienceForm
employmentHistory={employmentHistory}
setEmploymentHistory={setEmploymentHistory}
/>
</div>
<div className="resume">
<GeneralInfoDisplay basicInfo={basicInfo} />
@ -35,6 +41,7 @@ function App() {
setEditEducation={setEditEducation}
setEducationInfo={setEducationInfo}
/>
<ExperienceDisplay employmentHistory={employmentHistory} />
</div>
</div>
);

View file

@ -1,31 +1,25 @@
export default function EducationInfoDisplay(props) {
return (
<div>
{props.educationInfo.length <= 0 ? (
<>
<p>Add your Education info</p>
</>
) : (
<EducationDisplay
educationInfo={props.educationInfo}
setEducationInfo={props.setEducationInfo}
setEditEducation={props.setEditEducation}
/>
)}
</div>
</>
);
}
function EducationDisplay(props) {
return (
<div>
<>
{props.educationInfo.map((item) => {
return (
<div key={item.schoolName} className="education-info">
<h2>School: {item.schoolName}</h2>
<p>
Graduation Date: {item.graduationDate + " "}
Field of Study: {item.fieldOfStudy}
Graduation: {item.graduationDate + " "}
Degree: {item.fieldOfStudy}
<button onClick={() => props.setEditEducation(item)}>edit</button>
<button
onClick={() =>
@ -42,7 +36,7 @@ function EducationDisplay(props) {
</div>
);
})}
</div>
</>
);
}

View file

@ -1,9 +1,7 @@
import { useState, useEffect } from "react";
export default function EducationInfoForm(props) {
// const [schools, setSchools] = useState([]);
const [educationItemActive, setEducationItemActive] = useState(false);
// const [editSchool, setEditSchool] = useState(null);
return (
<div className="education-info section">
@ -50,15 +48,12 @@ function EducationForm({
}, [editSchool]);
let schoolId = editSchool
? educationInfo.findIndex(
(school) => school.schoolName === editSchool.schoolName,
)
? educationInfo.findIndex((school) => school.id === editSchool.id)
: null;
const contactFormStyle = {
display: "flex",
flexDirection: "column",
width: "30vw",
};
return (
@ -68,19 +63,19 @@ function EducationForm({
<form action="" style={contactFormStyle}>
<input
type="text"
placeholder="School Name"
placeholder="Enter university/school"
value={schoolName}
onChange={(e) => setSchoolName(e.target.value)}
/>
<input
type="text"
placeholder="Graduation Date"
placeholder="Enter graduation date"
value={graduationDate}
onChange={(e) => setGraduationDate(e.target.value)}
/>
<input
type="text"
placeholder="Field of Study"
placeholder="Enter degree/field of study"
value={fieldOfStudy}
onChange={(e) => setFieldOfStudy(e.target.value)}
/>
@ -103,6 +98,7 @@ function EducationForm({
schoolName: schoolName,
fieldOfStudy: fieldOfStudy,
graduationDate: graduationDate,
id: crypto.randomUUID(),
},
]);
}
@ -120,6 +116,7 @@ function EducationForm({
setGraduationDate("");
setSchoolName("");
setFieldOfStudy("");
schoolId = null;
}}
>
Clear

View file

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

View file

@ -1,46 +1,20 @@
import { useState } from "react";
export default function ExperienceForm() {
const [jobs, setJobs] = useState([]);
export default function ExperienceForm(props) {
// const [jobs, setJobs] = useState([]);
const [showJobForm, setShowJobForm] = useState(false);
const mainDivStyle = {
display: "flex",
justifyContent: "space-between",
flexDirection: "row-reverse",
};
return (
<div className="jobs" style={mainDivStyle}>
<div className="job-info">
<JobList jobs={jobs} />
</div>
<div className="Job-info-form">
<button onClick={() => setShowJobForm(!showJobForm)}>
Add Employer Info
</button>
<JobForm setJobs={setJobs} jobs={jobs} isActive={showJobForm} />
<JobForm
setJobs={props.setEmploymentHistory}
jobs={props.employmentHistory}
isActive={showJobForm}
/>
</div>
</div>
);
}
function JobList(props) {
return (
<>
{props.jobs.map((item) => {
return (
<div className="job" key={item.id}>
<h2>{item.employer}</h2>
<h3>{item.jobTitle}</h3>
<p>
{item.employmentStart} - {item.employmentEnd}
</p>
<p>{item.jobDescription}</p>
</div>
);
})}
</>
);
}
@ -54,7 +28,6 @@ function JobForm({ isActive, jobs, setJobs }) {
const formStyle = {
display: "flex",
flexDirection: "column",
width: "30vw",
};
function clear() {
@ -68,7 +41,8 @@ function JobForm({ isActive, jobs, setJobs }) {
function handleSubmit(event, stuff) {
event.preventDefault();
const newJob = { ...stuff };
const key = crypto.randomUUID();
const newJob = { ...stuff, id: key };
setJobs([...jobs, newJob]);

View file

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

View file

@ -1,68 +1,83 @@
import { useState } from "react";
import Input from "./input";
export default function GeneralInfoForm(props) {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [fullName, setFullName] = useState("");
const [location, setLocation] = useState("");
const [phone, setPhone] = useState("");
const [email, setEmail] = useState("");
const contactFormStyle = {
display: "flex",
flexDirection: "column",
width: "30vw",
};
const mainStyle = {
display: "flex",
justifyContent: "space-between",
};
return (
<div className="general-info section" style={mainStyle}>
<div className="contact-info-form">
<>
<div className="general-info-form">
<form action="">
<div style={contactFormStyle}>
<input
type="text"
placeholder="First Name"
value={firstName}
<h2 className="general-info-header">Personal Details</h2>
<Input
label={true}
name="fullName"
labelName="Full name"
value={fullName}
placeholder=""
onChange={(e) => {
setFirstName(e.target.value)
props.setBasicInfo({ ...props.basicInfo, firstName: e.target.value })
}
}
setFullName(e.target.value);
props.setBasicInfo({
...props.basicInfo,
fullName: e.target.value,
});
}}
/>
<input
type="text"
placeholder="Last Name"
value={lastName}
<Input
label={true}
name="location"
labelName="Location"
placeholder=""
value={location}
onChange={(e) => {
setLastName(e.target.value)
props.setBasicInfo({ ...props.basicInfo, lastName: e.target.value })
}} />
<input
setLocation(e.target.value);
props.setBasicInfo({
...props.basicInfo,
location: e.target.value,
});
}}
/>
<Input
label={true}
type="email"
placeholder="Email"
name="email"
labelName="Email"
placeholder=""
value={email}
onChange={(e) => {
setEmail(e.target.value)
props.setBasicInfo({ ...props.basicInfo, email: e.target.value })
}
}
setEmail(e.target.value);
props.setBasicInfo({
...props.basicInfo,
email: e.target.value,
});
}}
/>
<input
<Input
type="text"
placeholder="Phone Number"
label={true}
labelName="Phone"
placeholder=""
value={phone}
onChange={(e) => {
setPhone(e.target.value)
props.setBasicInfo({ ...props.basicInfo, phone: e.target.value })
setPhone(e.target.value);
props.setBasicInfo({
...props.basicInfo,
phone: e.target.value,
});
}}
/>
</div>
</form>
</div>
</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>
);
}

View file

@ -0,0 +1,15 @@
.input {
display: flex;
flex-direction: column;
font-size: 1.3rem;
line-height: 1.3;
}
.input label {
padding: 10px 0 5px 0;
font-size: 1rem;
}
.input input {
font-size: 1.3rem;
}