├── .gitignore
├── README.md
├── package.json
├── public
└── index.html
├── src
├── App.css
├── App.js
├── assets
│ ├── images
│ │ └── react_logo.png
│ └── styles
│ │ └── styles.scss
├── components
│ ├── AddStudent.js
│ ├── Header.js
│ ├── Student.js
│ └── Students.js
├── data
│ └── students.js
├── index.css
├── index.js
├── res.js
└── utils
│ └── random-id.js
└── yarn.lock
/.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 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React App
2 |
3 | yarn start
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client_boiler_plate",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "axios": "^0.19.2",
10 | "bootstrap": "^4.4.1",
11 | "moment": "^2.24.0",
12 | "node-sass": "^4.13.1",
13 | "react": "^16.12.0",
14 | "react-dom": "^16.12.0",
15 | "react-moment": "^0.9.7",
16 | "react-redux": "^7.2.0",
17 | "react-router-dom": "^5.1.2",
18 | "react-scripts": "3.4.0",
19 | "react-strap": "^0.0.1",
20 | "redux": "^4.0.5"
21 | },
22 | "scripts": {
23 | "start": "react-scripts start",
24 | "build": "react-scripts build",
25 | "test": "react-scripts test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": "react-app"
30 | },
31 | "proxy": "http://localhost:5000",
32 | "browserslist": {
33 | "production": [
34 | ">0.2%",
35 | "not dead",
36 | "not op_mini all"
37 | ],
38 | "development": [
39 | "last 1 chrome version",
40 | "last 1 firefox version",
41 | "last 1 safari version"
42 | ]
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 | React App
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .students {
2 | display: flex;
3 | flex-wrap: wrap;
4 | justify-content: space-around;
5 | }
6 |
7 | .students>div {
8 | width: 25%;
9 | }
10 |
11 | img {
12 | width: 25%;
13 | }
14 |
15 | .container {
16 | border: solid 10px purple;
17 | }
18 |
19 | .students {
20 | border: 5px solid blue;
21 | }
22 |
23 | .student {
24 | border: 2px solid green;
25 | }
26 |
27 | .add {
28 | border: 2px solid red;
29 | }
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { students } from './data/students'
3 | import Students from './components/Students'
4 | import AddStudent from './components/AddStudent'
5 | import './App.css'
6 |
7 | class App extends Component {
8 | state = {
9 | student: {
10 | firstName: '',
11 | lastName: '',
12 | country: '',
13 | email: '',
14 | avatar:
15 | 'https://secure.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=400&d=mm&r=g'
16 | },
17 | students: students
18 | }
19 | handleChange = e => {
20 | // let name = e.target.name
21 | // let value = e.target.value
22 | // destructuring name, value from input element or target
23 | const { name, value } = e.target
24 | // setting the value of the input to the state
25 | const student = {
26 | ...this.state.student,
27 | [name]: value,
28 | id: this.state.students.length + 1
29 | }
30 | this.setState({ student })
31 | }
32 | handleSubmit = e => {
33 | // it prevents the default behavior of the form element
34 | e.preventDefault()
35 | this.setState({ students: [...this.state.students, this.state.student] })
36 | }
37 |
38 | deleteStudent = id => {
39 | const students = this.state.students.filter(student => id !== student.id)
40 | this.setState({ students: students })
41 | }
42 |
43 | render() {
44 | // const { firstName, lastName, country, email, avatar } = this.state.student
45 | return (
46 |
47 |
Number of students: {this.state.students.length}
48 |
53 |
54 |
55 |
56 | {/*
*/}
64 |
65 | )
66 | }
67 | }
68 |
69 | export default App
70 |
--------------------------------------------------------------------------------
/src/assets/images/react_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Asabeneh/react-students/9a7a9ee83bafc8d570c44299b140eb494d993940/src/assets/images/react_logo.png
--------------------------------------------------------------------------------
/src/assets/styles/styles.scss:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin:0;
4 | box-sizing:border-box;
5 | }
6 | h1 {
7 | /*
8 | color:#61dbfb;
9 | */
10 | }
--------------------------------------------------------------------------------
/src/components/AddStudent.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 |
4 | const AddStudent = props => {
5 | const { firstName, lastName, country, email, avatar } = props.data
6 | const { onChange, onSubmit } = props
7 | return (
8 |
9 |
Add Student
10 |
42 |
43 | )
44 | }
45 |
46 | export default AddStudent
47 |
--------------------------------------------------------------------------------
/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 |
4 | const Header = props => {
5 | return (
6 |
7 | Getting Started React
8 |
9 | )
10 | }
11 |
12 | Header.propTypes = {}
13 |
14 | export default Header
15 |
--------------------------------------------------------------------------------
/src/components/Student.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 |
4 | const Student = props => {
5 | return (
6 |
7 |
8 | {props.student.firstName} {props.student.lastName}
9 |
10 |
{props.student.country}
11 |
12 |
Title{props.student.title}
13 |
{props.student.email}
14 |
Phone: {props.student.phone}
15 |

16 |
17 |
18 |
19 | )
20 | }
21 |
22 | Student.propTypes = {}
23 |
24 | export default Student
25 |
--------------------------------------------------------------------------------
/src/components/Students.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Student from './Student'
3 | import PropTypes from 'prop-types'
4 |
5 | const Students = props => {
6 | const studentList = props.students.map(student => (
7 |
8 | ))
9 | return {studentList}
10 | }
11 |
12 | Students.propTypes = {}
13 |
14 | export default Students
15 |
--------------------------------------------------------------------------------
/src/data/students.js:
--------------------------------------------------------------------------------
1 |
2 | export const students = [
3 | {
4 | id: 'FUZ2tN',
5 | firstName: 'Travis',
6 | lastName: 'Anderson',
7 | title: 'Customer Implementation Technician',
8 | jobTitle: 'Direct Branding Engineer',
9 | avatar:
10 | 'https://s3.amazonaws.com/uifaces/faces/twitter/mauriolg/128.jpg',
11 | age: 40,
12 | country: 'Bouvet Island (Bouvetoya)',
13 | email: 'travis.anderson@cfeo.io',
14 | phone: '116-870-7400'
15 | },
16 | {
17 | id: 'dzkra2',
18 | firstName: 'Dewitt',
19 | lastName: 'Schmeler',
20 | title: 'Forward Accountability Officer',
21 | jobTitle: 'Dynamic Brand Officer',
22 | avatar:
23 | 'https://s3.amazonaws.com/uifaces/faces/twitter/donjain/128.jpg',
24 | age: 76,
25 | country: 'Mauritius',
26 | email: 'dewitt.schmeler@cfeo.io',
27 | phone: '697-834-2957'
28 | },
29 | {
30 | id: 'EnwPVl',
31 | firstName: 'Robyn',
32 | lastName: 'Koelpin',
33 | title: 'Product Data Orchestrator',
34 | jobTitle: 'District Infrastructure Assistant',
35 | avatar:
36 | 'https://s3.amazonaws.com/uifaces/faces/twitter/jayphen/128.jpg',
37 | age: 71,
38 | country: 'Montenegro',
39 | email: 'robyn.koelpin@cfeo.io',
40 | phone: '057-303-4551'
41 | },
42 | {
43 | id: '7UNLC8',
44 | firstName: 'Aidan',
45 | lastName: 'Cole',
46 | title: 'Regional Infrastructure Engineer',
47 | jobTitle: 'Forward Applications Associate',
48 | avatar:
49 | 'https://s3.amazonaws.com/uifaces/faces/twitter/justinrgraham/128.jpg',
50 | age: 67,
51 | country: 'Japan',
52 | email: 'aidan.cole@cfeo.io',
53 | phone: '499-663-4136'
54 | },
55 | {
56 | id: '3uaY51',
57 | firstName: 'Lavinia',
58 | lastName: 'Rowe',
59 | title: 'Global Directives Producer',
60 | jobTitle: 'Direct Identity Orchestrator',
61 | avatar:
62 | 'https://s3.amazonaws.com/uifaces/faces/twitter/mattlat/128.jpg',
63 | age: 27,
64 | country: 'Pakistan',
65 | email: 'lavinia.rowe@cfeo.io',
66 | phone: '400-908-3733'
67 | },
68 | {
69 | id: 'YcCMbc',
70 | firstName: 'Erling',
71 | lastName: 'Mitchell',
72 | title: 'Lead Marketing Producer',
73 | jobTitle: 'Customer Communications Facilitator',
74 | avatar:
75 | 'https://s3.amazonaws.com/uifaces/faces/twitter/madebybrenton/128.jpg',
76 | age: 45,
77 | country: 'Cambodia',
78 | email: 'erling.mitchell@cfeo.io',
79 | phone: '243-036-6107'
80 | },
81 | {
82 | id: 'lH2C29',
83 | firstName: 'Jorge',
84 | lastName: 'Pagac',
85 | title: 'International Creative Supervisor',
86 | jobTitle: 'Corporate Response Coordinator',
87 | avatar:
88 | 'https://s3.amazonaws.com/uifaces/faces/twitter/zforrester/128.jpg',
89 | age: 87,
90 | country: 'Tonga',
91 | email: 'jorge.pagac@cfeo.io',
92 | phone: '326-724-9325'
93 | },
94 | {
95 | id: 'dRXzo7',
96 | firstName: 'Carroll',
97 | lastName: 'Hills',
98 | title: 'Internal Marketing Officer',
99 | jobTitle: 'Internal Communications Representative',
100 | avatar:
101 | 'https://s3.amazonaws.com/uifaces/faces/twitter/to_soham/128.jpg',
102 | age: 22,
103 | country: 'Comoros',
104 | email: 'carroll.hills@cfeo.io',
105 | phone: '945-685-2040'
106 | },
107 | {
108 | id: 'nuHIut',
109 | firstName: 'Leon',
110 | lastName: 'Lueilwitz',
111 | title: 'Lead Group Manager',
112 | jobTitle: 'Senior Assurance Developer',
113 | avatar:
114 | 'https://s3.amazonaws.com/uifaces/faces/twitter/RussellBishop/128.jpg',
115 | age: 30,
116 | country: 'Japan',
117 | email: 'leon.lueilwitz@cfeo.io',
118 | phone: '587-102-3681'
119 | },
120 | {
121 | id: 'FtOsN8',
122 | firstName: 'Skylar',
123 | lastName: 'Moore',
124 | title: 'Global Branding Officer',
125 | jobTitle: 'Legacy Assurance Designer',
126 | avatar:
127 | 'https://s3.amazonaws.com/uifaces/faces/twitter/andrewofficer/128.jpg',
128 | age: 72,
129 | country: 'Bulgaria',
130 | email: 'skylar.moore@cfeo.io',
131 | phone: '294-134-1336'
132 | }
133 | ]
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto';
4 | }
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import './index.css'
4 | import App from './App'
5 |
6 | ReactDOM.render(, document.getElementById('root'))
7 |
--------------------------------------------------------------------------------
/src/res.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { randomId, showDateTime } from './utils/random-id.js'
3 | import { students } from './data/students'
4 | import './assets/styles/styles.scss'
5 | import './App.css'
6 |
7 |
8 | console.log(showDateTime())
9 |
10 | class App extends Component {
11 | state = {
12 | student: {
13 | firstName: '',
14 | lastName: '',
15 | country: '',
16 | email: '',
17 | avatar:
18 | 'https://secure.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=400&d=mm&r=g'
19 | },
20 |
21 | students: students
22 | }
23 |
24 | handleChange = e => {
25 | // let name = e.target.name
26 | // let value = e.target.value
27 | // destructuring name, value from input element or target
28 | const { name, value } = e.target
29 | // setting the value of the input to the state
30 |
31 | const student = {
32 | ...this.state.student,
33 | [name]: value,
34 | id: randomId()
35 | }
36 |
37 | this.setState({ student })
38 | }
39 | handleSubmit = e => {
40 | // it prevents the default behavior of the form element
41 | e.preventDefault()
42 |
43 | this.setState({ students: [...this.state.students, this.state.student] })
44 | }
45 |
46 | deleteStudent = id => {
47 | const students = this.state.students.filter(student => id !== student.id)
48 | this.setState({ students: students })
49 | }
50 |
51 | render() {
52 | const { students } = this.state
53 | console.log(students)
54 |
55 | const { firstName, lastName, country, email, avatar } = this.state.student
56 | console.log(students)
57 | return (
58 |
59 | {studentsList}
60 |
61 | )
62 | }
63 | }
64 |
65 | export default App
66 |
--------------------------------------------------------------------------------
/src/utils/random-id.js:
--------------------------------------------------------------------------------
1 | export const randomId = (n = 6) => {
2 | const lettersAndNums =
3 | '0123456ABCDEFGHIJKLMNOPKRSTUVWXYZabcdefghihjklmnopqrstuvwxyz'
4 | let id = ''
5 | for (let i = 0; i < n; i++) {
6 | let index = Math.floor(Math.random() * lettersAndNums.length)
7 | id = id + lettersAndNums[index]
8 | }
9 | return id
10 | }
11 |
12 | export const showDateTime = () => {
13 | const months = [
14 | 'January',
15 | 'February',
16 | 'March',
17 | 'April',
18 | 'May',
19 | 'June',
20 | 'July',
21 | 'August',
22 | 'September',
23 | 'October',
24 | 'November',
25 | 'December'
26 | ]
27 | const now = new Date()
28 | const year = now.getFullYear()
29 | const month = months[now.getMonth()]
30 | const date = now.getDate()
31 | let hours = now.getHours()
32 | let minutes = now.getMinutes()
33 | let seconds = now.getSeconds()
34 | if (hours < 10) {
35 | hours = '0' + hours
36 | }
37 | if (minutes < 10) {
38 | minutes = '0' + minutes
39 | }
40 | if (seconds < 10) {
41 | seconds = '0' + seconds
42 | }
43 |
44 | const dateMonthYear = `${month} ${date}, ${year}`
45 |
46 | const time = hours + ':' + minutes
47 | const fullTime = dateMonthYear + ' ' + time
48 | return fullTime + `:${seconds}`
49 | }
50 |
--------------------------------------------------------------------------------