sign up
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
"@tauri-apps/api": "^2.2.0",
|
||||
"@tauri-apps/plugin-os": "^2.2.0",
|
||||
"@tauri-apps/plugin-shell": "^2.2.0",
|
||||
"axios": "^1.7.9",
|
||||
"framer-motion": "^11.18.2",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.3.1",
|
||||
|
||||
85
AceJobAgency.client/pnpm-lock.yaml
generated
85
AceJobAgency.client/pnpm-lock.yaml
generated
@@ -23,6 +23,9 @@ importers:
|
||||
'@tauri-apps/plugin-shell':
|
||||
specifier: ^2.2.0
|
||||
version: 2.2.0
|
||||
axios:
|
||||
specifier: ^1.7.9
|
||||
version: 1.7.9
|
||||
framer-motion:
|
||||
specifier: ^11.18.2
|
||||
version: 11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -1717,6 +1720,9 @@ packages:
|
||||
arg@5.0.2:
|
||||
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
autoprefixer@10.4.20:
|
||||
resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
@@ -1724,6 +1730,9 @@ packages:
|
||||
peerDependencies:
|
||||
postcss: ^8.1.0
|
||||
|
||||
axios@1.7.9:
|
||||
resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
@@ -1779,6 +1788,10 @@ packages:
|
||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||
engines: {node: '>=12.5.0'}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
commander@4.1.1:
|
||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -1817,6 +1830,10 @@ packages:
|
||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
didyoumean@1.2.2:
|
||||
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
|
||||
|
||||
@@ -1859,10 +1876,23 @@ packages:
|
||||
resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
|
||||
hasBin: true
|
||||
|
||||
follow-redirects@1.15.9:
|
||||
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
foreground-child@3.3.0:
|
||||
resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
form-data@4.0.1:
|
||||
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
|
||||
@@ -1999,6 +2029,14 @@ packages:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
@@ -2113,6 +2151,9 @@ packages:
|
||||
resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
@@ -3687,7 +3728,7 @@ snapshots:
|
||||
|
||||
'@react-aria/calendar@3.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@internationalized/date': 3.6.0
|
||||
'@internationalized/date': 3.7.0
|
||||
'@react-aria/i18n': 3.12.4(react@18.3.1)
|
||||
'@react-aria/interactions': 3.22.5(react@18.3.1)
|
||||
'@react-aria/live-announcer': 3.4.1
|
||||
@@ -3739,7 +3780,7 @@ snapshots:
|
||||
|
||||
'@react-aria/datepicker@3.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@internationalized/date': 3.6.0
|
||||
'@internationalized/date': 3.7.0
|
||||
'@internationalized/number': 3.6.0
|
||||
'@internationalized/string': 3.2.5
|
||||
'@react-aria/focus': 3.19.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -4241,7 +4282,7 @@ snapshots:
|
||||
|
||||
'@react-stately/calendar@3.6.0(react@18.3.1)':
|
||||
dependencies:
|
||||
'@internationalized/date': 3.6.0
|
||||
'@internationalized/date': 3.7.0
|
||||
'@react-stately/utils': 3.10.5(react@18.3.1)
|
||||
'@react-types/calendar': 3.5.0(react@18.3.1)
|
||||
'@react-types/shared': 3.26.0(react@18.3.1)
|
||||
@@ -4284,7 +4325,7 @@ snapshots:
|
||||
|
||||
'@react-stately/datepicker@3.11.0(react@18.3.1)':
|
||||
dependencies:
|
||||
'@internationalized/date': 3.6.0
|
||||
'@internationalized/date': 3.7.0
|
||||
'@internationalized/string': 3.2.5
|
||||
'@react-stately/form': 3.1.1(react@18.3.1)
|
||||
'@react-stately/overlays': 3.6.13(react@18.3.1)
|
||||
@@ -4499,7 +4540,7 @@ snapshots:
|
||||
|
||||
'@react-types/calendar@3.5.0(react@18.3.1)':
|
||||
dependencies:
|
||||
'@internationalized/date': 3.6.0
|
||||
'@internationalized/date': 3.7.0
|
||||
'@react-types/shared': 3.26.0(react@18.3.1)
|
||||
react: 18.3.1
|
||||
|
||||
@@ -4526,7 +4567,7 @@ snapshots:
|
||||
|
||||
'@react-types/datepicker@3.9.0(react@18.3.1)':
|
||||
dependencies:
|
||||
'@internationalized/date': 3.6.0
|
||||
'@internationalized/date': 3.7.0
|
||||
'@react-types/calendar': 3.6.0(react@18.3.1)
|
||||
'@react-types/overlays': 3.8.12(react@18.3.1)
|
||||
'@react-types/shared': 3.27.0(react@18.3.1)
|
||||
@@ -4858,6 +4899,8 @@ snapshots:
|
||||
|
||||
arg@5.0.2: {}
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
autoprefixer@10.4.20(postcss@8.5.1):
|
||||
dependencies:
|
||||
browserslist: 4.24.4
|
||||
@@ -4868,6 +4911,14 @@ snapshots:
|
||||
postcss: 8.5.1
|
||||
postcss-value-parser: 4.2.0
|
||||
|
||||
axios@1.7.9:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.9
|
||||
form-data: 4.0.1
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
@@ -4925,6 +4976,10 @@ snapshots:
|
||||
color-convert: 2.0.1
|
||||
color-string: 1.9.1
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
commander@4.1.1: {}
|
||||
|
||||
compute-scroll-into-view@3.1.1: {}
|
||||
@@ -4949,6 +5004,8 @@ snapshots:
|
||||
|
||||
deepmerge@4.3.1: {}
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
didyoumean@1.2.2: {}
|
||||
|
||||
dlv@1.1.3: {}
|
||||
@@ -5007,11 +5064,19 @@ snapshots:
|
||||
|
||||
flat@5.0.2: {}
|
||||
|
||||
follow-redirects@1.15.9: {}
|
||||
|
||||
foreground-child@3.3.0:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
form-data@4.0.1:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
|
||||
fraction.js@4.3.7: {}
|
||||
|
||||
framer-motion@11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
@@ -5124,6 +5189,12 @@ snapshots:
|
||||
braces: 3.0.3
|
||||
picomatch: 2.3.1
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
@@ -5212,6 +5283,8 @@ snapshots:
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
react-dom@18.3.1(react@18.3.1):
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import {
|
||||
Input,
|
||||
Button,
|
||||
Link,
|
||||
Select,
|
||||
SelectItem,
|
||||
DatePicker,
|
||||
} from "@heroui/react";
|
||||
import { Input, Button, Link, Select, SelectItem } from "@heroui/react";
|
||||
import { IconMail, IconLock } from "@tabler/icons-react";
|
||||
import { useState } from "react";
|
||||
import http from "../http";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export default function SignupView({
|
||||
onLogin,
|
||||
@@ -17,6 +12,44 @@ export default function SignupView({
|
||||
email: string;
|
||||
}) {
|
||||
const [emailValue, setEmailValue] = useState(email);
|
||||
const [firstName, setFirstName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
const [nric, setNric] = useState("");
|
||||
const [gender, setGender] = useState("0");
|
||||
const dateOfBirthInput = document.getElementById("dateOfBirthInput");
|
||||
const [password, setPassword] = useState("");
|
||||
const [confirmPassword, setConfirmPassword] = useState("");
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const user = {
|
||||
id: "",
|
||||
firstName,
|
||||
lastName,
|
||||
gender: Number(gender),
|
||||
nationalRegistrationIdentityCardNumber: nric,
|
||||
email: emailValue,
|
||||
password,
|
||||
dateOfBirth: new Date((dateOfBirthInput as any).value),
|
||||
resumeName: "",
|
||||
whoAmI: "",
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await http.post("/User/register", user);
|
||||
|
||||
if (response.status != 200) {
|
||||
throw new Error("Failed to sign up");
|
||||
}
|
||||
|
||||
// Handle successful signup (e.g., show a message, redirect, etc.)
|
||||
console.log("User signed up successfully");
|
||||
} catch (error) {
|
||||
console.error("Error during signup:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
<div className="flex flex-col">
|
||||
@@ -25,8 +58,16 @@ export default function SignupView({
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-row gap-2">
|
||||
<Input label="First name" />
|
||||
<Input label="Last name" />
|
||||
<Input
|
||||
label="First name"
|
||||
value={firstName}
|
||||
onValueChange={setFirstName}
|
||||
/>
|
||||
<Input
|
||||
label="Last name"
|
||||
value={lastName}
|
||||
onValueChange={setLastName}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
endContent={<IconMail />}
|
||||
@@ -35,34 +76,46 @@ export default function SignupView({
|
||||
value={emailValue}
|
||||
onValueChange={setEmailValue}
|
||||
/>
|
||||
<Input label="NRIC" />
|
||||
<Input label="NRIC" value={nric} onValueChange={setNric} />
|
||||
<div className="flex flex-row gap-2">
|
||||
<Select label="Gender">
|
||||
<SelectItem>Male</SelectItem>
|
||||
<SelectItem>Female</SelectItem>
|
||||
<Select
|
||||
label="Gender"
|
||||
selectedKeys={[gender]}
|
||||
onChange={(e) => {
|
||||
setGender(e.target.value);
|
||||
}}
|
||||
>
|
||||
<SelectItem key={"0"}>Male</SelectItem>
|
||||
<SelectItem key={"1"}>Female</SelectItem>
|
||||
</Select>
|
||||
<DatePicker label="Date of birth" />
|
||||
<input
|
||||
type="date"
|
||||
className="rounded-xl px-4 transition-colors dark:bg-neutral-800 dark:hover:bg-neutral-700"
|
||||
id="dateOfBirthInput"
|
||||
/>
|
||||
</div>
|
||||
<Input endContent={<IconLock />} label="Password" type="password" />
|
||||
<Input
|
||||
endContent={<IconLock />}
|
||||
label="Password"
|
||||
type="password"
|
||||
value={password}
|
||||
onValueChange={setPassword}
|
||||
/>
|
||||
<Input
|
||||
endContent={<IconLock />}
|
||||
label="Confirm password"
|
||||
type="password"
|
||||
value={confirmPassword}
|
||||
onValueChange={setConfirmPassword}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 w-full">
|
||||
<Button color="primary" className="w-full">
|
||||
<Button color="primary" className="w-full" onPress={handleSubmit}>
|
||||
Sign up
|
||||
</Button>
|
||||
<div className="flex flex-row gap-2 w-full justify-center *:my-auto">
|
||||
<p className="text-sm">Already have an account?</p>
|
||||
<Link
|
||||
color="primary"
|
||||
onPress={() => {
|
||||
onLogin();
|
||||
}}
|
||||
className="text-sm"
|
||||
>
|
||||
<Link color="primary" onPress={onLogin} className="text-sm">
|
||||
Login
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
44
AceJobAgency.client/src/http.ts
Normal file
44
AceJobAgency.client/src/http.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import axios from "axios";
|
||||
|
||||
const http = axios.create({
|
||||
baseURL: "http://localhost:5117",
|
||||
});
|
||||
|
||||
// Add a request interceptor
|
||||
http.interceptors.request.use(
|
||||
function (config) {
|
||||
// Do something before request is sent
|
||||
let accessToken = localStorage.getItem("accessToken");
|
||||
if (accessToken) {
|
||||
config.headers["Authorization"] = `Bearer ${accessToken}`;
|
||||
}
|
||||
if (config.data && config.data.user) {
|
||||
delete config.data.user;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
function (error) {
|
||||
// Do something with request error
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// Add a response interceptor
|
||||
http.interceptors.response.use(
|
||||
function (response) {
|
||||
// Any status code that lie within the range of 2xx cause this function to trigger
|
||||
// Do something with response data
|
||||
return response;
|
||||
},
|
||||
function (error) {
|
||||
// Any status codes that falls outside the range of 2xx cause this function to trigger
|
||||
// Do something with response error
|
||||
if (error.response.status === 401 || error.response.status === 403) {
|
||||
localStorage.clear();
|
||||
window.location.assign("/error");
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default http;
|
||||
Reference in New Issue
Block a user