Skip to content

Commit bd764f8

Browse files
authored
Merge pull request #14 from p0nch000/feature/edit-pages
Feature/edit pages
2 parents 3329ae4 + c2493ca commit bd764f8

21 files changed

+19900
-1387
lines changed

package-lock.json

+17,047
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+10-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
"start": "react-scripts start",
1818
"build": "react-scripts build",
1919
"test": "react-scripts test",
20-
"eject": "react-scripts eject"
20+
"eject": "react-scripts eject",
21+
"prettier": "prettier --write .",
22+
"prettier:check": "prettier --check .",
23+
"prepare": "husky install"
2124
},
2225
"eslintConfig": {
2326
"extends": [
@@ -40,6 +43,11 @@
4043
},
4144
"devDependencies": {
4245
"eslint-config-prettier": "^8.8.0",
43-
"prettier": "2.8.8"
46+
"prettier": "2.8.8",
47+
"husky": "^8.0.0",
48+
"lint-staged": "^13.0.0"
49+
},
50+
"lint-staged": {
51+
"**/*": "prettier --write --ignore-unknown"
4452
}
4553
}

src/App.css

+19-6
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ body {
99

1010
.resumeSection {
1111
background-color: white;
12-
padding: 10px;
13-
margin-left: 30%;
14-
margin-right: 30%;
12+
padding: 20px;
13+
margin: 0 auto 20px;
14+
max-width: 600px;
1515
border-radius: 15px;
1616
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
17-
margin-bottom: 20px;
1817
color: black;
1918
}
2019

@@ -23,9 +22,23 @@ body {
2322
}
2423

2524
button {
26-
padding: 10px;
25+
padding: 10px 15px;
26+
border: none;
2727
border-radius: 4px;
28-
background-color: rgb(248 185 42);
28+
background-color: rgb(248, 185, 42);
29+
cursor: pointer;
30+
transition: background-color 0.3s ease;
31+
}
32+
33+
button:hover {
34+
background-color: rgb(230, 170, 30);
35+
}
36+
37+
.button-group {
38+
display: flex;
39+
justify-content: center;
40+
gap: 10px;
41+
margin-top: 10px;
2942
}
3043

3144
.modal-overlay {

src/App.js

+84-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,58 @@
1+
import React, { useState } from "react";
12
import "./App.css";
3+
import AddSkillForm from "./components/skills/AddSkillForm";
4+
import SkillView from "./components/skills/SkillView";
5+
import SkillEditPage from "./components/skills/SkillEditPage";
6+
import EducationForm from "./components/education/EducationForm";
7+
import EducationView from "./components/education/EducationView";
8+
import EducationEditPage from "./components/education/EducationEditPage";
29
import User from "./components/User/page";
310

411
function App() {
12+
const [showAddSkillForm, setShowAddSkillForm] = useState(false);
13+
const [showSkillEditPage, setShowSkillEditPage] = useState(false);
14+
const [skills, setSkills] = useState([]);
15+
16+
const [showEducationForm, setShowEducationForm] = useState(false);
17+
const [showEducationEditPage, setShowEducationEditPage] = useState(false);
18+
const [education, setEducation] = useState([]);
19+
20+
const handleAddSkillClick = () => {
21+
setShowAddSkillForm(!showAddSkillForm);
22+
};
23+
24+
const handleFormSubmit = (newSkill) => {
25+
setSkills([...skills, newSkill]);
26+
setShowAddSkillForm(false);
27+
};
28+
29+
const toggleSkillEditPage = () => {
30+
setShowSkillEditPage(!showSkillEditPage);
31+
};
32+
33+
const handleSkillUpdate = (updatedSkills) => {
34+
setSkills(updatedSkills);
35+
setShowSkillEditPage(false);
36+
};
37+
38+
const handleAddEducationClick = () => {
39+
setShowEducationForm(!showEducationForm);
40+
};
41+
42+
const handleEducationFormSubmit = (newEducation) => {
43+
setEducation([...education, newEducation]);
44+
setShowEducationForm(false);
45+
};
46+
47+
const toggleEducationEditPage = () => {
48+
setShowEducationEditPage(!showEducationEditPage);
49+
};
50+
51+
const handleEducationUpdate = (updatedEducation) => {
52+
setEducation(updatedEducation);
53+
setShowEducationEditPage(false);
54+
};
55+
556
return (
657
<div className="App">
758
<h1>Resume Builder</h1>
@@ -15,21 +66,46 @@ function App() {
1566
<h2>Experience</h2>
1667
<p>Experience Placeholder</p>
1768
<button>Add Experience</button>
18-
<br></br>
69+
<br />
1970
</div>
2071
<div className="resumeSection">
2172
<h2>Education</h2>
22-
<p>Education Placeholder</p>
23-
<button>Add Education</button>
24-
<br></br>
73+
<EducationView education={education} />
74+
<div className="button-group">
75+
<button onClick={handleAddEducationClick}>
76+
{showEducationForm ? "Hide" : "Add Education"}
77+
</button>
78+
<button onClick={toggleEducationEditPage}>
79+
{showEducationEditPage ? "Hide Edit Education" : "Edit Education"}
80+
</button>
81+
</div>
82+
{showEducationForm && (
83+
<EducationForm onSubmit={handleEducationFormSubmit} />
84+
)}
85+
{showEducationEditPage && (
86+
<EducationEditPage
87+
education={education}
88+
onUpdate={handleEducationUpdate}
89+
/>
90+
)}
2591
</div>
2692
<div className="resumeSection">
2793
<h2>Skills</h2>
28-
<p>Skill Placeholder</p>
29-
<button>Add Skill</button>
30-
<br></br>
94+
<SkillView skills={skills} />
95+
<div className="button-group">
96+
<button onClick={handleAddSkillClick}>
97+
{showAddSkillForm ? "Hide" : "Add Skill"}
98+
</button>
99+
<button onClick={toggleSkillEditPage}>
100+
{showSkillEditPage ? "Hide Edit Skills" : "Edit Skills"}
101+
</button>
102+
</div>
103+
{showAddSkillForm && <AddSkillForm onSubmit={handleFormSubmit} />}
104+
{showSkillEditPage && (
105+
<SkillEditPage skills={skills} onUpdate={handleSkillUpdate} />
106+
)}
31107
</div>
32-
<br></br>
108+
<br />
33109
<button>Export</button>
34110
</div>
35111
);

src/App.test.js

+30-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
1+
import React from "react";
12
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
2-
// import App from "./App";
3+
import App from "./App";
34
import User from "./components/User/page.jsx";
45

5-
/*
6-
test("renders learn react link", () => {
6+
// App component test
7+
test("renders main components of Resume Builder", () => {
78
render(<App />);
8-
const linkElement = screen.getByText(/learn react/i);
9-
expect(linkElement).toBeInTheDocument();
9+
10+
// Check for the main title
11+
const titleElement = screen.getByText(/Resume Builder/i);
12+
expect(titleElement).toBeInTheDocument();
13+
14+
// Check for section titles
15+
expect(
16+
screen.getByRole("heading", { name: /Experience/i })
17+
).toBeInTheDocument();
18+
expect(
19+
screen.getByRole("heading", { name: /Education/i })
20+
).toBeInTheDocument();
21+
expect(screen.getByRole("heading", { name: /Skills/i })).toBeInTheDocument();
22+
23+
// Check for some buttons
24+
expect(
25+
screen.getByRole("button", { name: /Add Experience/i })
26+
).toBeInTheDocument();
27+
expect(
28+
screen.getByRole("button", { name: /Add Education/i })
29+
).toBeInTheDocument();
30+
expect(
31+
screen.getByRole("button", { name: /Add Skill/i })
32+
).toBeInTheDocument();
33+
expect(screen.getByRole("button", { name: /Export/i })).toBeInTheDocument();
1034
});
11-
*/
1235

1336
// User component test
1437
describe("User Component", () => {
@@ -91,3 +114,4 @@ describe("User Component", () => {
91114
});
92115
});
93116
});
117+

src/assets/close.png

5.19 KB
Loading

src/assets/edit.png

10.8 KB
Loading

src/assets/graduation-cap.png

15.1 KB
Loading
+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { useState } from "react";
2+
import defaultLogo from "../../assets/graduation-cap.png";
3+
4+
const EducationEdit = ({ education, showEdit, setShowEdit }) => {
5+
const [formData, setFormData] = useState(education);
6+
7+
const handleChange = (field) => (e) => {
8+
e.preventDefault();
9+
10+
setFormData({
11+
...formData,
12+
[field]: e.currentTarget.value,
13+
});
14+
};
15+
16+
const handleSubmit = (e) => {
17+
e.preventDefault();
18+
19+
fetch("/resume/education", {
20+
method: "PATCH",
21+
headers: {
22+
"Content-Type": "application/json",
23+
},
24+
body: JSON.stringify(formData),
25+
})
26+
.then((response) => response.json())
27+
.then((data) => {
28+
setShowEdit([false, null]);
29+
alert("Education successfully updated!");
30+
})
31+
.catch((error) => {
32+
setShowEdit([false, null]);
33+
alert("Error: Education not updated :(");
34+
});
35+
};
36+
37+
const handleEditClick = (e) => {
38+
e.preventDefault();
39+
setShowEdit([false, null]);
40+
};
41+
42+
return (
43+
<div className="modal">
44+
<div className="modal-content">
45+
<span class="close" onClick={handleEditClick}>
46+
&times;
47+
</span>
48+
<div className="education-form-container">
49+
<form onSubmit={handleSubmit}>
50+
<h1 className="education-item-school">
51+
<img src={defaultLogo} alt="defaultLogo" className="logo" />
52+
Edit Education
53+
</h1>
54+
<label>
55+
<h2>Course</h2>
56+
<input
57+
type="text"
58+
value={formData.course}
59+
placeholder={education.course}
60+
onChange={handleChange("course")}
61+
/>
62+
</label>
63+
<label>
64+
<h2>School</h2>
65+
<input
66+
type="text"
67+
value={formData.school}
68+
placeholder={education.school}
69+
onChange={handleChange("school")}
70+
/>
71+
</label>
72+
<label>
73+
<h2>Start Date</h2>
74+
<input
75+
type="month"
76+
value={formData.start_date}
77+
placeholder={education.start_date}
78+
onChange={handleChange("start_date")}
79+
/>
80+
</label>
81+
<label>
82+
<h2>End Date</h2>
83+
<input
84+
type="month"
85+
value={formData.end_date}
86+
placeholder={education.end_date}
87+
onChange={handleChange("end_date")}
88+
/>
89+
</label>
90+
<label>
91+
<h2>Grade</h2>
92+
<input
93+
type="number"
94+
min="0"
95+
max="100"
96+
value={formData.grade}
97+
placeholder={education.grade}
98+
onChange={handleChange("grade")}
99+
/>
100+
%
101+
</label>
102+
<label>
103+
<h2>Logo URL</h2>
104+
<input
105+
type="text"
106+
value={formData.logo}
107+
placeholder={education.logo}
108+
onChange={handleChange("logo")}
109+
/>
110+
</label>
111+
112+
<button onSubmit={handleSubmit}>Edit Education</button>
113+
</form>
114+
</div>
115+
</div>
116+
</div>
117+
);
118+
};
119+
120+
export default EducationEdit;

0 commit comments

Comments
 (0)