diff --git a/app/courses/page.tsx b/app/courses/page.tsx
new file mode 100644
index 0000000..29a7f48
--- /dev/null
+++ b/app/courses/page.tsx
@@ -0,0 +1,8 @@
+export default function CoursesPage() {
+ return (
+
+
Courses
+
List of courses will be displayed here.
+
+ );
+}
diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx
index 45a306c..71abac0 100644
--- a/app/dashboard/page.tsx
+++ b/app/dashboard/page.tsx
@@ -1,6 +1,5 @@
import { redirect } from "next/navigation";
import { getAuthUser } from "@/lib/auth";
-import LogoutButton from "@/components/auth/logout/LogoutButton";
export default async function DashboardPage() {
const user = await getAuthUser();
@@ -11,8 +10,7 @@ export default async function DashboardPage() {
return (
Welcome, {user.firstname || user.email}
-
Organisation: {user.organisationName}
-
+
Enroll in an organisation to get started
);
}
diff --git a/app/history/page.tsx b/app/history/page.tsx
new file mode 100644
index 0000000..093fd4e
--- /dev/null
+++ b/app/history/page.tsx
@@ -0,0 +1,8 @@
+export default function HistoryPage() {
+ return (
+
+
History
+
History page content goes here.
+
+ );
+}
diff --git a/app/layout.tsx b/app/layout.tsx
index 868de58..c0e726d 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,9 +1,8 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
-import AuthHeader from "@/components/AuthHeader";
-import Footer from "@/components/Footer";
import { AuthProvider } from "@/context/AuthContext";
+import LayoutClient from "./layoutClient";
const inter = Inter({ subsets: ["latin"] });
@@ -12,7 +11,7 @@ export const metadata: Metadata = {
description: "Organization and employee skill management platform",
};
-export default function RootLayout({
+export default async function RootLayout({
children,
}: {
children: React.ReactNode;
@@ -21,9 +20,7 @@ export default function RootLayout({
-
- {children}
-
+ {children}
diff --git a/app/layoutClient.tsx b/app/layoutClient.tsx
new file mode 100644
index 0000000..9781077
--- /dev/null
+++ b/app/layoutClient.tsx
@@ -0,0 +1,34 @@
+"use client";
+
+import { useAuth } from "@/context/AuthContext";
+import HeaderNav from "@/components/HeaderNav";
+import SideNav from "@/components/SideNav";
+import Footer from "@/components/Footer";
+
+export default function LayoutClient({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const { user } = useAuth();
+ const isLoggedIn = user && user.isLoggedIn;
+
+ return (
+
+ {isLoggedIn && (
+
+
+ {children}
+
+ )}
+ {!isLoggedIn && (
+
+
+ {children}
+
+ )}
+
+
+
+ );
+}
diff --git a/app/loading.tsx b/app/loading.tsx
new file mode 100644
index 0000000..55bc33a
--- /dev/null
+++ b/app/loading.tsx
@@ -0,0 +1,27 @@
+export default function Loading() {
+ return (
+
+ );
+}
diff --git a/app/organisations/page.tsx b/app/organisations/page.tsx
new file mode 100644
index 0000000..ec9c8db
--- /dev/null
+++ b/app/organisations/page.tsx
@@ -0,0 +1,8 @@
+export default function OrganisationsPage() {
+ return (
+
+
Organisations
+
List of organisations will be displayed here.
+
+ );
+}
diff --git a/app/reports/page.tsx b/app/reports/page.tsx
new file mode 100644
index 0000000..8fc852e
--- /dev/null
+++ b/app/reports/page.tsx
@@ -0,0 +1,8 @@
+export default function ReportsPage() {
+ return (
+
+
Reports
+
List of reports will be displayed here.
+
+ );
+}
diff --git a/app/roadmap/page.tsx b/app/roadmap/page.tsx
new file mode 100644
index 0000000..bf5fba0
--- /dev/null
+++ b/app/roadmap/page.tsx
@@ -0,0 +1,8 @@
+export default function RoadmapPage() {
+ return (
+
+
Roadmap
+
Roadmap page content goes here.
+
+ );
+}
diff --git a/app/settings/page.tsx b/app/settings/page.tsx
new file mode 100644
index 0000000..2d5771f
--- /dev/null
+++ b/app/settings/page.tsx
@@ -0,0 +1,8 @@
+export default function SettingsPage() {
+ return (
+
+
Settings
+
Settings page content goes here.
+
+ );
+}
diff --git a/components/AuthHeader.tsx b/components/AuthHeader.tsx
deleted file mode 100644
index 7fce395..0000000
--- a/components/AuthHeader.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import Image from "next/image";
-import Link from "next/link";
-
-export default function AuthHeader() {
- const authenticated = false; // Replace with actual authentication logic
-
- if (!authenticated) {
- return (
-
-
-
-
-
- SKILLSTACK
-
-
-
-
- );
- }
-
- return null;
-}
diff --git a/components/HeaderNav.tsx b/components/HeaderNav.tsx
new file mode 100644
index 0000000..9cc2f54
--- /dev/null
+++ b/components/HeaderNav.tsx
@@ -0,0 +1,17 @@
+import Image from "next/image";
+import Link from "next/link";
+
+export default function HeaderNav() {
+ return (
+
+
+
+
+
+ SKILLSTACK
+
+
+
+
+ );
+}
diff --git a/components/SideNav.tsx b/components/SideNav.tsx
new file mode 100644
index 0000000..020edf5
--- /dev/null
+++ b/components/SideNav.tsx
@@ -0,0 +1,111 @@
+"use client";
+
+import Image from "next/image";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import { useState } from "react";
+import {
+ HomeIcon,
+ BookOpenIcon,
+ ChartBarIcon,
+ UsersIcon,
+ MapIcon,
+ ClockIcon,
+ CogIcon,
+} from "@heroicons/react/24/outline";
+import LogoutButton from "./auth/logout/LogoutButton";
+import { useAuth } from "@/context/AuthContext";
+
+const menuSections = [
+ {
+ heading: "General",
+ items: [
+ { label: "Dashboard", href: "/dashboard", icon: HomeIcon },
+ { label: "My Roadmap", href: "/roadmap", icon: MapIcon },
+ { label: "Courses", href: "/courses", icon: BookOpenIcon },
+ { label: "Reports", href: "/reports", icon: ChartBarIcon },
+ ],
+ },
+ {
+ heading: "Management",
+ items: [
+ { label: "History", href: "/history", icon: ClockIcon },
+ { label: "Organisations", href: "/organisations", icon: UsersIcon },
+ { label: "Settings", href: "/settings", icon: CogIcon },
+ ],
+ },
+];
+
+export default function SideNav() {
+ const path = usePathname();
+ const { user } = useAuth();
+ const firstName = user.firstname || user.email;
+ const lastName = user.lastname || user.email;
+ const avatarUrl = `https://avatar.iran.liara.run/username?username=${firstName}+${lastName}&background=f4d9b2&color=FF9800`;
+ const [imgSrc, setImgSrc] = useState(avatarUrl);
+
+ return (
+
+ );
+}
diff --git a/components/auth/logout/LogoutButton.tsx b/components/auth/logout/LogoutButton.tsx
index 9a5e7a1..8d2d1d8 100644
--- a/components/auth/logout/LogoutButton.tsx
+++ b/components/auth/logout/LogoutButton.tsx
@@ -24,7 +24,7 @@ export default function LogoutButton() {
diff --git a/next.config.ts b/next.config.ts
index 50e09c1..dedb731 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -9,6 +9,13 @@ const nextConfig: NextConfig = {
},
];
},
+ images: {
+ remotePatterns: [
+ {
+ hostname: "avatar.iran.liara.run",
+ },
+ ],
+ },
};
export default nextConfig;
diff --git a/package-lock.json b/package-lock.json
index 473fec8..3b93464 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "skillstack",
"version": "0.1.0",
"dependencies": {
+ "@heroicons/react": "^2.2.0",
"cookie": "^1.0.2",
"next": "15.3.2",
"react": "^19.0.0",
@@ -226,6 +227,15 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@heroicons/react": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz",
+ "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">= 16 || ^19.0.0-rc"
+ }
+ },
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
diff --git a/package.json b/package.json
index 0447103..9176390 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
+ "@heroicons/react": "^2.2.0",
"cookie": "^1.0.2",
"next": "15.3.2",
"react": "^19.0.0",
diff --git a/public/avatar-placeholder.jpg b/public/avatar-placeholder.jpg
new file mode 100644
index 0000000..7a8a843
Binary files /dev/null and b/public/avatar-placeholder.jpg differ