diff --git a/client/package-lock.json b/client/package-lock.json
index 0abc62a..873e636 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -9,7 +9,8 @@
"version": "0.0.0",
"dependencies": {
"react": "^19.2.0",
- "react-dom": "^19.2.0"
+ "react-dom": "^19.2.0",
+ "react-router-dom": "^7.13.1"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
@@ -1677,6 +1678,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/cookie": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2561,6 +2575,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -2578,6 +2593,44 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "7.13.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz",
+ "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.13.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.1.tgz",
+ "integrity": "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.13.1"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -2649,6 +2702,12 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
+ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
diff --git a/client/package.json b/client/package.json
index 6895186..d123ae8 100644
--- a/client/package.json
+++ b/client/package.json
@@ -11,7 +11,8 @@
},
"dependencies": {
"react": "^19.2.0",
- "react-dom": "^19.2.0"
+ "react-dom": "^19.2.0",
+ "react-router-dom": "^7.13.1"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
diff --git a/client/src/App.jsx b/client/src/App.jsx
index f67355a..480eb34 100644
--- a/client/src/App.jsx
+++ b/client/src/App.jsx
@@ -1,35 +1,57 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
-import './App.css'
+import { BrowserRouter, Routes, Route } from 'react-router-dom';
+import Header from './components/layout/Header';
+import Footer from './components/layout/Footer';
+import Home from './pages/Home';
+import Login from './pages/Login';
+import Register from './pages/Register';
+import Dashboard from './pages/Dashboard';
function App() {
- const [count, setCount] = useState(0)
-
return (
- <>
-
-
-
- Edit src/App.jsx and save to test HMR
-
+
+
+ {/* Header appears on all pages */}
+
+
+ {/* Main content area */}
+
+
+ {/* Define your routes here */}
+ } />
+ } />
+ } />
+ } />
+
+ {/* 404 Page - catches all unmatched routes */}
+ } />
+
+
+
+ {/* Footer appears on all pages */}
+
-
- Click on the Vite and React logos to learn more
-
- >
- )
+
+ );
}
-export default App
+// Simple 404 component
+const NotFound = () => {
+ return (
+
+
404 - Page Not Found
+
The page you're looking for doesn't exist.
+
+ );
+};
+
+const appStyle = {
+ display: 'flex',
+ flexDirection: 'column',
+ minHeight: '100vh',
+};
+
+const mainStyle = {
+ flex: 1,
+};
+
+export default App;
diff --git a/client/src/components/layout/Footer.jsx b/client/src/components/layout/Footer.jsx
new file mode 100644
index 0000000..51ed6d8
--- /dev/null
+++ b/client/src/components/layout/Footer.jsx
@@ -0,0 +1,26 @@
+const Footer = () => {
+ return (
+
+ );
+};
+
+const footerStyle = {
+ backgroundColor: '#333',
+ color: 'white',
+ padding: '2rem 0',
+ marginTop: 'auto',
+ textAlign: 'center',
+};
+
+const containerStyle = {
+ maxWidth: '1200px',
+ margin: '0 auto',
+ padding: '0 2rem',
+};
+
+export default Footer;
\ No newline at end of file
diff --git a/client/src/components/layout/Header.jsx b/client/src/components/layout/Header.jsx
new file mode 100644
index 0000000..bc411a7
--- /dev/null
+++ b/client/src/components/layout/Header.jsx
@@ -0,0 +1,57 @@
+import { Link } from 'react-router-dom';
+
+const Header = () => {
+ return (
+
+ );
+};
+
+// Basic inline styles (you can move these to CSS later)
+const headerStyle = {
+ backgroundColor: '#333',
+ color: 'white',
+ padding: '1rem 0',
+};
+
+const containerStyle = {
+ maxWidth: '1200px',
+ margin: '0 auto',
+ padding: '0 2rem',
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+};
+
+const logoStyle = {
+ margin: 0,
+ fontSize: '1.5rem',
+};
+
+const linkStyle = {
+ color: 'white',
+ textDecoration: 'none',
+};
+
+const navLinkStyle = {
+ color: 'white',
+ textDecoration: 'none',
+ marginLeft: '2rem',
+};
+
+export default Header;
\ No newline at end of file
diff --git a/client/src/index.css b/client/src/index.css
index 08a3ac9..a7f816f 100644
--- a/client/src/index.css
+++ b/client/src/index.css
@@ -1,68 +1,31 @@
-:root {
- font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
-
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
- font-synthesis: none;
- text-rendering: optimizeLegibility;
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ background-color: #f8f9fa;
}
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
-
-body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
+h1, h2, h3, h4, h5, h6 {
+ margin-bottom: 0.5rem;
}
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
+p {
+ margin-bottom: 1rem;
}
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
+a {
+ color: #007bff;
+ text-decoration: none;
}
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
-}
+a:hover {
+ text-decoration: underline;
+}
\ No newline at end of file
diff --git a/client/src/pages/Dashboard.jsx b/client/src/pages/Dashboard.jsx
new file mode 100644
index 0000000..4da4992
--- /dev/null
+++ b/client/src/pages/Dashboard.jsx
@@ -0,0 +1,60 @@
+const Dashboard = () => {
+ return (
+
+
+
Dashboard
+
Welcome back!
+
+
+
+
+
Your Dashboard
+
This page will display:
+
+ - Your created content (posts/recipes/workouts)
+ - Statistics and analytics
+ - Quick actions (create new, edit, delete)
+ - Recent activity
+
+
+ This will be built after authentication is implemented
+
+
+
+
+ );
+};
+
+const containerStyle = {
+ minHeight: '80vh',
+ padding: '2rem',
+};
+
+const headerStyle = {
+ maxWidth: '1200px',
+ margin: '0 auto 2rem',
+};
+
+const contentStyle = {
+ maxWidth: '1200px',
+ margin: '0 auto',
+};
+
+const placeholderStyle = {
+ backgroundColor: '#f8f9fa',
+ padding: '2rem',
+ borderRadius: '8px',
+};
+
+const listStyle = {
+ paddingLeft: '1.5rem',
+ marginTop: '1rem',
+};
+
+const noteStyle = {
+ marginTop: '1rem',
+ fontStyle: 'italic',
+ color: '#666',
+};
+
+export default Dashboard;
\ No newline at end of file
diff --git a/client/src/pages/Home.jsx b/client/src/pages/Home.jsx
new file mode 100644
index 0000000..d7198f8
--- /dev/null
+++ b/client/src/pages/Home.jsx
@@ -0,0 +1,112 @@
+import { Link } from 'react-router-dom';
+
+const Home = () => {
+ return (
+
+
+
{/* Platform Name/Tagline */}
+
+ {/* Brief description of what your platform does */}
+
+
+
+ Get Started
+
+
+ Login
+
+
+
+
+ {/* Features Section (Optional) */}
+
+
Why Choose {/* Platform Name */}?
+
+ {/* Add 3 feature cards based on your theme */}
+
+
Feature 1
+
Description
+
+
+
Feature 2
+
Description
+
+
+
Feature 3
+
Description
+
+
+
+
+ );
+};
+
+const containerStyle = {
+ minHeight: '100vh',
+};
+
+const heroStyle = {
+ textAlign: 'center',
+ padding: '4rem 2rem',
+ backgroundColor: '#f5f5f5',
+};
+
+const titleStyle = {
+ fontSize: '3rem',
+ marginBottom: '1rem',
+ color: '#333',
+};
+
+const subtitleStyle = {
+ fontSize: '1.25rem',
+ color: '#666',
+ marginBottom: '2rem',
+};
+
+const ctaStyle = {
+ display: 'flex',
+ gap: '1rem',
+ justifyContent: 'center',
+};
+
+const buttonStyle = {
+ backgroundColor: '#007bff',
+ color: 'white',
+ padding: '0.75rem 2rem',
+ borderRadius: '5px',
+ textDecoration: 'none',
+ fontWeight: 'bold',
+};
+
+const secondaryButtonStyle = {
+ backgroundColor: 'white',
+ color: '#007bff',
+ padding: '0.75rem 2rem',
+ borderRadius: '5px',
+ textDecoration: 'none',
+ fontWeight: 'bold',
+ border: '2px solid #007bff',
+};
+
+const featuresStyle = {
+ padding: '4rem 2rem',
+ textAlign: 'center',
+};
+
+const featureGridStyle = {
+ display: 'grid',
+ gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
+ gap: '2rem',
+ marginTop: '2rem',
+ maxWidth: '1200px',
+ margin: '2rem auto',
+};
+
+const featureCardStyle = {
+ padding: '2rem',
+ backgroundColor: 'white',
+ borderRadius: '8px',
+ boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
+};
+
+export default Home;
\ No newline at end of file
diff --git a/client/src/pages/Login.jsx b/client/src/pages/Login.jsx
new file mode 100644
index 0000000..154061f
--- /dev/null
+++ b/client/src/pages/Login.jsx
@@ -0,0 +1,85 @@
+import { Link } from 'react-router-dom';
+
+const Login = () => {
+ return (
+
+
+
Login
+
Sign in to your account
+
+ {/* Placeholder for login form */}
+
+
Login form will be implemented in a future lesson
+
This will include:
+
+ - Email input field
+ - Password input field
+ - Login button
+ - Form validation
+
+
+
+
+ Don't have an account?{' '}
+
+ Register here
+
+
+
+
+ );
+};
+
+const containerStyle = {
+ minHeight: '80vh',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: '2rem',
+};
+
+const formContainerStyle = {
+ maxWidth: '400px',
+ width: '100%',
+ padding: '2rem',
+ backgroundColor: 'white',
+ borderRadius: '8px',
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
+};
+
+const titleStyle = {
+ textAlign: 'center',
+ marginBottom: '0.5rem',
+ color: '#333',
+};
+
+const subtitleStyle = {
+ textAlign: 'center',
+ color: '#666',
+ marginBottom: '2rem',
+};
+
+const placeholderStyle = {
+ backgroundColor: '#f8f9fa',
+ padding: '1.5rem',
+ borderRadius: '5px',
+ marginBottom: '1rem',
+};
+
+const listStyle = {
+ paddingLeft: '1.5rem',
+ marginTop: '1rem',
+};
+
+const linkTextStyle = {
+ textAlign: 'center',
+ marginTop: '1rem',
+};
+
+const linkStyle = {
+ color: '#007bff',
+ textDecoration: 'none',
+ fontWeight: 'bold',
+};
+
+export default Login;
\ No newline at end of file
diff --git a/client/src/pages/Register.jsx b/client/src/pages/Register.jsx
new file mode 100644
index 0000000..8d6494c
--- /dev/null
+++ b/client/src/pages/Register.jsx
@@ -0,0 +1,88 @@
+import { Link } from 'react-router-dom';
+
+const Register = () => {
+ return (
+
+
+
Create Account
+
Join {/* Your Platform Name */} today
+
+ {/* Placeholder for registration form */}
+
+
Registration form will be implemented in a future lesson
+
This will include:
+
+ - Name input field
+ - Email input field
+ - Password input field
+ - Confirm password field
+ - Registration button
+ - Form validation
+
+
+
+
+ Already have an account?{' '}
+
+ Login here
+
+
+
+
+ );
+};
+
+// Use the same styles as Login page
+const containerStyle = {
+ minHeight: '80vh',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: '2rem',
+};
+
+const formContainerStyle = {
+ maxWidth: '400px',
+ width: '100%',
+ padding: '2rem',
+ backgroundColor: 'white',
+ borderRadius: '8px',
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
+};
+
+const titleStyle = {
+ textAlign: 'center',
+ marginBottom: '0.5rem',
+ color: '#333',
+};
+
+const subtitleStyle = {
+ textAlign: 'center',
+ color: '#666',
+ marginBottom: '2rem',
+};
+
+const placeholderStyle = {
+ backgroundColor: '#f8f9fa',
+ padding: '1.5rem',
+ borderRadius: '5px',
+ marginBottom: '1rem',
+};
+
+const listStyle = {
+ paddingLeft: '1.5rem',
+ marginTop: '1rem',
+};
+
+const linkTextStyle = {
+ textAlign: 'center',
+ marginTop: '1rem',
+};
+
+const linkStyle = {
+ color: '#007bff',
+ textDecoration: 'none',
+ fontWeight: 'bold',
+};
+
+export default Register;
\ No newline at end of file