Skip to main content

Command Palette

Search for a command to run...

DOVE CG Tech frontend

Published
14 min read
E

Ekemini Thompson is a Machine Learning Engineer and Data Scientist, specializing in AI solutions, predictive analytics, and healthcare innovations, with a passion for leveraging technology to solve real-world problems.

Step-by-Step Instructions for Beginners

  1. Open Your Project:

    • Open VS Code.

    • Click File > Open Folder and select your dove-cg-tech folder.

    • In the file explorer (left side), open the frontend folder to see public and src.

  2. Create New Folders:

    • In frontend/src, right-click src, select New Folder, and create:

      • api

      • context

      • hooks

      • redux

      • utils

      • Inside components, create: auth, company, courses, payments, dashboard, certificates

      • Inside pages, create: company, courses, dashboard, payments, certificates, cart

      • Inside redux, create: slices

    • In frontend/public, right-click public, select New Folder, and create assets.

    • Inside assets, create: images, fonts.

  3. Create/Update Files:

    • For each file below, navigate to the specified folder in the file explorer.

    • To create a file: Right-click the folder, select New File, name it exactly as shown, paste the code, and save (Ctrl+S or Cmd+S).

    • To update a file: Open the existing file, replace its content with the provided code, and save.

  4. Install New Dependencies:

    • Open a terminal in VS Code (Terminal > New Terminal).

    • Ensure you’re in the frontend folder (type cd frontend if needed).

    • Run: npm install @reduxjs/toolkit react-redux

    • Verify existing dependencies (react, react-dom, react-router-dom@6, axios, @mui/material, @mui/icons-material, @emotion/react, @emotion/styled, framer-motion) are installed. If not, run:
      npm install react react-dom react-router-dom@6 axios @mui/material @mui/icons-material @emotion/react @emotion/styled framer-motion

    • Test Your Website:

      • In the terminal, type: npm start
    • Your browser should open to http://localhost:3000.

    • Check the navbar, home page, login/register pages, and try a wrong URL (e.g., /random) to see the 404 page.

    • If errors appear, check the terminal or browser console (right-click page > Inspect > Console).

Code Files

1. Update public/index.html

Location: frontend/public/index.html Purpose: Sets up the webpage with a dark background and root div for React.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="theme-color" content="#121212" />
  <meta name="description" content="DOVE CG Tech - Corporate eLearning Platform" />
  <title>DOVE CG Tech</title>
</head>
<body style="background-color: #121212; margin: 0;">
  <div id="root"></div>
</body>
</html>

How to Update:

  • Open frontend/public/index.html in the file explorer.

  • Replace its content with the code above.

  • Save.


2. Update src/styles/global.css

Location: frontend/src/styles/global.css Purpose: Defines the black, green, and yellow color scheme.

:root {
  --black-primary: #121212;
  --black-secondary: #1A1A1A;
  --green-primary: #00FF7F;
  --green-secondary: #2ECC71;
  --yellow-primary: #FFD700;
  --yellow-secondary: #F1C40F;
  --text-light: #E0E0E0;
  --text-muted: #AAAAAA;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: var(--black-primary);
  color: var(--text-light);
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

a {
  text-decoration: none;
  color: var(--green-primary);
}

button {
  cursor: pointer;
}

How to Update:

  • Open frontend/src/styles/global.css.

  • Replace its content with the code above.

  • Save.


3. Update src/components/ui/Navbar.js

Location: frontend/src/components/ui/Navbar.js Purpose: Navigation bar with dynamic buttons based on auth state, using the new MUI theme and auth hook.

import React from 'react';
import { AppBar, Toolbar, Typography, Button, Box } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../hooks/useAuth';

const StyledAppBar = styled(AppBar)(({ theme }) => ({
  backgroundColor: theme.palette.background.paper,
  color: theme.palette.primary.main,
}));

const NavButton = styled(Button)(({ theme }) => ({
  color: theme.palette.text.primary,
  '&:hover': {
    color: theme.palette.primary.main,
    backgroundColor: 'rgba(0, 255, 127, 0.1)',
  },
}));

const Navbar = () => {
  const { user, logout } = useAuth();
  const navigate = useNavigate();

  return (
    <StyledAppBar position="static">
      <Toolbar>
        <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
          DOVE CG Tech
        </Typography>
        <Box>
          <NavButton onClick={() => navigate('/')}>Home</NavButton>
          <NavButton onClick={() => navigate('/courses')}>Courses</NavButton>
          <NavButton onClick={() => navigate('/company')}>Company</NavButton>
          {user ? (
            <>
              <NavButton onClick={() => navigate('/dashboard')}>Dashboard</NavButton>
              <NavButton onClick={() => { logout(); navigate('/'); }}>Logout</NavButton>
            </>
          ) : (
            <>
              <NavButton onClick={() => navigate('/login')}>Login</NavButton>
              <NavButton
                variant="contained"
                onClick={() => navigate('/register')}
                sx={{
                  backgroundColor: 'var(--green-primary)',
                  color: 'var(--black-primary)',
                  '&:hover': { backgroundColor: 'var(--green-secondary)' },
                }}
              >
                Sign Up
              </NavButton>
            </>
          )}
        </Box>
      </Toolbar>
    </StyledAppBar>
  );
};

export default Navbar;

How to Update:

  • Open frontend/src/components/ui/Navbar.js.

  • Replace its content with the code above.

  • Save.


4. Update src/components/ui/Footer.js

Location: frontend/src/components/ui/Footer.js Purpose: Footer with links and copyright, styled with the new theme.

import React from 'react';
import { Box, Typography, Container, Link } from '@mui/material';
import { styled } from '@mui/material/styles';

const FooterContainer = styled(Box)({
  backgroundColor: 'var(--black-secondary)',
  color: 'var(--text-light)',
  padding: '20px 0',
  marginTop: 'auto',
  borderTop: '1px solid var(--green-primary)',
});

const Footer = () => {
  return (
    <FooterContainer component="footer">
      <Container maxWidth="lg">
        <Box
          sx={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            flexWrap: 'wrap',
            gap: 2,
          }}
        >
          <Typography variant="body2">
            © {new Date().getFullYear()} DOVE CG Tech. All rights reserved.
          </Typography>
          <Box sx={{ display: 'flex', gap: 2 }}>
            <Link
              href="/about"
              sx={{
                color: 'var(--green-primary)',
                '&:hover': { color: 'var(--yellow-primary)' },
              }}
            >
              About
            </Link>
            <Link
              href="/contact"
              sx={{
                color: 'var(--green-primary)',
                '&:hover': { color: 'var(--yellow-primary)' },
              }}
            >
              Contact
            </Link>
            <Link
              href="/privacy"
              sx={{
                color: 'var(--green-primary)',
                '&:hover': { color: 'var(--yellow-primary)' },
              }}
            >
              Privacy Policy
            </Link>
          </Box>
        </Box>
      </Container>
    </FooterContainer>
  );
};

export default Footer;

How to Update:

  • Open frontend/src/components/ui/Footer.js.

  • Replace its content with the code above.

  • Save.


5. Update src/pages/Home.js

Location: frontend/src/pages/Home.js Purpose: Home page with a hero section, updated to use the MUI theme.

import React from 'react';
import { Box, Typography, Button, Container } from '@mui/material';
import { styled } from '@mui/material/styles';

const HeroSection = styled(Box)(({ theme }) => ({
  minHeight: '80vh',
  background: 'linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url(/assets/hero-bg.jpg)',
  backgroundSize: 'cover',
  backgroundPosition: 'center',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  textAlign: 'center',
  color: theme.palette.text.primary,
}));

const Home = () => {
  return (
    <HeroSection>
      <Container maxWidth="md">
        <Typography variant="h2" component="h1" gutterBottom sx={{ fontWeight: 'bold', color: 'var(--green-primary)' }}>
          Transform Your Workforce with DOVE CG Tech
        </Typography>
        <Typography variant="h5" component="p" gutterBottom sx={{ mb: 4 }}>
          Cutting-edge eLearning solutions for corporate excellence
        </Typography>
        <Button 
          variant="contained" 
          size="large"
          sx={{
            bgcolor: 'var(--green-primary)',
            color: 'var(--black-primary)',
            fontWeight: 'bold',
            px: 4,
            py: 2,
            '&:hover': {
              bgcolor: 'var(--green-secondary)',
              boxShadow: '0 0 15px var(--yellow-primary)',
            }
          }}
        >
          Explore Courses
        </Button>
      </Container>
    </HeroSection>
  );
};

export default Home;

How to Update:

  • Open frontend/src/pages/Home.js.

  • Replace its content with the code above.

  • Save.


6. Update src/pages/auth/Client/Login.js

Location: frontend/src/pages/auth/Client/Login.js Purpose: Login page with API integration and auth context.

import React, { useState } from 'react';
import { Box, Typography, TextField, Button, Container, CircularProgress } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../../hooks/useAuth';
import { login } from '../../../api/auth';

const LoginContainer = styled(Box)({
  minHeight: '80vh',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  padding: '20px',
});

const LoginForm = styled(Box)(({ theme }) => ({
  backgroundColor: theme.palette.background.paper,
  padding: '40px',
  borderRadius: '8px',
  boxShadow: `0 0 10px ${theme.palette.primary.main}`,
  width: '100%',
  maxWidth: '400px',
}));

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);
  const { login: authLogin } = useAuth();
  const navigate = useNavigate();

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    try {
      const data = await login(email, password);
      authLogin(email, data.token);
      navigate('/dashboard');
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  };

  return (
    <LoginContainer>
      <Container maxWidth="sm">
        <LoginForm component="form" onSubmit={handleSubmit}>
          <Typography
            variant="h4"
            component="h1"
            gutterBottom
            sx={{ color: 'var(--green-primary)', textAlign: 'center' }}
          >
            Login
          </Typography>
          {error && (
            <Typography color="error" sx={{ mb: 2, textAlign: 'center' }}>
              {error}
            </Typography>
          )}
          <TextField
            label="Email"
            variant="outlined"
            fullWidth
            margin="normal"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            sx={{ '& .MuiInputLabel-root': { color: 'var(--text-muted)' } }}
          />
          <TextField
            label="Password"
            type="password"
            variant="outlined"
            fullWidth
            margin="normal"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            sx={{ '& .MuiInputLabel-root': { color: 'var(--text-muted)' } }}
          />
          <Button
            variant="contained"
            fullWidth
            type="submit"
            disabled={loading}
            sx={{
              mt: 2,
              py: 1.5,
              bgcolor: 'var(--green-primary)',
              color: 'var(--black-primary)',
              '&:hover': { bgcolor: 'var(--green-secondary)' },
            }}
          >
            {loading ? <CircularProgress size={24} color="inherit" /> : 'Sign In'}
          </Button>
        </LoginForm>
      </Container>
    </LoginContainer>
  );
};

export default Login;

How to Update:

  • Open frontend/src/pages/auth/Client/Login.js.

  • Replace its content with the code above.

  • Save.


7. Update src/pages/auth/Client/Register.js

Location: frontend/src/pages/auth/Client/Register.js Purpose: Registration page with API integration.

import React, { useState } from 'react';
import { Box, Typography, TextField, Button, Container, CircularProgress } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../../hooks/useAuth';
import { register } from '../../../api/auth';

const RegisterContainer = styled(Box)({
  minHeight: '80vh',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  padding: '20px',
});

const RegisterForm = styled(Box)(({ theme }) => ({
  backgroundColor: theme.palette.background.paper,
  padding: '40px',
  borderRadius: '8px',
  boxShadow: `0 0 10px ${theme.palette.primary.main}`,
  width: '100%',
  maxWidth: '400px',
}));

const Register = () => {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);
  const { login: authLogin } = useAuth();
  const navigate = useNavigate();

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    try {
      const data = await register(name, email, password);
      authLogin(email, data.token);
      navigate('/dashboard');
    } catch (err) {
      setError(err);
    } finally {
      setLoading(false);
    }
  };

  return (
    <RegisterContainer>
      <Container maxWidth="sm">
        <RegisterForm component="form" onSubmit={handleSubmit}>
          <Typography
            variant="h4"
            component="h1"
            gutterBottom
            sx={{ color: 'var(--green-primary)', textAlign: 'center' }}
          >
            Register
          </Typography>
          {error && (
            <Typography color="error" sx={{ mb: 2, textAlign: 'center' }}>
              {error}
            </Typography>
          )}
          <TextField
            label="Full Name"
            variant="outlined"
            fullWidth
            margin="normal"
            value={name}
            onChange={(e) => setName(e.target.value)}
            sx={{ '& .MuiInputLabel-root': { color: 'var(--text-muted)' } }}
          />
          <TextField
            label="Email"
            variant="outlined"
            fullWidth
            margin="normal"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            sx={{ '& .MuiInputLabel-root': { color: 'var(--text-muted)' } }}
          />
          <TextField
            label="Password"
            type="password"
            variant="outlined"
            fullWidth
            margin="normal"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            sx={{ '& .MuiInputLabel-root': { color: 'var(--text-muted)' } }}
          />
          <Button
            variant="contained"
            fullWidth
            type="submit"
            disabled={loading}
            sx={{
              mt: 2,
              py: 1.5,
              bgcolor: 'var(--green-primary)',
              color: 'var(--black-primary)',
              '&:hover': { bgcolor: 'var(--green-secondary)' },
            }}
          >
            {loading ? <CircularProgress size={24} color="inherit" /> : 'Sign Up'}
          </Button>
        </RegisterForm>
      </Container>
    </RegisterContainer>
  );
};

export default Register;

How to Update:

  • Open frontend/src/pages/auth/Client/Register.js.

  • Replace its content with the code above.

  • Save.


8. Update src/App.js

Location: frontend/src/App.js Purpose: Main app structure with Redux, MUI theme, and new routes.

import React from 'react';
import { Provider } from 'react-redux';
import { ThemeProvider } from '@mui/material/styles';
import { AuthProvider } from './context/authContext';
import store from './redux/store';
import theme from './styles/theme';
import AppRoutes from './routes';
import Navbar from './components/ui/Navbar';
import Footer from './components/ui/Footer';
import './styles/global.css';

function App() {
  return (
    <Provider store={store}>
      <ThemeProvider theme={theme}>
        <AuthProvider>
          <div className="app" style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column' }}>
            <Navbar />
            <main style={{ flex: 1 }}>
              <AppRoutes />
            </main>
            <Footer />
          </div>
        </AuthProvider>
      </ThemeProvider>
    </Provider>
  );
}

export default App;

How to Update:

  • Open frontend/src/App.js.

  • Replace its content with the code above.

  • Save.


9. Update src/index.js

Location: frontend/src/index.js Purpose: Renders the app with React 18’s createRoot.

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

How to Update:

  • Open frontend/src/index.js.

  • Replace its content with the code above.

  • Save.


10. Create src/api/auth.js

Location: frontend/src/api/auth.js Purpose: Handles API calls for login and registration.

import axios from 'axios';

const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:5000/api';

export const login = async (email, password) => {
  try {
    const response = await axios.post(`${API_URL}/auth/login`, { email, password });
    return response.data;
  } catch (error) {
    throw error.response?.data?.message || 'Login failed';
  }
};

export const register = async (name, email, password) => {
  try {
    const response = await axios.post(`${API_URL}/auth/register`, { name, email, password });
    return response.data;
  } catch (error) {
    throw error.response?.data?.message || 'Registration failed';
  }
};

How to Create:

  • In frontend/src/api, right-click, select New File, name it auth.js.

  • Paste the code above.

  • Save.


11. Create src/context/authContext.js

Location: frontend/src/context/authContext.js Purpose: Manages user authentication state.

import React, { createContext, useState, useEffect } from 'react';

export const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const token = localStorage.getItem('token');
    if (token) {
      setUser({ token });
    }
    setLoading(false);
  }, []);

  const login = async (email, password) => {
    // Use api/auth.js login function
    setUser({ email, token: 'dummy-token' });
    localStorage.setItem('token', 'dummy-token');
  };

  const logout = () => {
    setUser(null);
    localStorage.removeItem('token');
  };

  return (
    <AuthContext.Provider value={{ user, loading, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

How to Create:

  • In frontend/src/context, right-click, select New File, name it authContext.js.

  • Paste the code above.

  • Save.


12. Create src/hooks/useAuth.js

Location: frontend/src/hooks/useAuth.js Purpose: Custom hook to access auth context.

import { useContext } from 'react';
import { AuthContext } from '../context/authContext';

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

How to Create:

  • In frontend/src/hooks, right-click, select New File, name it useAuth.js.

  • Paste the code above.

  • Save.


13. Create src/styles/theme.js

Location: frontend/src/styles/theme.js Purpose: MUI theme with black, green, yellow colors.

import { createTheme } from '@mui/material/styles';

const theme = createTheme({
  palette: {
    primary: {
      main: '#00FF7F', // Green
    },
    secondary: {
      main: '#FFD700', // Yellow
    },
    background: {
      default: '#121212', // Black
      paper: '#1A1A1A', // Darker black
    },
    text: {
      primary: '#E0E0E0', // Light text
      secondary: '#AAAAAA', // Muted text
    },
  },
  typography: {
    fontFamily: "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif",
  },
});

export default theme;

How to Create:

  • In frontend/src/styles, right-click, select New File, name it theme.js.

  • Paste the code above.

  • Save.


14. Create src/routes.js

Location: frontend/src/routes.js Purpose: Centralizes routing configuration.

import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import Login from './pages/auth/Client/Login';
import Register from './pages/auth/Client/Register';
import NotFound from './pages/404';

const AppRoutes = () => (
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/login" element={<Login />} />
    <Route path="/register" element={<Register />} />
    <Route path="*" element={<NotFound />} />
  </Routes>
);

export default AppRoutes;

How to Create:

  • In frontend/src, right-click, select New File, name it routes.js.

  • Paste the code above.

  • Save.


15. Create src/pages/404.js

Location: frontend/src/pages/404.js Purpose: Displays a "Page Not Found" page.

import React from 'react';
import { Box, Typography, Button, Container } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useNavigate } from 'react-router-dom';

const NotFoundContainer = styled(Box)({
  minHeight: '80vh',
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  textAlign: 'center',
  color: 'var(--text-light)',
});

const NotFound = () => {
  const navigate = useNavigate();

  return (
    <NotFoundContainer>
      <Container maxWidth="sm">
        <Typography variant="h1" sx={{ color: 'var(--green-primary)', fontWeight: 'bold' }}>
          404
        </Typography>
        <Typography variant="h5" gutterBottom>
          Page Not Found
        </Typography>
        <Typography variant="body1" sx={{ mb: 4 }}>
          Sorry, the page you're looking for doesn't exist.
        </Typography>
        <Button
          variant="contained"
          onClick={() => navigate('/')}
          sx={{
            bgcolor: 'var(--green-primary)',
            color: 'var(--black-primary)',
            '&:hover': { bgcolor: 'var(--green-secondary)' },
          }}
        >
          Go Home
        </Button>
      </Container>
    </NotFoundContainer>
  );
};

export default NotFound;

How to Create:

  • In frontend/src/pages, right-click, select New File, name it 404.js.

  • Paste the code above.

  • Save.


16. Create src/redux/store.js

Location: frontend/src/redux/store.js Purpose: Sets up Redux store for state management.

import { configureStore } from '@reduxjs/toolkit';
import authReducer from './slices/authSlice';
import courseReducer from './slices/courseSlice';

const store = configureStore({
  reducer: {
    auth: authReducer,
    courses: courseReducer,
  },
});

export default store;

How to Create:

  • In frontend/src/redux, right-click, select New File, name it store.js.

  • Paste the code above.

  • Save.


17. Create src/redux/slices/authSlice.js

Location: frontend/src/redux/slices/authSlice.js Purpose: Manages authentication state in Redux.

import { createSlice } from '@reduxjs/toolkit';

const authSlice = createSlice({
  name: 'auth',
  initialState: {
    user: null,
    token: null,
    isAuthenticated: false,
  },
  reducers: {
    setUser: (state, action) => {
      state.user = action.payload.user;
      state.token = action.payload.token;
      state.isAuthenticated: true;
    },
    clearUser: (state) => {
      state.user = null;
      state.token = null;
      state.isAuthenticated = false;
    },
  },
});

export const { setUser, clearUser } = authSlice.actions;
export default authSlice.reducer;

How to Create:

  • In frontend/src/redux/slices, right-click, select New File, name it authSlice.js.

  • Paste the code above.

  • Save.


18. Create src/redux/slices/courseSlice.js

Location: frontend/src/redux/slices/courseSlice.js Purpose: Placeholder for course state management (required by store.js).

import { createSlice } from '@reduxjs/toolkit';

const courseSlice = createSlice({
  name: 'courses',
  initialState: {
    courses: [],
  },
  reducers: {
    setCourses: (state, action) => {
      state.courses = action.payload;
    },
  },
});

export const { setCourses } = courseSlice.actions;
export default courseSlice.reducer;

How to Create:

  • In frontend/src/redux/slices, right-click, select New File, name it courseSlice.js.

  • Paste the code above.

  • Save.


19. Create src/utils/constants.js

Location: frontend/src/utils/constants.js Purpose: Stores shared constants like colors and API URL.

export const COLORS = {
  BLACK_PRIMARY: '#121212',
  BLACK_SECONDARY: '#1A1A1A',
  GREEN_PRIMARY: '#00FF7F',
  GREEN_SECONDARY: '#2ECC71',
  YELLOW_PRIMARY: '#FFD700',
  YELLOW_SECONDARY: '#F1C40F',
  TEXT_LIGHT: '#E0E0E0',
  TEXT_MUTED: '#AAAAAA',
};

export const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:5000/api';

How to Create:

  • In frontend/src/utils, right-click, select New File, name it constants.js.

  • Paste the code above.

  • Save.


Notes for Beginners

  • Folder Structure:

    • Your frontend/src should now have:

      • styles/global.css, styles/theme.js

      • components/ui/Navbar.js, components/ui/Footer.js

      • pages/Home.js, pages/404.js, pages/auth/Client/Login.js, pages/auth/Client/Register.js

      • api/auth.js

      • context/authContext.js

      • hooks/useAuth.js

      • redux/store.js, redux/slices/authSlice.js, redux/slices/courseSlice.js

      • utils/constants.js

      • App.js, index.js, routes.js

  • What’s Missing:

    • Files like courses.js, cartContext.js, useCart.js, etc., weren’t created as they’re not critical for the initial setup. You can add them later.

    • The Login.js and Register.js files assume a backend API at http://localhost:5000/api. Update API_URL in constants.js if your backend is different.

  • Testing:

    • Run npm start to check the site.

    • Test navigation (Home, Login, Register, 404 page).

    • The Navbar should show “Dashboard” and “Logout” when logged in (currently uses a dummy token).

  • Errors:

    • If you see errors, check:

      • File names and paths are exact (case-sensitive).

      • All dependencies are installed.

      • Save all files.

    • Check the terminal or browser console for details.

  • Tips:

    • Save often (Ctrl+S or Cmd+S).

    • The Home.js file references /assets/hero-bg.jpg. Add an image to frontend/public/assets/images or remove the background line if not needed.

    • Have fun! You’re building a real website!

If you need additional files (e.g., courses.js, cartContext.js) or run into errors, let me know, and I’ll provide the code or help troubleshoot!