Skip to content

Commit

Permalink
feat(react-router): Add routes
Browse files Browse the repository at this point in the history
  • Loading branch information
1ilsang committed Aug 19, 2023
1 parent 584c5a0 commit c7bdd6e
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 16 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ module.exports = {
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'react-hooks/exhaustive-deps': 'off',
'react-refresh/only-export-components': 'off',
'import/order': [
'error',
{
Expand Down
16 changes: 10 additions & 6 deletions src/features/app/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import {
QueryClient,
QueryClientProvider,
QueryErrorResetBoundary,
} from '@tanstack/react-query';
import { FunctionComponent } from 'react';
import { RouterProvider } from 'react-router-dom';

import LayoutContainer from '../shared/layout/Container';
import HomeContainer from '../home/Container';
import Router from './Router';

const queryClient = new QueryClient();

const AppContainer: FunctionComponent = () => {
return (
<QueryClientProvider client={queryClient}>
<LayoutContainer>
<HomeContainer />
</LayoutContainer>
<QueryErrorResetBoundary>
<RouterProvider router={Router} />
</QueryErrorResetBoundary>
</QueryClientProvider>
);
};
Expand Down
30 changes: 30 additions & 0 deletions src/features/app/Router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Suspense } from 'react';
import {
Route,
createBrowserRouter,
createRoutesFromElements,
} from 'react-router-dom';

import LayoutContainer from '../shared/layout/Container';
import HomeContainer from '../home/Container';
import LoginContainer from '../login/Container';
import ErrorContainer from '../shared/error/Container';
import NotFound from '../shared/error/notfound/NotFound';

const router = createRoutesFromElements(
<Route
path="/"
element={
<Suspense>
<LayoutContainer />
</Suspense>
}
errorElement={<ErrorContainer />}
>
<Route index element={<HomeContainer />} />
<Route path="login" element={<LoginContainer />} />
<Route path="*" element={<NotFound />} />
</Route>,
);

export default createBrowserRouter(router);
6 changes: 5 additions & 1 deletion src/features/login/hooks/useLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { ChangeEventHandler, ReactEventHandler, useState } from 'react';
import { useAtom } from 'jotai';
import { useNavigate } from 'react-router-dom';

import { setItem } from '../../shared/utils/storage';
import { DummyUser } from '../type';
import { DUMMY_USER } from '../constants';
import { userAtom } from '../atom';
import { URL } from '../../shared/constants/url';

const useLogin = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState(false);
const [, setUser] = useAtom(userAtom);

const navigate = useNavigate();

const handleEmailChange: ChangeEventHandler<HTMLInputElement> = (e) => {
setEmail(e.target.value);
setError(false);
Expand All @@ -29,7 +33,7 @@ const useLogin = () => {
delete curUser.password;
setUser({ ...curUser });
setItem('user', curUser);
// TODO: Redirect Home;
navigate(URL.home);
};

return {
Expand Down
4 changes: 4 additions & 0 deletions src/features/shared/constants/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum URL {
home = '/',
login = '/login',
}
7 changes: 7 additions & 0 deletions src/features/shared/error/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FunctionComponent } from 'react';

const ErrorContainer: FunctionComponent = () => {
return <div>Error!</div>;
};

export default ErrorContainer;
19 changes: 19 additions & 0 deletions src/features/shared/error/notfound/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FunctionComponent } from 'react';
import { useNavigate } from 'react-router-dom';

import { URL } from '../../constants/url';
import './notfound.scss';

const NotFound: FunctionComponent = () => {
const navigate = useNavigate();
const handleHomeClick = () => navigate(URL.home);

return (
<div className="not-found">
<span>404</span>
<button onClick={handleHomeClick}>Go Home</button>
</div>
);
};

export default NotFound;
17 changes: 17 additions & 0 deletions src/features/shared/error/notfound/notfound.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.not-found {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;

span {
font-size: 3rem;
font-weight: 600;
}

button {
border: none;
cursor: pointer;
}
}
13 changes: 8 additions & 5 deletions src/features/shared/layout/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { FunctionComponent, PropsWithChildren } from 'react';
import { FunctionComponent } from 'react';
import { Outlet } from 'react-router-dom';

import './layout.scss';
import useLayout from './hooks/useLayout';

const LayoutContainer: FunctionComponent<PropsWithChildren> = ({
children,
}) => {
const LayoutContainer: FunctionComponent = () => {
useLayout();
return <div className="layout-container">{children}</div>;
return (
<div className="layout-container">
<Outlet />
</div>
);
};

export default LayoutContainer;
13 changes: 9 additions & 4 deletions src/features/shared/layout/hooks/useLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { useAtom } from 'jotai';
import { useLayoutEffect } from 'react';
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

import { userAtom } from '../../../login/atom';
import { getItem } from '../../utils/storage';
import { URL } from '../../constants/url';

const useLayout = () => {
const [user] = useAtom(userAtom);
const [, setUser] = useAtom(userAtom);
const navigate = useNavigate();

useLayoutEffect(() => {
useEffect(() => {
const user = getItem('user');
if (!user) {
// TODO: Redirect Login
navigate(URL.login);
return;
}
setUser({ ...user });
}, []);
};

Expand Down

0 comments on commit c7bdd6e

Please sign in to comment.