Skip to content

Frontend Development Documentation

Aniekan Winner Anietie edited this page Mar 13, 2025 · 1 revision

This document outlines how to structure and build the Schooltracker frontend. Follow these guidelines to ensure consistency across components, routes, API calls, and utility functions.


1. Folder Structure

Organize the frontend code in a clear, modular manner. Below is a recommended folder structure:

frontend/
├── public/
├── src/
│   ├── api/                    # API call functions and related logic
│   ├── components/             # Reusable UI components
│   │   └── SomeComponent/
│   │       ├── SomeComponent.tsx
│   │       └── props.ts        # Component props and types
│   ├── constants/              # All constants (routes, endpoints, etc.)
│   │   ├── Routes.ts           # Application route constants
│   │   └── Endpoints.ts        # API endpoints constants
│   ├── interfaces/             # General interface files (e.g., modal interfaces)
│   │   └── ModalProps.ts       # Modal-specific types
│   ├── contexts/               # Global state contexts
│   ├── hooks/                  # Custom hooks
│   ├── pages/                  # Page-level components
│   ├── utilities/              # Utility functions (formatters, helpers, etc.)
│   ├── App.tsx
│   ├── main.tsx
│   └── index.css
├── .env
├── package.json
└── tsconfig.json

2. Routing

All routes must be centralized in the constants/Routes.ts file. This file will contain a single exported object that holds all the paths for the application.

Example: src/constants/Routes.ts

/**
 * This file contains constants for all of the routes in the app
 */
export const ROUTES = {
  App: {
    main: "/",
  },
  Home: {
    main: "/home",
  },
  Dashboard: {
    main: "/dashboard",
  },
  // Add additional routes here...
};

Use these route constants throughout your application when defining React Router paths and linking between pages.


3. API Endpoints

Store all API endpoint constants in a single file: constants/Endpoints.ts. This file should define base URLs using environment variables and create a structured object for each feature’s endpoints.

Example: src/constants/Endpoints.ts

const BASE_URL = import.meta.env.VITE_BASE_URL;
const AUTH_URL = import.meta.env.VITE_BASE_AUTH_URL;

const endpoints = {
  Auth: {
    getLoginOtp: AUTH_URL + "/auth/login/otp",
    verifyOtp: AUTH_URL + "/auth/verify/otp",
    getRegisterOtp: AUTH_URL + "/auth/register/otp",
  },
  SchoolTrackerUser: {
    main: BASE_URL + "/schooltracker/users",
    getApplications: BASE_URL + "/schooltracker/users/applications",
  },
  // Add more endpoint groups as needed...
};

export { endpoints, BASE_URL };

4. API Calls

All API call functions should be encapsulated in files located in the api/ directory. For example, you might have files like api/auth.ts or api/schoolTracker.ts that import the relevant endpoints from the constants file and use Axios (or another HTTP client) to perform calls.

Example: src/api/auth.ts

import axios from 'axios';
import { endpoints } from '../constants/Endpoints';

export const sendLoginOtp = async (email: string) => {
  try {
    const response = await axios.post(endpoints.Auth.getLoginOtp, { email });
    return response.data;
  } catch (error) {
    throw error;
  }
};

// Additional API functions for auth...

This approach keeps all API interactions centralized and easier to maintain.


5. Component Types

For each React component, define its props and types in a separate props.ts file located within the component's directory. This ensures that the component’s API is clearly documented and maintainable.

Example: src/components/SomeComponent/props.ts

export interface SomeComponentProps {
  title: string;
  onClick: () => void;
  // Add additional props as needed...
}

Then import these types in your component file:

// src/components/SomeComponent/SomeComponent.tsx
import React from 'react';
import { SomeComponentProps } from './props';

const SomeComponent: React.FC<SomeComponentProps> = ({ title, onClick }) => {
  return (
    <div onClick={onClick}>
      <h1>{title}</h1>
    </div>
  );
};

export default SomeComponent;

6. Modal & Other Shared Interfaces

For interfaces that are shared across multiple components—such as modal properties—create a separate file in the interfaces/ directory.

Example: src/interfaces/ModalProps.ts

export interface ModalProps {
  isOpen: boolean;
  title?: string;
  content: React.ReactNode;
  onClose: () => void;
}

Components that use modals can import these shared types to ensure consistency.


7. Utilities

General utility functions and helper methods should be placed in the utilities/ directory. These might include formatting functions, date manipulation utilities, or other reusable logic.

Example: src/utilities/formatDate.ts

export const formatDate = (dateString: string): string => {
  const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric' };
  return new Date(dateString).toLocaleDateString(undefined, options);
};

Any constant values that do not fit into routes or endpoints should also be stored in the constants/ directory.


8. Final Notes

  • Consistency: Always use the constants from Routes.ts and Endpoints.ts to avoid hardcoding URLs or paths across your project.
  • Separation of Concerns: Keep API calls, component logic, types, and utilities in their respective directories to maintain a modular and scalable codebase.
  • Documentation: Comment your code you build. This ensures team members can quickly understand the structure.