Skip to content

Commit d459564

Browse files
Merge pull request #12 from snippet-labs/component/navigation
[CLIENT] [COMPONENT] : Navigation bar in application
2 parents 9649777 + 60b7fb3 commit d459564

File tree

15 files changed

+414
-8
lines changed

15 files changed

+414
-8
lines changed

client/index.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33

44
<head>
55
<meta charset="UTF-8" />
6-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<link rel="icon" type="image/svg+xml" href="/public//logos/__favicon.png" />
77
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<!-- GOOGLE FONTS -->
9+
<link rel="preconnect" href="https://fonts.googleapis.com">
10+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11+
<link href="https://fonts.googleapis.com/css2?family=Monoton&display=swap" rel="stylesheet">
12+
<!-- APPLICATION TITLE -->
813
<title>SNIPPETLABS | Offical page</title>
914
</head>
1015

client/public/logos/__favicon.png

53 KB
Loading

client/src/App.tsx

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,37 @@
1-
import React from 'react';
1+
import React, { lazy, Suspense, useEffect, useState } from 'react';
2+
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';
3+
// COMPONENTS
4+
const Layout = lazy(() => import('./components/Layout/Layout'));
5+
// UTILS
6+
import Loader from './utils/Loader/Loader';
7+
// ICONS
8+
//STORE
9+
10+
const Content: React.FC = () => {
11+
// STATES
12+
const location = useLocation();
13+
const [isLoading, setIsLoading] = useState<boolean>(() => false);
14+
15+
useEffect(() => {
16+
setIsLoading(true);
17+
const loadingTime = setTimeout(() => {
18+
setIsLoading(false);
19+
}, 1000);
20+
21+
return () => clearTimeout(loadingTime);
22+
}, [location.pathname]);
23+
return isLoading ? <Loader /> : <Layout />;
24+
};
225

326
const App: React.FC = () => {
427
return (
5-
<div>
6-
<div className="flex items-center justify-center text-5xl">
7-
SNIPPETLABS
8-
</div>
9-
</div>
28+
<Suspense fallback={<Loader />}>
29+
<BrowserRouter>
30+
<Routes>
31+
<Route path="/*" element={<Content />} />
32+
</Routes>
33+
</BrowserRouter>
34+
</Suspense>
1035
);
1136
};
1237

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react';
2+
3+
const Footer: React.FC = () => {
4+
return <div></div>;
5+
};
6+
7+
export default Footer;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* Desktop and Mobile Navigation links */
2+
.DESKTOP-LINKS {
3+
@apply font-semibold rounded-2xl bg-white/20 shadow-lg ring-2 ring-black/10 px-3 py-4;
4+
}
5+
.DESKTOP-LINKS-ACTIVE {
6+
@apply text-black rounded-xl shadow-lg border-1 p-3;
7+
}
8+
.MOBILE-LINKS {
9+
@apply font-semibold rounded-xl bg-white/20 shadow-lg ring-2 ring-black/10 p-2;
10+
}
11+
.MOBILE-LINKS-HOVER {
12+
@apply font-semibold rounded-xl hover:bg-white/20 hover:shadow-lg hover:ring-2 hover:ring-black/10 p-2;
13+
}
14+
15+
/* Button */
16+
.BUTTON {
17+
@apply font-semibold rounded-2xl bg-white shadow-lg ring-2 px-4 py-4;
18+
}
19+
20+
/* Border */
21+
.BORDER-LEFT-CORNER-3XL {
22+
@apply border-l-3 border-white rounded-l-2xl;
23+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React, { useState } from 'react';
2+
import { NavLink, Link } from 'react-router-dom';
3+
4+
// ICONS
5+
import { HiMenuAlt3, HiX } from 'react-icons/hi';
6+
// UTILS
7+
import Logo from '../../../utils/Logo/Logo';
8+
// DATA
9+
import NAVIGATION_LINKS from '../../../data/NavigationLinks/NavigationLinks';
10+
11+
const NavigationBar: React.FC = () => {
12+
// STATES
13+
const [toggleSidebar, setToggleSidebar] = useState(() => false);
14+
15+
// STATE HANDLER FUNCTION
16+
const handleOpenSidebar = () => {
17+
setToggleSidebar(!toggleSidebar);
18+
};
19+
const handleCloseSidebar = () => {
20+
setToggleSidebar(false);
21+
};
22+
23+
// RENDER
24+
return (
25+
<>
26+
<div className="FULL h-[9vh] BG-BLACK-PRIMARY FLEX-BETWEEN PADDING">
27+
<Logo className="font-style-logo text-4xl TEXT-WHITE-PRIMARY" />
28+
{/* Desktop Navigation Bar */}
29+
<div className="hidden FLEX-CENTER-LG gap-4">
30+
<div className="DESKTOP-LINKS">
31+
<ul className="TEXT-COLOR-PRIMARY FLEX-CENTER gap-6">
32+
{NAVIGATION_LINKS.map(({ name, path }, id) => (
33+
<li key={id} className="GRAY-300 TEXT-WHITE-PRIMARY-HOVER">
34+
<NavLink
35+
to={path}
36+
className={({ isActive }) =>
37+
isActive ? 'DESKTOP-LINKS-ACTIVE BG-WHITE-PRIMARY' : ''
38+
}
39+
>
40+
{name}
41+
</NavLink>
42+
</li>
43+
))}
44+
</ul>
45+
</div>
46+
<Link to="/contact-us" className="TEXT-BLACK-PRIMARY BUTTON POINTER">
47+
Contract
48+
</Link>
49+
</div>
50+
{/* Mobile Navigation Bar */}
51+
<button
52+
className="lg:hidden MOBILE-LINKS-HOVER POINTER"
53+
onClick={handleOpenSidebar}
54+
>
55+
<HiMenuAlt3 size={30} className="TEXT-WHITE-PRIMARY" />
56+
</button>
57+
</div>
58+
59+
{/* Mobile Sidebar Toggle with Overlay */}
60+
<div
61+
className={`FIXED inset-0 z-50 lg:hidden transition-opacity D-300 EASE ${
62+
toggleSidebar
63+
? 'opacity-100 pointer-events-auto'
64+
: 'opacity-0 pointer-events-none'
65+
}`}
66+
>
67+
{/* Backdrop */}
68+
<div
69+
className="ABSOLUTE inset-0 BG-BLACK-PRIMARY backdrop-blur-3xl transition-opacity D-300 EASE"
70+
onClick={handleCloseSidebar}
71+
/>
72+
73+
{/* Sidebar */}
74+
<div
75+
className={`ABSOLUTE BORDER-LEFT-CORNER-3XL T0 R0 h-full w-80 max-w-[85vw] BG-BLACK-PRIMARY TEXT-WHITE-PRIMARY TRANSFORM D-300 EASE ${
76+
toggleSidebar ? 'translate-x-0' : 'translate-x-full'
77+
}`}
78+
>
79+
{/* Sidebar Header */}
80+
<div className="FLEX-BETWEEN PADDING h-[9vh] border-b border-gray-500">
81+
<Logo className="font-style-logo text-3xl TEXT-WHITE-PRIMARY" />
82+
<button
83+
onClick={handleCloseSidebar}
84+
className="TEXT-WHITE-PRIMARY POINTER p-2 WHITE-20-HOVER rounded-xl COLORS D-300"
85+
>
86+
<HiX size={30} />
87+
</button>
88+
</div>
89+
90+
{/* Sidebar Content */}
91+
<div className="p-6">
92+
{/* Navigation Links */}
93+
<nav className="mb-8">
94+
<ul className="space-y-4">
95+
{NAVIGATION_LINKS.map(({ name, path }, id) => (
96+
<li key={id}>
97+
<NavLink
98+
to={path}
99+
onClick={handleCloseSidebar}
100+
className={({ isActive }) =>
101+
`BLOCK px-4 py-3 rounded-xl ALL D-300 ${
102+
isActive
103+
? 'BG-WHITE-PRIMARY TEXT-BLACK-PRIMARY SEMIBOLD'
104+
: 'TEXT-WHITE-PRIMARY WHITE-20-HOVER'
105+
}`
106+
}
107+
>
108+
{name}
109+
</NavLink>
110+
</li>
111+
))}
112+
</ul>
113+
</nav>
114+
115+
{/* Contact Button */}
116+
<Link
117+
to="/contact-us"
118+
onClick={handleCloseSidebar}
119+
className="BLOCK FULL CENTER TEXT-BLACK-PRIMARY BUTTON POINTER TRANSFROM D-300 hover:scale-105"
120+
>
121+
Contract
122+
</Link>
123+
</div>
124+
</div>
125+
</div>
126+
</>
127+
);
128+
};
129+
130+
export default NavigationBar;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React, { Suspense } from 'react';
2+
import { Routes, Route } from 'react-router-dom';
3+
4+
// COMPONENTS
5+
import NavigationBar from '../General/NavigationBar/NavigationBar';
6+
import Footer from '../General/Footer/Footer';
7+
// UTILS
8+
import Loader from '../../utils/Loader/Loader';
9+
10+
const Layout: React.FC = () => {
11+
return (
12+
<div>
13+
<NavigationBar />
14+
<Suspense fallback={<Loader />}>
15+
<Routes>
16+
<Route path="/" element={<></>} />
17+
</Routes>
18+
</Suspense>
19+
20+
<Footer />
21+
</div>
22+
);
23+
};
24+
25+
export default Layout;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { NavigationLinkProps } from "./NavigationLinks.types";
2+
3+
const NAVIGATION_LINKS: NavigationLinkProps[] = [
4+
{
5+
id: 1,
6+
name: "Home",
7+
path: "/"
8+
},
9+
{
10+
id: 2,
11+
name: "AboutUs",
12+
path: "/about-us"
13+
},
14+
{
15+
id: 3,
16+
name: "TechStack",
17+
path: "/tech-stack"
18+
},
19+
{
20+
id: 4,
21+
name: "Client",
22+
path: "/client-projects"
23+
},
24+
{
25+
id: 5,
26+
name: "Products",
27+
path: "/products"
28+
},
29+
{
30+
id: 6,
31+
name: "Team",
32+
path: "/team"
33+
}
34+
];
35+
36+
export default NAVIGATION_LINKS;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export type NavigationLinkProps = {
2+
id: number;
3+
name: string;
4+
path: string;
5+
}

0 commit comments

Comments
 (0)