├── .gitignore
├── .nfs.2005102e.6c0c
├── README.md
├── assets
├── css
│ ├── employee.css
│ ├── login.css
│ ├── main.css
│ └── normalize.css
├── demo
│ ├── demo-creating.gif
│ ├── demo-deleting.gif
│ └── demo-login.gif
├── html
│ ├── footer.html
│ └── header.html
├── img
│ └── 3669361_delete_ic_icon.png
└── js
│ └── index.js
├── index.php
├── package-lock.json
├── package.json
├── resources
├── employees.json
├── images_mock.json
└── users.json
└── src
├── dashboard.php
├── employee.php
├── imageGallery.php
└── library
├── avatarsApi.php
├── employeeController.php
├── employeeManager.php
├── loginController.php
├── loginManager.php
└── sessionHelper.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 |
--------------------------------------------------------------------------------
/.nfs.2005102e.6c0c:
--------------------------------------------------------------------------------
1 | `#php` `#CRUD` `#master-in-software-engineering`
2 |
3 | # PHP Employee manager application
4 |
5 | ## About this project
6 |
7 | In this project we demonstrate CRUD operation with PHP JSON and JS. The main goal was to learn how to make a fetch request from the client side using JS, receiving the request in PHP and CRUDing over the JSON file, sending it back to the front-end.
8 |
9 |
10 | ## Getting Started
11 |
12 | There's not too much to it, just make sure your machine is supporting a php development environment, if not you can download any of your favourite integrated development environment software such as [XAMPP](https://www.apachefriends.org/index.html) or [WAMP](https://www.wampserver.com/en/) if you are using Windows OS.
13 |
14 |
15 | ### Installing
16 |
17 | After cloning make sure you copy all the files into htdocs in your local machine so you can see the output in your browser.
18 | Run your localhost with the cloned folder.
19 |
20 |
21 | ### Log in
22 |
23 | In order to log in, use the following fake details:
24 |
25 | ```
26 | Email: admin@assemblerschool.com
27 | Password: 123456
28 | ```
29 |
30 |
31 | ## Technologies and Libraries
32 |
33 | * PHP
34 | * JavaScript
35 | * HTML
36 | * CSS
37 | * [Sweet Alert 2](https://sweetalert2.github.io/)
38 |
39 |
40 | ## Demo
41 |
42 | 
43 | 
44 | 
45 |
46 | ## Authors
47 |
48 | [Sefi Cohen](https://github.com/seficohen1)
49 |
50 | [Julio Macias](https://github.com/juliomc23)
51 |
52 |
53 | ## License
54 |
55 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
56 |
57 | ## Acknowledgments
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | `#php` `#CRUD` `#master-in-software-engineering`
2 |
3 | # PHP Employee manager application
4 |
5 | ## About this project
6 |
7 | In this project we demonstrate CRUD operation with PHP JSON and JS. The main goal was to learn how to make a fetch request from the client side using JS, receiving the request in PHP and CRUDing over the JSON file, sending it back to the front-end.
8 |
9 |
10 | ## Getting Started
11 |
12 | There's not too much to it, just make sure your machine is supporting a php development environment, if not you can download any of your favourite integrated development environment software such as [XAMPP](https://www.apachefriends.org/index.html) or [WAMP](https://www.wampserver.com/en/) if you are using Windows OS.
13 |
14 |
15 | ### Installing
16 |
17 | After cloning make sure you copy all the files into htdocs in your local machine so you can see the output in your browser.
18 | Run your localhost with the cloned folder.
19 |
20 |
21 | ### Log in
22 |
23 | In order to log in, use the following fake details:
24 |
25 | ```
26 | Email: admin@assemblerschool.com
27 | Password: 123456
28 | ```
29 |
30 |
31 | ## Technologies and Libraries
32 |
33 | * PHP
34 | * JavaScript
35 | * HTML
36 | * CSS
37 | * [Sweet Alert 2](https://sweetalert2.github.io/)
38 |
39 |
40 | ## Demo
41 |
42 | 
43 | 
44 | 
45 |
46 | ## Authors
47 |
48 | [Sefi Cohen](https://github.com/seficohen1)
49 |
50 | [Julio Macias](https://github.com/juliomc23)
51 |
52 |
53 | ## License
54 |
55 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
56 |
57 | ## Acknowledgments
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/assets/css/employee.css:
--------------------------------------------------------------------------------
1 | @import url(./normalize.css);
2 | @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300;400&display=swap');
3 |
4 | :root {
5 | --primary: #143F6B;
6 | --secondary: #F55353;
7 | --terciary: #FEB139;
8 | --cuaternary: #F6F54D;
9 | }
10 |
11 | .main__content{
12 | height: 100vh;
13 | width: 100%;
14 | display: flex;
15 | justify-content: center;
16 | align-items: center;
17 | background-color: var(--primary);
18 | font-family: 'Mulish', sans-serif;
19 | }
20 |
21 | .formEl__edit{
22 | width: 75%;
23 | height: 75%;
24 | display: flex;
25 | flex-wrap: wrap;
26 | justify-content: space-around;
27 | align-items: center;
28 | background-color: var(--terciary);
29 | border-radius: 0.5rem;
30 | }
31 |
32 | input{
33 | height: 2rem;
34 | background-color: white;
35 | border: none;
36 | font-weight: bold;
37 | text-align: left;
38 | letter-spacing: 0.1rem;
39 | text-align: center;
40 | border-radius: 0.5rem;
41 | outline: none;
42 | font-size: 1.3rem;
43 | width: 15rem;
44 | }
45 |
46 | .div__inputLabel{
47 | width: 30%;
48 | height: 5rem;
49 | display: flex;
50 | flex-direction: column;
51 | justify-content: space-around;
52 | align-items: center;
53 | }
54 |
55 | label{
56 | cursor: pointer;
57 | font-weight: bold;
58 | letter-spacing: 0.1rem;
59 | }
60 |
61 | .button__change{
62 | border: none;
63 | background-color: var(--primary);
64 | color: white;
65 | font-weight: bold;
66 | height: 2.2rem;
67 | width: 5rem;
68 | border-radius: 1rem;
69 | cursor: pointer;
70 | transition: all 300ms;
71 | }
72 |
73 | .button__change:hover{
74 | transform: scale(1.1);
75 | background-color: #17538f;
76 | }
--------------------------------------------------------------------------------
/assets/css/login.css:
--------------------------------------------------------------------------------
1 | @import url(./normalize.css);
2 | @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300;400&display=swap');
3 |
4 | :root{
5 | --primary: #143F6B;
6 | --secondary: #F55353;
7 | --terciary: #FEB139;
8 | --cuaternary: #F6F54D;
9 | }
10 |
11 |
12 | .main__section{
13 | height: 100vh;
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: center;
17 | align-items: center;
18 | background-color: var(--primary);
19 | font-family: 'Mulish', sans-serif;
20 | }
21 |
22 | .main__form{
23 | border: 1px solid black;
24 | height: 10rem;
25 | width: 30rem;
26 | display: flex;
27 | flex-direction: column;
28 | justify-content: center;
29 | align-items: center;
30 | background-color: var(--secondary);
31 | border-radius: 1rem;
32 | }
33 |
34 | .name__input{
35 | width: 75%;
36 | height: 25%;
37 | padding-left: 1rem;
38 | border: none;
39 | border-bottom: 0.5px solid #ccc;
40 | border-top-left-radius: 1rem;
41 | border-top-right-radius: 1rem;
42 | outline: none;
43 | }
44 |
45 | .pass__input{
46 | width: 75%;
47 | height: 25%;
48 | padding-left: 1rem;
49 | border: none;
50 | border-top: none;
51 | border-bottom-left-radius: 1rem;
52 | border-bottom-right-radius: 1rem;
53 | outline: none;
54 | }
55 |
56 | .login__input{
57 | margin-top: 1rem;
58 | height: 2rem;
59 | width: 5rem;
60 | background-color: var(--terciary);
61 | font-weight: bold;
62 | transition: all 300ms;
63 | border-radius: 1rem;
64 | }
65 |
66 | .login__input:hover{
67 | cursor: pointer;
68 | transform: scale(1.1);
69 | }
70 |
71 | .alert__span{
72 | margin-top: 2rem;
73 | color: white;
74 | text-transform: uppercase;
75 | letter-spacing: 0.2rem;
76 | font-weight: bold;
77 | }
--------------------------------------------------------------------------------
/assets/css/main.css:
--------------------------------------------------------------------------------
1 | @import url(./normalize.css);
2 | @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@300;400&display=swap');
3 |
4 | :root {
5 | --primary: #143F6B;
6 | --secondary: #F55353;
7 | --terciary: #FEB139;
8 | --cuaternary: #F6F54D;
9 | }
10 |
11 |
12 | .toggle {
13 | display: none;
14 | }
15 |
16 |
17 | .fade-out {
18 | -webkit-animation: fade-out 1s ease-out 1.5s both;
19 | animation: fade-out 1s ease-out 1.5s both;
20 | }
21 |
22 | @-webkit-keyframes fade-out {
23 | 0% {
24 | opacity: 1;
25 | }
26 |
27 | 100% {
28 | opacity: 0;
29 | }
30 | }
31 |
32 | @keyframes fade-out {
33 | 0% {
34 | opacity: 1;
35 | }
36 |
37 | 100% {
38 | opacity: 0;
39 | }
40 | }
41 |
42 | .main__container {
43 | height: 100vh;
44 | font-family: 'Mulish', sans-serif;
45 | }
46 |
47 | .employee_table {
48 | width: 100%;
49 | height: 100%;
50 | text-align: center;
51 | }
52 |
53 | .thead__table{
54 | width: 100%;
55 | color: var(--primary);
56 | height: 4rem;
57 | }
58 |
59 | .trow__tableHead{
60 | width: 100%;
61 | }
62 |
63 | .thead__col{
64 | width: 12%;
65 | font-weight: bold;
66 | font-size: 1.1rem;
67 | }
68 |
69 | .addEmp__button{
70 | height: 2rem;
71 | width: 2rem;
72 | display: flex;
73 | justify-content: center;
74 | align-items: center;
75 | font-size: 2rem;
76 | padding-bottom: 0.35rem;
77 | font-weight: bold;
78 | background-color: transparent;
79 | background-color: green;
80 | color: white;
81 | border: none;
82 | border-radius: 10rem;
83 | cursor: pointer;
84 | }
85 |
86 | .delete__Button{
87 | background-color: transparent;
88 | color: var(--secondary);
89 | border: none;
90 | cursor: pointer;
91 | }
92 |
93 | .edit__button{
94 | color: var(--primary);
95 | text-decoration: none;
96 | margin-right: 1.2rem;
97 | }
98 |
99 | .createEmp__button{
100 | background-color: transparent;
101 | border: none;
102 | cursor: pointer;
103 | }
104 |
105 | .delete__Button{
106 | background-image: url('../img/3669361_delete_ic_icon.png');
107 | height: 24px;
108 | width: 24px;
109 | background-color: transparent;
110 | color: var(--secondary);
111 | border: none;
112 | cursor: pointer;
113 | }
114 |
115 | .fa-check{
116 | color: green;
117 | font-size: 2rem;
118 | transition: all 300ms;
119 | }
120 |
121 |
122 | .fa-check:hover{
123 | color: rgb(1, 202, 1);
124 | font-size: 2rem;
125 | }
126 |
127 | input{
128 | padding-left: 0.3rem;
129 | /* text-transform: capitalize; */
130 | outline: none;
131 | border: 1px solid black;
132 | }
133 |
134 |
135 |
136 | .fa-pen-to-square {
137 | width: 24px;
138 | height: 24px;
139 | }
--------------------------------------------------------------------------------
/assets/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in iOS.
9 | */
10 |
11 | html {
12 | line-height: 1.15; /* 1 */
13 | -webkit-text-size-adjust: 100%; /* 2 */
14 | }
15 |
16 | /* Sections
17 | ========================================================================== */
18 |
19 | /**
20 | * Remove the margin in all browsers.
21 | */
22 |
23 | body {
24 | margin: 0;
25 | }
26 |
27 | /**
28 | * Render the `main` element consistently in IE.
29 | */
30 |
31 | main {
32 | display: block;
33 | }
34 |
35 | /**
36 | * Correct the font size and margin on `h1` elements within `section` and
37 | * `article` contexts in Chrome, Firefox, and Safari.
38 | */
39 |
40 | h1 {
41 | font-size: 2em;
42 | margin: 0.67em 0;
43 | }
44 |
45 | /* Grouping content
46 | ========================================================================== */
47 |
48 | /**
49 | * 1. Add the correct box sizing in Firefox.
50 | * 2. Show the overflow in Edge and IE.
51 | */
52 |
53 | hr {
54 | box-sizing: content-box; /* 1 */
55 | height: 0; /* 1 */
56 | overflow: visible; /* 2 */
57 | }
58 |
59 | /**
60 | * 1. Correct the inheritance and scaling of font size in all browsers.
61 | * 2. Correct the odd `em` font sizing in all browsers.
62 | */
63 |
64 | pre {
65 | font-family: monospace, monospace; /* 1 */
66 | font-size: 1em; /* 2 */
67 | }
68 |
69 | /* Text-level semantics
70 | ========================================================================== */
71 |
72 | /**
73 | * Remove the gray background on active links in IE 10.
74 | */
75 |
76 | a {
77 | background-color: transparent;
78 | }
79 |
80 | /**
81 | * 1. Remove the bottom border in Chrome 57-
82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83 | */
84 |
85 | abbr[title] {
86 | border-bottom: none; /* 1 */
87 | text-decoration: underline; /* 2 */
88 | text-decoration: underline dotted; /* 2 */
89 | }
90 |
91 | /**
92 | * Add the correct font weight in Chrome, Edge, and Safari.
93 | */
94 |
95 | b,
96 | strong {
97 | font-weight: bolder;
98 | }
99 |
100 | /**
101 | * 1. Correct the inheritance and scaling of font size in all browsers.
102 | * 2. Correct the odd `em` font sizing in all browsers.
103 | */
104 |
105 | code,
106 | kbd,
107 | samp {
108 | font-family: monospace, monospace; /* 1 */
109 | font-size: 1em; /* 2 */
110 | }
111 |
112 | /**
113 | * Add the correct font size in all browsers.
114 | */
115 |
116 | small {
117 | font-size: 80%;
118 | }
119 |
120 | /**
121 | * Prevent `sub` and `sup` elements from affecting the line height in
122 | * all browsers.
123 | */
124 |
125 | sub,
126 | sup {
127 | font-size: 75%;
128 | line-height: 0;
129 | position: relative;
130 | vertical-align: baseline;
131 | }
132 |
133 | sub {
134 | bottom: -0.25em;
135 | }
136 |
137 | sup {
138 | top: -0.5em;
139 | }
140 |
141 | /* Embedded content
142 | ========================================================================== */
143 |
144 | /**
145 | * Remove the border on images inside links in IE 10.
146 | */
147 |
148 | img {
149 | border-style: none;
150 | }
151 |
152 | /* Forms
153 | ========================================================================== */
154 |
155 | /**
156 | * 1. Change the font styles in all browsers.
157 | * 2. Remove the margin in Firefox and Safari.
158 | */
159 |
160 | button,
161 | input,
162 | optgroup,
163 | select,
164 | textarea {
165 | font-family: inherit; /* 1 */
166 | font-size: 100%; /* 1 */
167 | line-height: 1.15; /* 1 */
168 | margin: 0; /* 2 */
169 | }
170 |
171 | /**
172 | * Show the overflow in IE.
173 | * 1. Show the overflow in Edge.
174 | */
175 |
176 | button,
177 | input { /* 1 */
178 | overflow: visible;
179 | }
180 |
181 | /**
182 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
183 | * 1. Remove the inheritance of text transform in Firefox.
184 | */
185 |
186 | button,
187 | select { /* 1 */
188 | text-transform: none;
189 | }
190 |
191 | /**
192 | * Correct the inability to style clickable types in iOS and Safari.
193 | */
194 |
195 | button,
196 | [type="button"],
197 | [type="reset"],
198 | [type="submit"] {
199 | -webkit-appearance: button;
200 | }
201 |
202 | /**
203 | * Remove the inner border and padding in Firefox.
204 | */
205 |
206 | button::-moz-focus-inner,
207 | [type="button"]::-moz-focus-inner,
208 | [type="reset"]::-moz-focus-inner,
209 | [type="submit"]::-moz-focus-inner {
210 | border-style: none;
211 | padding: 0;
212 | }
213 |
214 | /**
215 | * Restore the focus styles unset by the previous rule.
216 | */
217 |
218 | button:-moz-focusring,
219 | [type="button"]:-moz-focusring,
220 | [type="reset"]:-moz-focusring,
221 | [type="submit"]:-moz-focusring {
222 | outline: 1px dotted ButtonText;
223 | }
224 |
225 | /**
226 | * Correct the padding in Firefox.
227 | */
228 |
229 | fieldset {
230 | padding: 0.35em 0.75em 0.625em;
231 | }
232 |
233 | /**
234 | * 1. Correct the text wrapping in Edge and IE.
235 | * 2. Correct the color inheritance from `fieldset` elements in IE.
236 | * 3. Remove the padding so developers are not caught out when they zero out
237 | * `fieldset` elements in all browsers.
238 | */
239 |
240 | legend {
241 | box-sizing: border-box; /* 1 */
242 | color: inherit; /* 2 */
243 | display: table; /* 1 */
244 | max-width: 100%; /* 1 */
245 | padding: 0; /* 3 */
246 | white-space: normal; /* 1 */
247 | }
248 |
249 | /**
250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
251 | */
252 |
253 | progress {
254 | vertical-align: baseline;
255 | }
256 |
257 | /**
258 | * Remove the default vertical scrollbar in IE 10+.
259 | */
260 |
261 | textarea {
262 | overflow: auto;
263 | }
264 |
265 | /**
266 | * 1. Add the correct box sizing in IE 10.
267 | * 2. Remove the padding in IE 10.
268 | */
269 |
270 | [type="checkbox"],
271 | [type="radio"] {
272 | box-sizing: border-box; /* 1 */
273 | padding: 0; /* 2 */
274 | }
275 |
276 | /**
277 | * Correct the cursor style of increment and decrement buttons in Chrome.
278 | */
279 |
280 | [type="number"]::-webkit-inner-spin-button,
281 | [type="number"]::-webkit-outer-spin-button {
282 | height: auto;
283 | }
284 |
285 | /**
286 | * 1. Correct the odd appearance in Chrome and Safari.
287 | * 2. Correct the outline style in Safari.
288 | */
289 |
290 | [type="search"] {
291 | -webkit-appearance: textfield; /* 1 */
292 | outline-offset: -2px; /* 2 */
293 | }
294 |
295 | /**
296 | * Remove the inner padding in Chrome and Safari on macOS.
297 | */
298 |
299 | [type="search"]::-webkit-search-decoration {
300 | -webkit-appearance: none;
301 | }
302 |
303 | /**
304 | * 1. Correct the inability to style clickable types in iOS and Safari.
305 | * 2. Change font properties to `inherit` in Safari.
306 | */
307 |
308 | ::-webkit-file-upload-button {
309 | -webkit-appearance: button; /* 1 */
310 | font: inherit; /* 2 */
311 | }
312 |
313 | /* Interactive
314 | ========================================================================== */
315 |
316 | /*
317 | * Add the correct display in Edge, IE 10+, and Firefox.
318 | */
319 |
320 | details {
321 | display: block;
322 | }
323 |
324 | /*
325 | * Add the correct display in all browsers.
326 | */
327 |
328 | summary {
329 | display: list-item;
330 | }
331 |
332 | /* Misc
333 | ========================================================================== */
334 |
335 | /**
336 | * Add the correct display in IE 10+.
337 | */
338 |
339 | template {
340 | display: none;
341 | }
342 |
343 | /**
344 | * Add the correct display in IE 10.
345 | */
346 |
347 | [hidden] {
348 | display: none;
349 | }
350 |
--------------------------------------------------------------------------------
/assets/demo/demo-creating.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/php-employee-management-v1/f317c9bf5968397c91d4cb573ff88430227109b2/assets/demo/demo-creating.gif
--------------------------------------------------------------------------------
/assets/demo/demo-deleting.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/php-employee-management-v1/f317c9bf5968397c91d4cb573ff88430227109b2/assets/demo/demo-deleting.gif
--------------------------------------------------------------------------------
/assets/demo/demo-login.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/php-employee-management-v1/f317c9bf5968397c91d4cb573ff88430227109b2/assets/demo/demo-login.gif
--------------------------------------------------------------------------------
/assets/html/footer.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/php-employee-management-v1/f317c9bf5968397c91d4cb573ff88430227109b2/assets/html/footer.html
--------------------------------------------------------------------------------
/assets/html/header.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/php-employee-management-v1/f317c9bf5968397c91d4cb573ff88430227109b2/assets/html/header.html
--------------------------------------------------------------------------------
/assets/img/3669361_delete_ic_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/juliomc23/php-employee-management-v1/f317c9bf5968397c91d4cb573ff88430227109b2/assets/img/3669361_delete_ic_icon.png
--------------------------------------------------------------------------------
/assets/js/index.js:
--------------------------------------------------------------------------------
1 | // GLOBAL VARIABLES
2 | const tableBodyEl = document.getElementById('table-body');
3 | const table = document.getElementById('table');
4 | const addNewEmpBtnEl = document.getElementById('addNewEmp');
5 | const createEmpButton = document.getElementById('createEmpButton');
6 | const empFormInputs = document.querySelectorAll('[form-emp]');
7 |
8 |
9 | // Functions
10 |
11 |
12 |
13 | const getEmps = async () => {
14 | const res = await fetch('.././src/library/employeeController.php');
15 | const data = await res.json()
16 |
17 | return data;
18 | }
19 | const deleteEmpId = (e) => {
20 |
21 | const btnId = e.currentTarget.getAttribute('data');
22 |
23 | Swal.fire({
24 | title: 'Are you sure?',
25 | text: "You won't be able to revert this!",
26 | icon: 'warning',
27 | showCancelButton: true,
28 | confirmButtonColor: '#3085d6',
29 | cancelButtonColor: '#d33',
30 | confirmButtonText: 'Yes, delete it!'
31 | }).then((result) => {
32 | if (result.isConfirmed) {
33 | const sendReq = async () => {
34 | const req = await fetch(`.././src/library/employeeController.php`, {
35 | method: 'DELETE',
36 | body: JSON.stringify(+btnId)
37 | });
38 | const res = await req.json()
39 | }
40 | sendReq();
41 | clearRow(e);
42 | Swal.fire(
43 | 'Deleted!',
44 | 'Your file has been deleted.',
45 | 'success'
46 | )
47 |
48 |
49 | }
50 | })
51 |
52 | }
53 |
54 | // Toggeling add button
55 | const addEmpFormHandler = () => {
56 |
57 | const addEmployeeForm = document.getElementById('addEmployeeForm');
58 | addEmployeeForm.classList.toggle('toggle');
59 |
60 | if (addEmployeeForm.classList == 'toggle') {
61 | addNewEmpBtnEl.textContent = '+'
62 | addNewEmpBtnEl.style.background = "green";
63 | } else {
64 | addNewEmpBtnEl.textContent = 'x';
65 | addNewEmpBtnEl.style.background = "#F55353";
66 | }
67 |
68 | }
69 | const createNewEmp = async (e) => {
70 | e.preventDefault();
71 | const validation = await validateForm();
72 | const newEmp = getEmpFormValues();
73 | if(!validation){
74 | Swal.fire({
75 | icon: 'error',
76 | title: 'Oops...',
77 | text: 'Please verify all details are correct and that your email does not exsit already',
78 | })
79 | }else{
80 | const req = await fetch(`.././src/library/employeeController.php`, {
81 | method: 'POST',
82 | body: JSON.stringify(newEmp),
83 | headers: {
84 | 'Content-Type': 'application/json'
85 | }
86 | });
87 | clearTable()
88 | clearForm();
89 | Swal.fire(
90 | 'Success!',
91 | 'Employee was added correctly',
92 | 'success'
93 | )
94 | showEmp();
95 | }
96 | }
97 |
98 | function createTableRowWihtEmp(id, name, email, age, streetAddress, city, state, postalCode, phoneNumber) {
99 | const trEl = document.createElement('tr')
100 |
101 | const nameData = document.createElement('td');
102 | nameData.textContent = name;
103 |
104 | const emailData = document.createElement('td');
105 | emailData.textContent = email;
106 |
107 | const ageData = document.createElement('td');
108 | ageData.textContent = age;
109 |
110 | const street_nData = document.createElement('td');
111 | street_nData.textContent = streetAddress;
112 |
113 | const cityData = document.createElement('td');
114 | cityData.textContent = city;
115 |
116 | const stateData = document.createElement('td');
117 | stateData.textContent = state;
118 |
119 | const postalData = document.createElement('td');
120 | postalData.textContent = postalCode;
121 |
122 |
123 | const phoneData = document.createElement('td');
124 | phoneData.textContent = phoneNumber;
125 |
126 |
127 | const deleteBtnEl = document.createElement('td');
128 | const btn = document.createElement('button');
129 | btn.setAttribute('data', id)
130 | btn.setAttribute('class', 'delete__Button')
131 |
132 | deleteBtnEl.appendChild(btn);
133 |
134 | const editBtnEl = document.createElement('td');
135 | const editBtn = document.createElement('a')
136 | const iconEditEl = document.createElement('i');
137 | editBtn.setAttribute('href', `.././src/library/employeeController.php?id=${id}`)
138 | editBtn.setAttribute('class', 'edit__button')
139 | iconEditEl.setAttribute('class', 'fa-solid fa-pen-to-square')
140 |
141 | editBtn.append(iconEditEl)
142 | editBtnEl.appendChild(editBtn);
143 |
144 |
145 | trEl.appendChild(nameData);
146 | trEl.appendChild(emailData);
147 | trEl.appendChild(ageData);
148 | trEl.appendChild(street_nData);
149 | trEl.appendChild(cityData);
150 | trEl.appendChild(stateData);
151 | trEl.appendChild(postalData);
152 | trEl.appendChild(phoneData);
153 | trEl.appendChild(deleteBtnEl);
154 | trEl.appendChild(editBtnEl);
155 |
156 |
157 | return trEl;
158 | }
159 |
160 |
161 | const showEmp = async () => {
162 | const emps = await getEmps();
163 |
164 | emps.map(emp => {
165 | const { id, name, email, age, streetAddress, city, state, postalCode, phoneNumber, gender, lastName } = emp;
166 | const empRow = createTableRowWihtEmp(id, name, email, age, streetAddress, city, state, postalCode, phoneNumber, gender, lastName);
167 | tableBodyEl.appendChild(empRow);
168 | })
169 | const btnsdelete = document.querySelectorAll('[data]')
170 | btnsdelete.forEach(btn => btn.addEventListener('click', deleteEmpId));
171 |
172 | }
173 |
174 | const clearForm = () => {
175 | const newEmpFormEl = document.getElementById('addEmployeeForm');
176 | Array.from(newEmpFormEl.children).map(el => {
177 | Array.from(el.children).forEach(el => el.value = '')
178 | })
179 | newEmpFormEl.classList.toggle('toggle');
180 | addNewEmpBtnEl.textContent = '+';
181 | }
182 |
183 |
184 | const clearRow = (e) => {
185 |
186 | if (table.hasChildNodes()) {
187 | tableBodyEl.removeChild(e.target.parentElement.parentElement)
188 | }
189 | }
190 |
191 | const clearTable = () => {
192 | Array.from(tableBodyEl.children).map(el => {
193 | if(!el.hasAttribute('id')) {
194 | tableBodyEl.removeChild(el)
195 | }
196 | })
197 | }
198 |
199 |
200 | const getEmpFormValues = () => {
201 |
202 | const id = document.getElementById('id').value = '';
203 | const name = document.getElementById('name').value;
204 | const lastName = document.getElementById('lastName').value = '';
205 | const gender = document.getElementById('gender').value = '';
206 | const email = document.getElementById('email').value;
207 | const age = document.getElementById('age').value;
208 | const streetAddress = document.getElementById('streetAddress').value;
209 | const city = document.getElementById('city').value;
210 | const state = document.getElementById('state').value;
211 | const postalCode = document.getElementById('postalCode').value;
212 | const phoneNumber = document.getElementById('phoneNumber').value;
213 |
214 | const data = {
215 | id, name, lastName, email, age, gender, streetAddress, city, state, postalCode, phoneNumber
216 | }
217 |
218 | return data;
219 | }
220 |
221 | // Validation helpers
222 |
223 | const validateForm = async () => {
224 | const validationArr = new Array()
225 |
226 | const name = empFormInputs[0]
227 | const email = empFormInputs[1]
228 | const age = empFormInputs[2]
229 | const streetAddress = empFormInputs[3]
230 | const city = empFormInputs[4]
231 | const state = empFormInputs[5]
232 | const postalCode = empFormInputs[6]
233 | const phoneNumber = empFormInputs[7]
234 |
235 | const regex = {
236 | emailReg: /^\w+([\.-\_]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, //checking for correct address
237 | firstNameReg: /^[a-zA-ZÀ-ÿ\s]{1,20}$/, // not allwoing numbers
238 | ageReg: /^(1[89]|[2-9]\d)$/, // age from 18 - 99
239 | phoneNumberReg: /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/, // allowing coutnry code and (-)
240 | addressReg: /[A-Za-z0-9'\.\-\s\,]/, // eliminates symbols which are not part of an address
241 | cityReg: /^[a-zA-Z\u0080-\u024F\s\/\-\)\(\`\.\"\']+$/, // allowing cities with special carachters
242 | stateReg: /^[a-zA-Z\u0080-\u024F\s\/\-\)\(\`\.\"\']+$/, // allowing states with special carachters
243 | }
244 |
245 | const { emailReg, firstNameReg, ageReg, addressReg, cityReg, stateReg, phoneNumberReg } = regex;
246 | if(firstNameReg.test(name.value)){
247 | validationArr.push(true)
248 | }
249 | if(emailReg.test(email.value)){
250 | const isEmailDuplicated = await checkEmail(email.value)
251 | if(isEmailDuplicated) {
252 | validationArr.push(true)
253 | }
254 |
255 | }
256 | if(ageReg.test(age.value)) {
257 | validationArr.push(true)
258 | }
259 | if(addressReg.test(streetAddress.value)) {
260 | validationArr.push(true)
261 | }
262 | if(cityReg.test(city.value)) {
263 | validationArr.push(true)
264 | }
265 | if(stateReg.test(state.value)) {
266 | validationArr.push(true)
267 | }
268 | if(phoneNumberReg.test(phoneNumber.value)) {
269 | validationArr.push(true)
270 | }
271 | if(postalCode.value.length != 0) {
272 | validationArr.push(true)
273 | }
274 |
275 | return validationArr.length == 8 ? true : false;
276 | }
277 |
278 | const checkEmail = async (email) => {
279 | let isEmailOK = false;
280 | const emps = await getEmps();
281 | emps.forEach(emp => {
282 | const {email: dbEmail} = emp
283 | const comparedEmail = email.trim()
284 | if(dbEmail === comparedEmail) {
285 | isEmailOK = false
286 | } else {
287 | isEmailOK = true
288 | }
289 | })
290 | return isEmailOK;
291 | }
292 |
293 |
294 |
295 | // events
296 |
297 |
298 |
299 | addNewEmpBtnEl.addEventListener('click', addEmpFormHandler);
300 |
301 | createEmpButton.addEventListener('click', createNewEmp)
302 |
303 |
304 |
305 | // on load
306 | showEmp();
307 |
308 |
309 |
310 |
311 |
312 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
Name | 53 |Age | 55 |Street No | 56 |City | 57 |State | 58 |Postal Code | 59 |Phone Number | 60 |61 | 62 | | 63 ||
---|---|---|---|---|---|---|---|---|