Skip to content

Commit 7bee674

Browse files
feat: navbar setup
0 parents  commit 7bee674

25 files changed

+3611
-0
lines changed

.eslintrc.cjs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
env: { browser: true, es2020: true },
3+
extends: [
4+
'eslint:recommended',
5+
'plugin:@typescript-eslint/recommended',
6+
'plugin:react-hooks/recommended',
7+
],
8+
parser: '@typescript-eslint/parser',
9+
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
10+
plugins: ['react-refresh'],
11+
rules: {
12+
'react-refresh/only-export-components': 'warn',
13+
},
14+
}

.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React + TS</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

package.json

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "test_site",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc && vite build",
9+
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@emotion/react": "^11.11.1",
14+
"@emotion/styled": "^11.11.0",
15+
"@mui/icons-material": "^5.13.7",
16+
"@mui/material": "^5.13.7",
17+
"@mui/styled-engine-sc": "^5.12.0",
18+
"@reduxjs/toolkit": "^1.9.5",
19+
"react": "^18.2.0",
20+
"react-dom": "^18.2.0",
21+
"react-redux": "^8.1.1",
22+
"react-router-dom": "^6.14.1",
23+
"styled-components": "^6.0.2"
24+
},
25+
"devDependencies": {
26+
"@types/react": "^18.0.37",
27+
"@types/react-dom": "^18.0.11",
28+
"@typescript-eslint/eslint-plugin": "^5.59.0",
29+
"@typescript-eslint/parser": "^5.59.0",
30+
"@vitejs/plugin-react": "^4.0.0",
31+
"eslint": "^8.38.0",
32+
"eslint-plugin-react-hooks": "^4.6.0",
33+
"eslint-plugin-react-refresh": "^0.3.4",
34+
"typescript": "^5.0.2",
35+
"vite": "^4.3.9"
36+
}
37+
}

public/vite.svg

+1
Loading

src/App.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React, { useMemo } from 'react';
2+
import { BrowserRouter, Navigate, Routes, Route } from 'react-router-dom';
3+
import { createTheme } from '@mui/material/styles';
4+
import { themeSettings } from './styles/theme';
5+
import { useAppSelector } from './store';
6+
import { CssBaseline, PaletteMode, ThemeProvider } from '@mui/material';
7+
8+
import Layout from './scenes/Layout';
9+
import Dashboard from './scenes/Dashboard';
10+
11+
const App = () => {
12+
const mode = useAppSelector((state) => state.global.mode) as PaletteMode;
13+
const theme = useMemo(() => createTheme(themeSettings(mode)), [mode]);
14+
15+
return (
16+
<BrowserRouter>
17+
<ThemeProvider theme={theme}>
18+
<CssBaseline />
19+
<Routes>
20+
<Route element={<Layout />}>
21+
<Route path='/' element={<Navigate to='/dashboard' replace />} />
22+
<Route path='/dashboard' element={<Dashboard />} />
23+
</Route>
24+
</Routes>
25+
</ThemeProvider>
26+
</BrowserRouter>
27+
);
28+
};
29+
30+
export default App;

src/assets/logo.png

3.23 KB
Loading

src/assets/profileIcon.png

441 Bytes
Loading

src/assets/react.svg

+1
Loading

src/components/FlexBetween/index.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Box } from '@mui/material';
2+
import React from 'react';
3+
4+
type Props = {
5+
children: React.ReactNode;
6+
};
7+
const FlexBetween = ({ children }: Props) => {
8+
return (
9+
<Box display='flex' justifyContent='space-between' alignItems='center' gap='1.5rem'>
10+
{children}
11+
</Box>
12+
);
13+
};
14+
15+
export default FlexBetween;

src/components/Navbar/index.tsx

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { AppBar, Box, IconButton, Link, Toolbar } from '@mui/material';
2+
import React from 'react';
3+
import FlexBetween from '../FlexBetween';
4+
import logo from '../../assets/logo.png';
5+
import { Link as RouterLink } from 'react-router-dom';
6+
7+
/* ASSETS */
8+
import './navbar.styles.css';
9+
import {
10+
FavoriteBorder,
11+
PersonOutlined,
12+
SearchOutlined,
13+
ShoppingCartCheckoutOutlined,
14+
} from '@mui/icons-material';
15+
16+
const Navbar = () => {
17+
return (
18+
<AppBar
19+
sx={{ position: 'static', background: 'none', boxShadow: 'none', padding: '1.25rem 2rem' }}
20+
>
21+
<Toolbar sx={{ display: 'flex', justifyContent: 'space-around' }}>
22+
<Box
23+
component='img'
24+
alt='profile'
25+
src={logo}
26+
height='32px'
27+
width='141px'
28+
sx={{ objectFit: 'cover' }}
29+
/>
30+
31+
<Box component='nav' maxWidth='430px' flexGrow={1}>
32+
<FlexBetween>
33+
<Link component={RouterLink} to='/' className='nav-item'>
34+
Home
35+
</Link>
36+
<Link component={RouterLink} to='/' className='nav-item'>
37+
Shop
38+
</Link>
39+
<Link component={RouterLink} to='/' className='nav-item'>
40+
About
41+
</Link>
42+
<Link component={RouterLink} to='/' className='nav-item'>
43+
Contact
44+
</Link>
45+
</FlexBetween>
46+
</Box>
47+
48+
<FlexBetween>
49+
<IconButton>
50+
<SearchOutlined />
51+
</IconButton>
52+
<IconButton>
53+
<PersonOutlined />
54+
</IconButton>
55+
<IconButton>
56+
<FavoriteBorder />
57+
</IconButton>
58+
<IconButton>
59+
<ShoppingCartCheckoutOutlined />
60+
</IconButton>
61+
</FlexBetween>
62+
</Toolbar>
63+
</AppBar>
64+
);
65+
};
66+
67+
export default Navbar;
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.nav-item {
2+
color: #000 !important;
3+
font-size: 1rem !important;
4+
font-style: normal;
5+
font-weight: 500;
6+
line-height: normal;
7+
}
8+
9+
.nav-item:hover {
10+
text-decoration: none !important;
11+
}

src/main.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom/client';
3+
import { Provider } from 'react-redux';
4+
5+
import App from './App';
6+
import store from './store';
7+
8+
import './styles/global.css';
9+
10+
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
11+
<React.StrictMode>
12+
<Provider store={store}>
13+
<App />
14+
</Provider>
15+
</React.StrictMode>
16+
);

src/scenes/Dashboard/index.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react';
2+
3+
const Dashboard = () => {
4+
return <div>Dashboard</div>;
5+
};
6+
7+
export default Dashboard;

src/scenes/Layout/index.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Box } from '@mui/material';
2+
import React from 'react';
3+
import FlexBetween from '../../components/FlexBetween';
4+
import Navbar from '../../components/Navbar';
5+
6+
const Layout = () => {
7+
return (
8+
<Box>
9+
<FlexBetween>
10+
<Navbar />
11+
</FlexBetween>
12+
</Box>
13+
);
14+
};
15+
16+
export default Layout;

src/store/index.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { configureStore } from '@reduxjs/toolkit';
2+
import { useSelector, useDispatch, TypedUseSelectorHook } from 'react-redux';
3+
import { rootReducer } from './slices';
4+
5+
const store = configureStore({
6+
reducer: rootReducer,
7+
});
8+
9+
export type RootState = ReturnType<typeof store.getState>;
10+
export type AppDispatch = typeof store.dispatch;
11+
12+
// Use throughout your app instead of plain `useDispatch` and `useSelector`
13+
export const useAppDispatch: () => AppDispatch = useDispatch;
14+
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
15+
16+
export default store;

src/store/slices/global.slice.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createSlice } from '@reduxjs/toolkit';
2+
3+
const globalSlice = createSlice({
4+
name: 'global',
5+
initialState: {
6+
mode: 'light',
7+
},
8+
reducers: {
9+
setMode: (state, actions) => {
10+
state.mode = actions.payload;
11+
},
12+
},
13+
});
14+
15+
export default globalSlice.reducer;
16+
17+
export const { setMode } = globalSlice.actions;

src/store/slices/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { combineReducers } from '@reduxjs/toolkit';
2+
import globalReducer from './global.slice';
3+
4+
export const rootReducer = combineReducers({ global: globalReducer });

src/styles/global.css

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
2+
3+
*,
4+
::before,
5+
::after {
6+
margin: 0;
7+
padding: 0;
8+
box-sizing: border-box;
9+
}
10+
11+
html,
12+
body {
13+
width: 100%;
14+
height: 100%;
15+
}

0 commit comments

Comments
 (0)