From 0c631e12e10b084a0af6d04a572ccfb4700858f8 Mon Sep 17 00:00:00 2001 From: Tom Victor Date: Tue, 20 Feb 2024 15:22:18 +0100 Subject: [PATCH 1/7] add skills pages --- frontend/package-lock.json | 98 +++++++++++++++++++ frontend/package.json | 4 + frontend/src/App.js | 39 -------- frontend/src/components/createSkill.jsx | 33 +++++++ .../{createUser.js => createUser.jsx} | 28 +++--- frontend/src/components/navbar.js | 38 ------- frontend/src/components/navbar.jsx | 34 +++++++ frontend/src/components/skill.jsx | 8 ++ frontend/src/components/skillList.jsx | 47 +++++++++ frontend/src/components/user.js | 15 --- frontend/src/components/user.jsx | 15 +++ frontend/src/components/userList.jsx | 49 ++++++++++ frontend/src/components/userlist.js | 49 ---------- frontend/src/index.js | 40 +++++++- frontend/src/routes/error-pages.jsx | 42 ++++++++ frontend/src/routes/home.jsx | 50 ++++++++++ frontend/src/routes/login.jsx | 11 +++ frontend/src/routes/skills.jsx | 46 +++++++++ frontend/src/routes/users.jsx | 46 +++++++++ 19 files changed, 535 insertions(+), 157 deletions(-) delete mode 100644 frontend/src/App.js create mode 100644 frontend/src/components/createSkill.jsx rename frontend/src/components/{createUser.js => createUser.jsx} (74%) delete mode 100644 frontend/src/components/navbar.js create mode 100644 frontend/src/components/navbar.jsx create mode 100644 frontend/src/components/skill.jsx create mode 100644 frontend/src/components/skillList.jsx delete mode 100644 frontend/src/components/user.js create mode 100644 frontend/src/components/user.jsx create mode 100644 frontend/src/components/userList.jsx delete mode 100644 frontend/src/components/userlist.js create mode 100644 frontend/src/routes/error-pages.jsx create mode 100644 frontend/src/routes/home.jsx create mode 100644 frontend/src/routes/login.jsx create mode 100644 frontend/src/routes/skills.jsx create mode 100644 frontend/src/routes/users.jsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 986ab4e..fab191b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "skillmap", "version": "0.1.0", "dependencies": { + "@floating-ui/react": "^0.26.9", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -16,6 +17,9 @@ "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "react-router-dom": "^6.22.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -2377,6 +2381,54 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.9.tgz", + "integrity": "sha512-p86wynZJVEkEq2BBjY/8p2g3biQ6TlgT4o/3KgFKyTWoJLU1GZ8wpctwRqtkEl2tseYA+kw7dBAIDFcednfI5w==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.8", + "@floating-ui/utils": "^0.2.1", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -3363,6 +3415,15 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@remix-run/router": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz", + "integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -14987,6 +15048,38 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz", + "integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==", + "dev": true, + "dependencies": { + "@remix-run/router": "1.15.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz", + "integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==", + "dev": true, + "dependencies": { + "@remix-run/router": "1.15.1", + "react-router": "6.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -16601,6 +16694,11 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/tailwindcss": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index ff50a94..6706ae8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@floating-ui/react": "^0.26.9", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -35,5 +36,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "react-router-dom": "^6.22.1" } } diff --git a/frontend/src/App.js b/frontend/src/App.js deleted file mode 100644 index 34f4a73..0000000 --- a/frontend/src/App.js +++ /dev/null @@ -1,39 +0,0 @@ -import './App.css'; -import UserList from './components/userlist'; -import Navbar from './components/navbar'; -import CreateUser from './components/createUser'; - -function App() { - return ( - -
- -
-
- -
-
- -
- -
-
- -
-
- -
- -
-
- -
-
- -
- -
- ); -} - -export default App; diff --git a/frontend/src/components/createSkill.jsx b/frontend/src/components/createSkill.jsx new file mode 100644 index 0000000..2cba863 --- /dev/null +++ b/frontend/src/components/createSkill.jsx @@ -0,0 +1,33 @@ +export default function CreateSkill() { + function onSubmission(event) { + event.preventDefault(); + + var skillName = event.target.elements.skillName.value; + console.log(skillName); + + fetch("http://localhost:8080/api/skills", { + method: "POST", + body: JSON.stringify({ + "skillName": skillName, + }), + }) + .then(response => response.json()) + .then(data => { + console.log(data); + alert(JSON.stringify(data)); + }) + } + return ( +
+

Create Skill

+
+
+
+ + +
+ +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/components/createUser.js b/frontend/src/components/createUser.jsx similarity index 74% rename from frontend/src/components/createUser.js rename to frontend/src/components/createUser.jsx index 2addc12..fd50d71 100644 --- a/frontend/src/components/createUser.js +++ b/frontend/src/components/createUser.jsx @@ -1,5 +1,5 @@ export default function CreateUser() { - function onSubmission(event){ + function onSubmission(event) { event.preventDefault(); var fullName = event.target.elements.fullName.value; @@ -10,34 +10,34 @@ export default function CreateUser() { fetch("http://localhost:8080/api/users", { method: "POST", body: JSON.stringify({ - "fullName":fullName, - "email":email, + "fullName": fullName, + "email": email, }), // headers: { // "Content-type": "application/json; charset=UTF-8", // }, }) - .then(response => response.json()) - .then(data => { - console.log(data); - alert(JSON.stringify(data)); - }) + .then(response => response.json()) + .then(data => { + console.log(data); + alert(JSON.stringify(data)); + }) } return ( -
-

Create User

-
+
+

Create User

+
- +
- +
); - } \ No newline at end of file +} \ No newline at end of file diff --git a/frontend/src/components/navbar.js b/frontend/src/components/navbar.js deleted file mode 100644 index 5d1e045..0000000 --- a/frontend/src/components/navbar.js +++ /dev/null @@ -1,38 +0,0 @@ -export default function Navbar(){ - return ( - -); -} \ No newline at end of file diff --git a/frontend/src/components/navbar.jsx b/frontend/src/components/navbar.jsx new file mode 100644 index 0000000..ab7d865 --- /dev/null +++ b/frontend/src/components/navbar.jsx @@ -0,0 +1,34 @@ +export default function Navbar() { + return ( + + ); +} \ No newline at end of file diff --git a/frontend/src/components/skill.jsx b/frontend/src/components/skill.jsx new file mode 100644 index 0000000..5ccb5a2 --- /dev/null +++ b/frontend/src/components/skill.jsx @@ -0,0 +1,8 @@ +export default function Skill({ id, name }) { + return ( + + {id} + {name} + + ); +} \ No newline at end of file diff --git a/frontend/src/components/skillList.jsx b/frontend/src/components/skillList.jsx new file mode 100644 index 0000000..552cb60 --- /dev/null +++ b/frontend/src/components/skillList.jsx @@ -0,0 +1,47 @@ +import React, { useState, useEffect } from 'react'; +import Skill from "./skill"; + +export default function SkillList() { + + const [data, setData] = useState([]); + + function reloadUserList(event) { + console.log(event); + fetch("http://localhost:8080/api/users", { + method: "GET", + }) + .then(response => response.json()) + .then(data => { + console.log(data); + setData(data); + // alert(JSON.stringify(data)); + }) + }; + + return ( +
+
+

Skill List

+
+ +
+ + + + + + + + + { + data.map((item) => ( + + )) + } + +
#IDName
+
+ + + ); +} \ No newline at end of file diff --git a/frontend/src/components/user.js b/frontend/src/components/user.js deleted file mode 100644 index dd39b4e..0000000 --- a/frontend/src/components/user.js +++ /dev/null @@ -1,15 +0,0 @@ -export default function User({id,fullName,email}) { - return ( - - {id} - {fullName} - {email} - - Go - Python - Rust - C - - - ); -} \ No newline at end of file diff --git a/frontend/src/components/user.jsx b/frontend/src/components/user.jsx new file mode 100644 index 0000000..02a08e7 --- /dev/null +++ b/frontend/src/components/user.jsx @@ -0,0 +1,15 @@ +export default function User({ id, fullName, email }) { + return ( + + {id} + {fullName} + {email} + + Go + Python + Rust + C + + + ); +} \ No newline at end of file diff --git a/frontend/src/components/userList.jsx b/frontend/src/components/userList.jsx new file mode 100644 index 0000000..39f5335 --- /dev/null +++ b/frontend/src/components/userList.jsx @@ -0,0 +1,49 @@ +import React, { useState, useEffect } from 'react'; +import User from "./user"; + +export default function UserList() { + + const [data, setData] = useState([]); + + function reloadUserList(event) { + console.log(event); + fetch("http://localhost:8080/api/users", { + method: "GET", + }) + .then(response => response.json()) + .then(data => { + console.log(data); + setData(data); + // alert(JSON.stringify(data)); + }) + }; + + return ( +
+
+

User List

+
+ +
+ + + + + + + + + + + { + data.map((item) => ( + + )) + } + +
#IDFull NameEmailSkills
+
+ + + ); +} \ No newline at end of file diff --git a/frontend/src/components/userlist.js b/frontend/src/components/userlist.js deleted file mode 100644 index cf7b55d..0000000 --- a/frontend/src/components/userlist.js +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import User from "./user"; - -export default function UserList() { - - const [data, setData] = useState([]); - - function reloadUserList(event){ - console.log(event); - fetch("http://localhost:8080/api/users", { - method: "GET", - }) - .then(response => response.json()) - .then(data => { - console.log(data); - setData(data); - // alert(JSON.stringify(data)); - }) - }; - - return ( -
-
-

User List

-
- -
- - - - - - - - - - - { - data.map((item)=>( - - )) - } - -
#IDFull NameEmailSkills
-
- - - ); - } \ No newline at end of file diff --git a/frontend/src/index.js b/frontend/src/index.js index 4e78e7c..4243e23 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -2,13 +2,49 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import 'bootstrap/dist/css/bootstrap.css'; -import App from './App'; +import '@floating-ui/react'; +import Home from './routes/home'; +import UserLogin from './routes/login'; import reportWebVitals from './reportWebVitals'; +import ErrorPage from "./routes/error-pages"; +import UserPage from './routes/users'; + +import { + createBrowserRouter, + RouterProvider, +} from "react-router-dom"; +import SkillPage from './routes/skills'; + + +const router = createBrowserRouter([ + + { + path: "/", + element: , + errorElement: , + }, + { + path: "/users", + element: , + errorElement: , + }, + { + path: "/skills", + element: , + errorElement: , + }, + { + path: "/login", + element: , + errorElement: , + }, +]); + const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + ); diff --git a/frontend/src/routes/error-pages.jsx b/frontend/src/routes/error-pages.jsx new file mode 100644 index 0000000..2832a62 --- /dev/null +++ b/frontend/src/routes/error-pages.jsx @@ -0,0 +1,42 @@ +import { useRouteError } from "react-router-dom"; +import Navbar from '../components/navbar'; + +export default function ErrorPage() { + const error = useRouteError(); + console.error(error); + + return ( + + +
+ +
+
+ +
+
+ +
+ + + +
+ + +

Oops!

+

Sorry, an unexpected error has occurred.

+

+ {error.statusText || error.message} +

+ + + +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/routes/home.jsx b/frontend/src/routes/home.jsx new file mode 100644 index 0000000..5728906 --- /dev/null +++ b/frontend/src/routes/home.jsx @@ -0,0 +1,50 @@ +import Navbar from '../components/navbar'; + +function Home() { + return ( + +
+ +
+
+ +
+
+ +
+ + + + +
+
+ +
+
+
+
+
50 Total Registered Users
+

Go to the User page for managing skills

+ Manage users +
+
+
+
+
+
+
10 Total Skills
+

go to the skills page for managing skills

+ Manage Skills +
+
+
+
+
+ ); +} + +export default Home; diff --git a/frontend/src/routes/login.jsx b/frontend/src/routes/login.jsx new file mode 100644 index 0000000..4edf032 --- /dev/null +++ b/frontend/src/routes/login.jsx @@ -0,0 +1,11 @@ + +function UserLogin() { + return ( + +
+

Login

+
+ ); +} + +export default UserLogin; diff --git a/frontend/src/routes/skills.jsx b/frontend/src/routes/skills.jsx new file mode 100644 index 0000000..e0d151b --- /dev/null +++ b/frontend/src/routes/skills.jsx @@ -0,0 +1,46 @@ +import Navbar from '../components/navbar'; +import SkillList from '../components/skillList'; +import CreateSkill from '../components/createSkill'; + +function SkillPage() { + return ( + +
+ +
+
+ +
+
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+ ); +} + +export default SkillPage; diff --git a/frontend/src/routes/users.jsx b/frontend/src/routes/users.jsx new file mode 100644 index 0000000..82b11b8 --- /dev/null +++ b/frontend/src/routes/users.jsx @@ -0,0 +1,46 @@ +import UserList from '../components/userList'; +import Navbar from '../components/navbar'; +import CreateUser from '../components/createUser'; + +function UserPage() { + return ( + +
+ +
+
+ +
+
+ +
+ + + +
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+ ); +} + +export default UserPage; From 1b919da15477a06d036af49f44e7b4ad6811781a Mon Sep 17 00:00:00 2001 From: Tom Victor Date: Tue, 20 Feb 2024 15:32:17 +0100 Subject: [PATCH 2/7] add detail views --- frontend/src/App.css | 38 ---------------- .../{createSkill.jsx => skillCreate.jsx} | 0 .../{createUser.jsx => userCreate.jsx} | 0 frontend/src/components/userDetail.jsx | 43 +++++++++++++++++++ frontend/src/components/userUpdate.jsx | 43 +++++++++++++++++++ frontend/src/index.css | 0 frontend/src/index.js | 8 +++- frontend/src/routes/skills.jsx | 2 +- frontend/src/routes/userDetail.jsx | 39 +++++++++++++++++ frontend/src/routes/userUpdate.jsx | 38 ++++++++++++++++ frontend/src/routes/users.jsx | 2 +- 11 files changed, 172 insertions(+), 41 deletions(-) delete mode 100644 frontend/src/App.css rename frontend/src/components/{createSkill.jsx => skillCreate.jsx} (100%) rename frontend/src/components/{createUser.jsx => userCreate.jsx} (100%) create mode 100644 frontend/src/components/userDetail.jsx create mode 100644 frontend/src/components/userUpdate.jsx delete mode 100644 frontend/src/index.css create mode 100644 frontend/src/routes/userDetail.jsx create mode 100644 frontend/src/routes/userUpdate.jsx diff --git a/frontend/src/App.css b/frontend/src/App.css deleted file mode 100644 index 74b5e05..0000000 --- a/frontend/src/App.css +++ /dev/null @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/frontend/src/components/createSkill.jsx b/frontend/src/components/skillCreate.jsx similarity index 100% rename from frontend/src/components/createSkill.jsx rename to frontend/src/components/skillCreate.jsx diff --git a/frontend/src/components/createUser.jsx b/frontend/src/components/userCreate.jsx similarity index 100% rename from frontend/src/components/createUser.jsx rename to frontend/src/components/userCreate.jsx diff --git a/frontend/src/components/userDetail.jsx b/frontend/src/components/userDetail.jsx new file mode 100644 index 0000000..8493950 --- /dev/null +++ b/frontend/src/components/userDetail.jsx @@ -0,0 +1,43 @@ +export default function UserDetail() { + function onSubmission(event) { + event.preventDefault(); + + var fullName = event.target.elements.fullName.value; + var email = event.target.elements.email.value; + console.log(fullName); + console.log(email); + + fetch("http://localhost:8080/api/users", { + method: "POST", + body: JSON.stringify({ + "fullName": fullName, + "email": email, + }), + // headers: { + // "Content-type": "application/json; charset=UTF-8", + // }, + }) + .then(response => response.json()) + .then(data => { + console.log(data); + alert(JSON.stringify(data)); + }) + } + return ( +
+

User Detail

+
+
+
+ + +
+
+ + +
+ +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/components/userUpdate.jsx b/frontend/src/components/userUpdate.jsx new file mode 100644 index 0000000..a2226a5 --- /dev/null +++ b/frontend/src/components/userUpdate.jsx @@ -0,0 +1,43 @@ +export default function UpdateUser() { + function onSubmission(event) { + event.preventDefault(); + + var fullName = event.target.elements.fullName.value; + var email = event.target.elements.email.value; + console.log(fullName); + console.log(email); + + fetch("http://localhost:8080/api/users", { + method: "POST", + body: JSON.stringify({ + "fullName": fullName, + "email": email, + }), + // headers: { + // "Content-type": "application/json; charset=UTF-8", + // }, + }) + .then(response => response.json()) + .then(data => { + console.log(data); + alert(JSON.stringify(data)); + }) + } + return ( +
+

Update User

+
+
+
+ + +
+
+ + +
+ +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/index.css b/frontend/src/index.css deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/src/index.js b/frontend/src/index.js index 4243e23..9247cbd 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,6 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import './index.css'; import 'bootstrap/dist/css/bootstrap.css'; import '@floating-ui/react'; import Home from './routes/home'; @@ -14,6 +13,7 @@ import { RouterProvider, } from "react-router-dom"; import SkillPage from './routes/skills'; +import UserDetail from './components/userDetail'; const router = createBrowserRouter([ @@ -28,6 +28,12 @@ const router = createBrowserRouter([ element: , errorElement: , }, + + { + path: "/users/:userId", + element: , + errorElement: , + }, { path: "/skills", element: , diff --git a/frontend/src/routes/skills.jsx b/frontend/src/routes/skills.jsx index e0d151b..81b0351 100644 --- a/frontend/src/routes/skills.jsx +++ b/frontend/src/routes/skills.jsx @@ -1,6 +1,6 @@ import Navbar from '../components/navbar'; import SkillList from '../components/skillList'; -import CreateSkill from '../components/createSkill'; +import CreateSkill from '../components/skillCreate'; function SkillPage() { return ( diff --git a/frontend/src/routes/userDetail.jsx b/frontend/src/routes/userDetail.jsx new file mode 100644 index 0000000..9257194 --- /dev/null +++ b/frontend/src/routes/userDetail.jsx @@ -0,0 +1,39 @@ +import UserList from '../components/userList'; +import Navbar from '../components/navbar'; +import UserDetail from '../components/userDetail'; + +function UserPage() { + return ( + +
+ +
+
+ +
+
+ +
+ + + +
+ +
+
+ +
+
+ + +
+
+ ); +} + +export default UserPage; diff --git a/frontend/src/routes/userUpdate.jsx b/frontend/src/routes/userUpdate.jsx new file mode 100644 index 0000000..dec8fd3 --- /dev/null +++ b/frontend/src/routes/userUpdate.jsx @@ -0,0 +1,38 @@ +import Navbar from '../components/navbar'; +import UpdateUser from '../components/userUpdate'; + +function UserPage() { + return ( + +
+ +
+
+ +
+
+ +
+ + + +
+ +
+
+ +
+
+ + +
+
+ ); +} + +export default UserPage; diff --git a/frontend/src/routes/users.jsx b/frontend/src/routes/users.jsx index 82b11b8..d9dd3e8 100644 --- a/frontend/src/routes/users.jsx +++ b/frontend/src/routes/users.jsx @@ -1,6 +1,6 @@ import UserList from '../components/userList'; import Navbar from '../components/navbar'; -import CreateUser from '../components/createUser'; +import CreateUser from '../components/userCreate'; function UserPage() { return ( From da283af7b090f90ec0dc077a1674eae328a14f63 Mon Sep 17 00:00:00 2001 From: Tom Victor Date: Tue, 20 Feb 2024 15:44:59 +0100 Subject: [PATCH 3/7] react effects --- frontend/src/components/userList.jsx | 7 ++++++- frontend/src/index.js | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/userList.jsx b/frontend/src/components/userList.jsx index 39f5335..3165aff 100644 --- a/frontend/src/components/userList.jsx +++ b/frontend/src/components/userList.jsx @@ -6,7 +6,7 @@ export default function UserList() { const [data, setData] = useState([]); function reloadUserList(event) { - console.log(event); + // console.log(event); fetch("http://localhost:8080/api/users", { method: "GET", }) @@ -18,6 +18,11 @@ export default function UserList() { }) }; + useEffect(() => { + console.log("effects"); + reloadUserList(null); + }, []) + return (

diff --git a/frontend/src/index.js b/frontend/src/index.js index 9247cbd..cba034e 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -13,7 +13,7 @@ import { RouterProvider, } from "react-router-dom"; import SkillPage from './routes/skills'; -import UserDetail from './components/userDetail'; +import UserDetail from './routes/userDetail'; const router = createBrowserRouter([ From ebedf75ebea28dbee17a6b53b6ad04baceb4cebd Mon Sep 17 00:00:00 2001 From: Tom Victor Date: Tue, 20 Feb 2024 15:50:44 +0100 Subject: [PATCH 4/7] fix user detail link --- frontend/src/components/user.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/user.jsx b/frontend/src/components/user.jsx index 02a08e7..c61e24d 100644 --- a/frontend/src/components/user.jsx +++ b/frontend/src/components/user.jsx @@ -1,8 +1,16 @@ +import { Link } from 'react-router-dom'; + + export default function User({ id, fullName, email }) { return ( - {id} - {fullName} + + {id} + + + + {fullName} + {email} Go From 51188a88e26ffb9c088e81b760efc725a50a7892 Mon Sep 17 00:00:00 2001 From: Tom Victor Date: Tue, 20 Feb 2024 16:58:29 +0100 Subject: [PATCH 5/7] frontend updates --- frontend/src/components/userCreate.jsx | 2 +- frontend/src/components/userDetail.jsx | 65 ++++++++++++++++++++++---- frontend/src/components/userList.jsx | 2 +- handlers/user.go | 4 +- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/userCreate.jsx b/frontend/src/components/userCreate.jsx index fd50d71..56e6f8e 100644 --- a/frontend/src/components/userCreate.jsx +++ b/frontend/src/components/userCreate.jsx @@ -7,7 +7,7 @@ export default function CreateUser() { console.log(fullName); console.log(email); - fetch("http://localhost:8080/api/users", { + fetch("http://localhost:8080/api/users/", { method: "POST", body: JSON.stringify({ "fullName": fullName, diff --git a/frontend/src/components/userDetail.jsx b/frontend/src/components/userDetail.jsx index 8493950..cd9d119 100644 --- a/frontend/src/components/userDetail.jsx +++ b/frontend/src/components/userDetail.jsx @@ -1,5 +1,15 @@ +import { useParams } from 'react-router-dom'; +import React, { useState, useEffect } from 'react'; + + export default function UserDetail() { - function onSubmission(event) { + const [data, setData] = useState([]); + const { userId } = useParams(); + const usetDetailApi = "http://localhost:8080/api/users/" + userId + "/"; + + console.log("UserDetailApi: ", usetDetailApi); + + function updateUser(event) { event.preventDefault(); var fullName = event.target.elements.fullName.value; @@ -7,14 +17,15 @@ export default function UserDetail() { console.log(fullName); console.log(email); - fetch("http://localhost:8080/api/users", { - method: "POST", + fetch(usetDetailApi, { + method: "PATCH", body: JSON.stringify({ "fullName": fullName, "email": email, }), // headers: { // "Content-type": "application/json; charset=UTF-8", + // "Origin": "localhost" // }, }) .then(response => response.json()) @@ -23,21 +34,59 @@ export default function UserDetail() { alert(JSON.stringify(data)); }) } + + function getUserDetails() { + console.log("get user detail"); + fetch(usetDetailApi, { + method: "GET", + }) + .then(response => response.json()) + .then(data => { + console.log(data); + setData(data); + }) + + } + + function deleteUser(event) { + event.preventDefault(); + console.log("Deleting user..."); + fetch(usetDetailApi, { + method: "DELETE", + }) + .then(response => response.json()) + .then(data => { + console.log(data); + setData(data); + }) + } + + + useEffect(() => { + getUserDetails(); + + }, []) + + return (
-

User Detail

+

User Details : {data.fullName}


-
+
- +
- +
- + + +
+
+
); } \ No newline at end of file diff --git a/frontend/src/components/userList.jsx b/frontend/src/components/userList.jsx index 3165aff..3c41042 100644 --- a/frontend/src/components/userList.jsx +++ b/frontend/src/components/userList.jsx @@ -7,7 +7,7 @@ export default function UserList() { function reloadUserList(event) { // console.log(event); - fetch("http://localhost:8080/api/users", { + fetch("http://localhost:8080/api/users/", { method: "GET", }) .then(response => response.json()) diff --git a/handlers/user.go b/handlers/user.go index c22ef71..287e6db 100644 --- a/handlers/user.go +++ b/handlers/user.go @@ -16,7 +16,7 @@ type UserHandler struct { func NewUserHandlerFrom(userManager managers.UserManager) *UserHandler { return &UserHandler{ - "api/users", + "api/users/", userManager, } } @@ -24,8 +24,8 @@ func NewUserHandlerFrom(userManager managers.UserManager) *UserHandler { func (handler *UserHandler) RegisterUserApis(r *gin.Engine) { userGroup := r.Group(handler.groupName) - userGroup.POST("", handler.Create) userGroup.GET("", handler.List) + userGroup.POST("", handler.Create) userGroup.GET(":userid/", handler.Detail) userGroup.DELETE(":userid/", handler.Delete) userGroup.PATCH(":userid/", handler.Update) From 5457136be798a8bab9b1ef3b970594c44160dec9 Mon Sep 17 00:00:00 2001 From: Tom Victor Date: Tue, 20 Feb 2024 17:25:37 +0100 Subject: [PATCH 6/7] cors issue fixed --- frontend/src/components/userDetail.jsx | 6 +----- frontend/src/index.js | 2 +- go.mod | 5 ++--- go.sum | 10 ++-------- main.go | 2 +- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/userDetail.jsx b/frontend/src/components/userDetail.jsx index cd9d119..ae4a88c 100644 --- a/frontend/src/components/userDetail.jsx +++ b/frontend/src/components/userDetail.jsx @@ -22,11 +22,7 @@ export default function UserDetail() { body: JSON.stringify({ "fullName": fullName, "email": email, - }), - // headers: { - // "Content-type": "application/json; charset=UTF-8", - // "Origin": "localhost" - // }, + }) }) .then(response => response.json()) .then(data => { diff --git a/frontend/src/index.js b/frontend/src/index.js index cba034e..55fcaf8 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -30,7 +30,7 @@ const router = createBrowserRouter([ }, { - path: "/users/:userId", + path: "/users/:userId/", element: , errorElement: , }, diff --git a/go.mod b/go.mod index 196ebff..5c9ff77 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/buildfromzero/skill-map go 1.21.0 require ( + github.com/gin-contrib/cors v1.5.0 github.com/gin-gonic/contrib v0.0.0-20221130124618-7e01895a63f2 github.com/gin-gonic/gin v1.9.1 gorm.io/driver/sqlite v1.5.5 @@ -23,14 +24,13 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect - github.com/kr/pretty v0.3.0 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.1.1 // indirect - github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/arch v0.7.0 // indirect @@ -39,6 +39,5 @@ require ( golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.32.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 011dcb5..e64f887 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= +github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/contrib v0.0.0-20221130124618-7e01895a63f2 h1:dyuNlYlG1faymw39NdJddnzJICy6587tiGSVioWhYoE= @@ -44,12 +46,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= @@ -65,10 +63,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -103,10 +99,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 00a0039..8ba9c0b 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,7 @@ import ( "github.com/buildfromzero/skill-map/handlers" "github.com/buildfromzero/skill-map/managers" "github.com/buildfromzero/skill-map/storage" - "github.com/gin-gonic/contrib/cors" + "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" ) From 1c88b50b57d85161bb68cafe455c686cdc20cfdc Mon Sep 17 00:00:00 2001 From: Tom Victor Date: Tue, 20 Feb 2024 17:49:30 +0100 Subject: [PATCH 7/7] fix minor frontend issues --- frontend/src/components/userDetail.jsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/userDetail.jsx b/frontend/src/components/userDetail.jsx index ae4a88c..7442cfa 100644 --- a/frontend/src/components/userDetail.jsx +++ b/frontend/src/components/userDetail.jsx @@ -36,12 +36,13 @@ export default function UserDetail() { fetch(usetDetailApi, { method: "GET", }) - .then(response => response.json()) + .then(response => { + return response.json(); + }) .then(data => { console.log(data); setData(data); }) - } function deleteUser(event) { @@ -50,10 +51,13 @@ export default function UserDetail() { fetch(usetDetailApi, { method: "DELETE", }) - .then(response => response.json()) + .then(response => { + console.log(response); + return response.json(); + }) .then(data => { console.log(data); - setData(data); + alert(JSON.stringify(data)); }) } @@ -63,7 +67,6 @@ export default function UserDetail() { }, []) - return (

User Details : {data.fullName}