Skip to content

Commit

Permalink
feature: user login/registration + refresh token
Browse files Browse the repository at this point in the history
  • Loading branch information
goto-eof committed Apr 27, 2023
1 parent bd9d168 commit f1c2263
Show file tree
Hide file tree
Showing 17 changed files with 576 additions and 19,533 deletions.
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
REACT_APP_URI=http:https://localhost
REACT_APP_PORT=8080
REACT_APP_URI=
REACT_APP_PORT=
19,079 changes: 0 additions & 19,079 deletions package-lock.json

This file was deleted.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "micro-jobs-client",
"version": "0.1.0",
"private": true,
"proxy": "http:https://127.0.0.1:8080",
"dependencies": {
"@chakra-ui/icons": "^2.0.19",
"@chakra-ui/react": "^2.6.0",
Expand All @@ -17,6 +18,7 @@
"axios": "^1.3.6",
"framer-motion": "^6.5.1",
"react": "^18.2.0",
"react-cookie": "^4.1.1",
"react-dom": "^18.2.0",
"react-icons": "^3.11.0",
"react-router-dom": "^6.10.0",
Expand Down
16 changes: 9 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import {
} from '@chakra-ui/react';
import Main from './Main';
import { BrowserRouter } from 'react-router-dom';
import InterceptorInit from './components/InterceptorInit';

export const App = () => (
<React.StrictMode>
<ChakraProvider theme={theme}>
<BrowserRouter>
<Main />
</BrowserRouter>
</ChakraProvider>
</React.StrictMode>
// <React.StrictMode>
<ChakraProvider theme={theme}>
<BrowserRouter>
<InterceptorInit />
<Main />
</BrowserRouter>
</ChakraProvider>
// </React.StrictMode>
);
81 changes: 50 additions & 31 deletions src/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import Home from './components/Home';
import Offers from './components/Offers';
import Requests from './components/Requests';
import InsertJob from './components/InsertJob';
import Register from './components/Register';
import Login from './components/Login';
import InterceptorInit from './components/InterceptorInit';

const Links = [
{ name: 'Home', url: '/' },
Expand All @@ -46,6 +49,9 @@ const NavLink = ({ children }: { children: ReactNode }) => (

export default function Main() {
const { isOpen, onOpen, onClose } = useDisclosure();
const isAuthenticated = () => {
return localStorage.getItem('access_token');
};
let navigate = useNavigate();
return (
<>
Expand Down Expand Up @@ -73,38 +79,49 @@ export default function Main() {
</HStack>
</HStack>
<Flex alignItems={'center'}>
<Button
variant={'solid'}
colorScheme={'teal'}
size={'sm'}
mr={4}
leftIcon={<AddIcon />}
onClick={() => navigate('/insertJob')}
>
Add Job
</Button>
<Menu>
<MenuButton
as={Button}
rounded={'full'}
variant={'link'}
cursor={'pointer'}
minW={0}
{isAuthenticated() && (
<Button
variant={'solid'}
colorScheme={'teal'}
size={'sm'}
mr={4}
leftIcon={<AddIcon />}
onClick={() => navigate('/insertJob')}
>
<Avatar
size={'sm'}
src={
'https://images.unsplash.com/photo-1493666438817-866a91353ca9?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&s=b616b2c5b373a80ffc9636ba24f7a4a9'
}
/>
</MenuButton>
<MenuList>
<MenuItem>Link 1</MenuItem>
<MenuItem>Link 2</MenuItem>
<MenuDivider />
<MenuItem>Link 3</MenuItem>
</MenuList>
</Menu>
Add Job
</Button>
)}
{isAuthenticated() && (
<Menu>
<MenuButton
as={Button}
rounded={'full'}
variant={'link'}
cursor={'pointer'}
minW={0}
>
<Avatar
size={'sm'}
src={
'https://images.unsplash.com/photo-1493666438817-866a91353ca9?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&fit=crop&h=200&w=200&s=b616b2c5b373a80ffc9636ba24f7a4a9'
}
/>
</MenuButton>
<MenuList>
<MenuItem>Link 1</MenuItem>
<MenuItem>Link 2</MenuItem>
<MenuDivider />
<MenuItem>Link 3</MenuItem>
</MenuList>
</Menu>
)}
{!isAuthenticated() && (
<>
<span onClick={() => navigate('/authenticate')}>Login</span>
{' | '}
<span onClick={() => navigate('/register')}>Register</span>
</>
)}
</Flex>
</Flex>

Expand All @@ -128,6 +145,8 @@ export default function Main() {
<Route path="/offers" element={<Offers />} />
<Route path="/requests" element={<Requests />} />
<Route path="/insertJob" element={<InsertJob />} />
<Route path="/register" element={<Register />} />
<Route path="/authenticate" element={<Login />} />
</Routes>
</Box>
</Box>
Expand Down
2 changes: 1 addition & 1 deletion src/components/InsertJob.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function InserJob() {
description: form.description,
type: form.type,
};
GenericService.create<Job>('job', data).then((data) => {
GenericService.create<Job>('api/v1/job', data).then((data) => {
console.log(data);
if (form.type == 0) {
navigate('/offers');
Expand Down
14 changes: 14 additions & 0 deletions src/components/InterceptorInit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { customInterceptor } from '../interceptors/LoginInterceptor';
interface NavigateFunctionComponentProps {}
export default function InterceptorInit({}: NavigateFunctionComponentProps) {
let navigate = useNavigate();
const [ran, setRan] = useState(false);

if (!ran) {
customInterceptor(navigate);
setRan(true);
}
return <></>;
}
77 changes: 77 additions & 0 deletions src/components/Login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {
Box,
Button,
Center,
FormControl,
FormLabel,
Input,
} from '@chakra-ui/react';
import { useState } from 'react';
import GenericService from '../service/GenericService';
import { useNavigate } from 'react-router-dom';
import LoginRequest from '../dto/LoginRequest';

export default function Login() {
const [form, setForm] = useState({
firstname: '',
lastname: '',
username: '',
email: '',
password: '',
});
const updateFormData = (evt: any) => {
const name = evt.target.name;
const value =
evt.target.type === 'checkbox' ? evt.target.checked : evt.target.value;
setForm({
...form,
[name]: value,
});
};

const navigate = useNavigate();

const onSubmit = () => {
const data: LoginRequest = {
username: form.username,
password: form.password,
};
GenericService.create<LoginRequest>('api/v1/auth/authenticate', data).then(
(data: any) => {
console.log(data);
localStorage.setItem('access_token', data.access_token);
localStorage.setItem('refresh_token', data.refresh_token);
navigate('/offers');
}
);
};

return (
<Center>
<Box width={'3xl'}>
<FormControl isRequired>
<FormLabel>Username</FormLabel>
<Input
name="username"
value={form.username}
placeholder="Username"
onChange={(e) => updateFormData(e)}
/>
</FormControl>
<FormControl isRequired>
<FormLabel>Password</FormLabel>
<Input
name="password"
value={form.password}
type="password"
placeholder="Password"
onChange={(e) => updateFormData(e)}
/>
</FormControl>
<Button mt={4} colorScheme="teal" type="submit" onClick={onSubmit}>
Submit
</Button>
</Box>
</Center>
);
}
31 changes: 18 additions & 13 deletions src/components/Offers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,28 @@ import PaginationUtil from '../util/PaginationUtil';
export default function Offers() {
const [offers, setOffers] = useState<Array<Job>>(new Array<Job>());
const [itemsCount, setItemsCount] = useState(0);
const [loaded, setLoaded] = useState(false);
useEffect(() => {
GenericService.getAll<Array<Job>>('job/offers/0').then((data) => {
setOffers(data);
});

GenericService.get<GenericResponse<number>>('job/count/offers').then(
(genericResponse) => {
setItemsCount(genericResponse.value);
}
);
if (!loaded) {
GenericService.getAll<Array<Job>>('api/v1/job/offers/0').then((data) => {
GenericService.get<GenericResponse<number>>(
'api/v1/job/count/offers'
).then((genericResponse) => {
setOffers(data);
setItemsCount(genericResponse.value);
});
});
setLoaded(true);
}
}, []);

const goToPage = (page: number) => {
GenericService.getAll<Array<Job>>('job/offers/' + page).then((data) => {
setOffers(data);
window.scrollTo(0, 0);
});
GenericService.getAll<Array<Job>>('api/v1/job/offers/' + page).then(
(data) => {
setOffers(data);
window.scrollTo(0, 0);
}
);
};

return (
Expand Down
Loading

0 comments on commit f1c2263

Please sign in to comment.