Preskool Banner

Introduction

Preskool is a simple and easy-to-access management dashboard for education, including schools, colleges, and universities.

Requirement

Technologies
  • React 19.2
  • TypeScript 5.9
  • Vite 6.3 (build tool & dev server)
  • Bootstrap 5.3 + SCSS
  • React Router 7.9
  • Redux Toolkit 2.12
System Requirements
  • Node.js version >= 18 (LTS 20+ recommended)
  • npm version >= 9 (ships with Node.js)
  • Yarn package (Optional)
  • Visual Studio Code
  • Terminal
  • A modern browser — Chrome, Edge, Firefox or Safari

Core Features

– Built with React 19 and TypeScript on Vite 6
– 400+ ready-made pages grouped by module
– Role based dashboards — Admin, Teacher, Student and Parent
– Academic, HRM, Finance, Attendance, Library, Transport, Hostel, Communication and Settings modules
– Hooks based architecture with reusable custom hooks
– Route level code splitting with React.lazy and Suspense
– Central route registry — one named key per path
– Redux Toolkit store with theme settings persisted to localStorage
– Service layer that switches between mock data and a real REST API
– Light / Dark theme and four layout modes — default, mini, boxed and RTL
– Path aliases for clean imports
– Organised SCSS architecture
– Fully responsive design
– Cross browser compatible
– Clean and well commented code
– Easy to customize
– Developer friendly
– And many more...

File Structure

Project Overview

The project follows a modular structure with clear separation of concerns. Page UI lives in views/, template internals in core/, and data access in services/.

preskool/
│
└── react/
    │
    ├── public/
    │   ├── assets/                 # images, fonts and static files
    │   └── favicon.png
    │
    ├── src/
    │   ├── app/
    │   │   └── providers/          # AppProviders, AuthProvider, auth-context
    │   │
    │   ├── components/
    │   │   ├── routing/            # ProtectedRoute, RoleGuard
    │   │   ├── ui/                 # shared presentational components
    │   │   └── workspace/
    │   │
    │   ├── config/                 # env.ts — the only reader of import.meta.env
    │   ├── constants/
    │   │
    │   ├── core/
    │   │   ├── common/             # header, sidebar, modals, theme-settings
    │   │   ├── data/               # redux store, slices and menu JSON
    │   │   └── modals/
    │   │
    │   ├── features/               # feature hooks — auth, dashboard, students
    │   ├── hooks/                  # useForm, useQuery, useToasts, …
    │   ├── layouts/                # MainLayout.tsx, AuthLayout.tsx
    │   ├── mocks/                  # static fixtures returned by mock services
    │   │
    │   ├── routes/
    │   │   ├── all_routes.tsx      # every path as a named key
    │   │   ├── route_config.tsx    # lazy imports + route arrays
    │   │   └── index.tsx           # the <Routes> tree
    │   │
    │   ├── services/               # api/, auth/, dashboard/, students/
    │   ├── style/
    │   │   ├── css/
    │   │   ├── fonts/
    │   │   ├── icon/
    │   │   └── scss/
    │   ├── types/
    │   ├── utils/
    │   ├── views/                  # every page's UI, grouped by module
    │   │
    │   ├── environment.tsx         # base_path and img_path
    │   ├── index.scss
    │   └── main.tsx                # application entry point
    │
    ├── eslint.config.js
    ├── index.html
    ├── package.json
    ├── package-lock.json
    ├── tsconfig.json
    ├── tsconfig.app.json
    ├── tsconfig.node.json
    └── vite.config.ts
									

React Structure

Structure Overview

PreSkool React is built with React 19, TypeScript and Vite. main.tsx mounts the app, AppProviders supplies the Redux store and the auth session, and ALLRoutes renders every page inside one of the two layouts.

The structure follows a clear top-down flow:

  • Entry pointsrc/main.tsx imports global CSS and mounts the app inside BrowserRouter
  • Providerssrc/app/providers/AppProviders.tsx composes the Redux store and the auth context
  • LayoutsMainLayout wraps the app pages (header, sidebar, theme settings), AuthLayout wraps the bare login and error screens
  • Viewssrc/views/ holds every page's UI, grouped by module (academic, hrm, finance-accounts, peoples …)
  • Servicessrc/services/ is the only place that talks to data, so views stay presentational
Entry Point — src/main.tsx:
import React from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router";

import { base_path } from "./environment";
import AppProviders from "./app/providers/AppProviders";
import ALLRoutes from "./routes";

import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import "../src/style/css/feather.css";
import "../src/index.scss";
import "bootstrap";

createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    {/* AppProviders composes the Redux store and the auth session provider. */}
    <AppProviders>
      <BrowserRouter basename={base_path}>
        <ALLRoutes />
      </BrowserRouter>
    </AppProviders>
  </React.StrictMode>
);
Route Tree — src/routes/index.tsx:
import React, { Suspense } from "react";
import { Route, Routes } from "react-router";

import { authRoutes, publicRoutes } from "./route_config";
import MainLayout from "../layouts/MainLayout";
import AuthLayout from "../layouts/AuthLayout";
import ProtectedRoute from "@components/routing/ProtectedRoute";

const Login = React.lazy(() => import("../views/auth/login/login"));

const ALLRoutes: React.FC = () => (
  <Suspense fallback={<div>Loading...</div>}>
    <Routes>
      <Route path="/" element={<Login />} />

      {/* ProtectedRoute is a pass-through while VITE_AUTH_ENABLED is false. */}
      <Route element={<ProtectedRoute />}>
        <Route element={<MainLayout />}>
          {publicRoutes.map((route, idx) => (
            <Route path={route.path} element={route.element} key={idx} />
          ))}
        </Route>
      </Route>

      <Route element={<AuthLayout />}>
        {authRoutes.map((route, idx) => (
          <Route path={route.path} element={route.element} key={idx} />
        ))}
      </Route>
    </Routes>
  </Suspense>
);

export default ALLRoutes;
Sample View — src/views/…/index.tsx:
import { Link } from "react-router-dom";
import { all_routes } from "@/routes/all_routes";
import { useQuery } from "@hooks";
import { studentsService } from "@services/students";

const StudentList = () => {
  const routes = all_routes;
  const { data: students, loading, error } = useQuery(() => studentsService.list());

  if (loading) return <div className="p-4">Loading...</div>;
  if (error) return <div className="p-4 text-danger">{error.message}</div>;

  return (
    <div className="page-wrapper">
      <div className="content">
        <h4 className="mb-3">Students</h4>
        <div className="row">
          {students?.map((student) => (
            <div className="col-xxl-3 col-xl-4 col-md-6" key={student.id}>
              <div className="card">
                <div className="card-body">
                  <h6>
                    <Link to={routes.studentDetails}>{student.name}</Link>
                  </h6>
                  <p className="mb-0">{student.email}</p>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

export default StudentList;
Note

Images are rendered through <ImageWithBasePath> (src/core/common/imageWithBasePath). It prefixes img_path from src/environment.tsx so assets resolve correctly under the Vite base.

React Scripts

Scripts Overview

The PreSkool React template uses Vite as the build tool. These are the only four scripts you need for development, linting and production builds.

You can find the scripts in the package.json file. Here are the available commands:

Command Description
npm run dev Starts the Vite development server with hot module replacement on http://localhost:5173/react
npm run build Type-checks the project with tsc -b, then bundles it for production into dist/
npm run preview Serves the last production build locally so you can verify it before deploying
npm run lint Runs ESLint across the project using the flat config in eslint.config.js
Package.json Scripts Section:
"scripts": {
  "dev": "vite",
  "build": "tsc -b && vite build",
  "lint": "eslint .",
  "preview": "vite preview"
}

Installation Guide

After unzipping the template files, you will find our product Preskool -> react (Source code)
Node.js (18 or above) and npm are required to run the React project

Open a terminal in the react folder and install the dependencies:

npm install (or) npm install --legacy-peer-deps

To run the project in development mode, run the command:

npm run dev

The application starts on http://localhost:5173/react. The /react prefix comes from the base option in vite.config.ts — change it there if you deploy to a different path.

If you want to make a build in production mode, run the following command in the root directory, otherwise the project will continue to run in the development mode.

npm run build

The build output is written to the dist/ folder. To check that build locally before deploying, run:

npm run preview

To install any plugins in your application, you have to run the following command

npm install plugin_name --save (or) npm install plugin_name --legacy-peer-deps
Deployment Note

Serve the contents of dist/ from any static host. Because routing happens on the client, the host must rewrite unknown paths back to index.html — otherwise refreshing a deep link returns a 404.

Path Aliases

Two Files, Kept In Sync

Aliases are declared twice — in compilerOptions.paths of tsconfig.app.json (for TypeScript) and in resolve.alias of vite.config.ts (for the bundler). If you add one, add it to both files.

Alias Target
@/*src/*
@app/*src/app/*
@views/*src/views/*
@components/*src/components/*
@core/*src/core/*
@layouts/*src/layouts/*
@features/*src/features/*
@mocks/*src/mocks/*
@hooks, @hooks/*src/hooks/*
@services, @services/*src/services/*
@config, @config/*src/config/*
@constants, @constants/*src/constants/*
@utils, @utils/*src/utils/*
@routes, @routes/*src/routes/*
Usage:
import { all_routes } from "@/routes/all_routes";
import ProtectedRoute from "@components/routing/ProtectedRoute";
import { useBootstrapTooltips } from "@hooks/useBootstrapTooltips";
import { studentsService } from "@services/students";

Routing

Routing uses React Router and is driven by two files inside src/routes/:

  • all_routes.tsx — every path as a named key. This is the single source of truth; always link with routes.studentList, never a raw string.
  • route_config.tsx — the lazy imports plus two arrays: publicRoutes (rendered inside MainLayout) and authRoutes (rendered inside AuthLayout).
Adding a New Page
Step What to do
1 Create the view under src/views/<module>/my-page/index.tsx
2 Add the path to src/routes/all_routes.tsx
3 Add a React.lazy import and a publicRoutes entry in src/routes/route_config.tsx
4 Link to it with routes.myPage
1. Register the path — all_routes.tsx:
export const all_routes = {
  // …existing paths
  myPage: "/my-page",
};
2. Register the route — route_config.tsx:
const MyPage = React.lazy(() => import("@views/module/my-page"));

export const publicRoutes = [
  // …existing routes
  {
    path: routes.myPage,
    element: <MyPage />,
    route: Route,
  },
];
3. Link to it:
import { Link } from "react-router-dom";
import { all_routes } from "@/routes/all_routes";

<Link to={all_routes.myPage}>My Page</Link>

API & Mock Data

Runs Without a Backend

The template ships with mock data enabled and authentication disabled, so it runs correctly with no .env file and no server.

Each domain folder in src/services/ follows the same four-file shape:

File Responsibility
<domain>.types.ts TypeScript types shared by both implementations
<domain>.mock.ts Resolves data from the fixtures in src/mocks/
<domain>.http.ts Real REST calls through the shared client
<domain>.service.ts Picks mock or HTTP via createService

createService (src/services/api/create-service.ts) chooses the implementation from env.useMockApi, so call sites never change. All HTTP traffic goes through the single client in src/services/api/client.ts.

Connecting a Real Backend

Create a .env file in the react folder:

VITE_API_BASE_URL=https://api.example.com/v1
VITE_USE_MOCK_API=false
VITE_AUTH_ENABLED=true
Variable Default Description
VITE_APP_ENV development Environment label — development, staging or production
VITE_API_BASE_URL empty Base URL of the REST API
VITE_USE_MOCK_API true Resolve data from static mocks instead of HTTP
VITE_AUTH_ENABLED false Enforce authentication on protected routes

src/config/env.ts is the only module that reads import.meta.env. While VITE_AUTH_ENABLED is false, ProtectedRoute and RoleGuard render their children unconditionally, so every route stays reachable. Flip it to true once a real auth API is connected and the same components start enforcing the session.

Important Note : Every VITE_* value is inlined into the client bundle and is therefore public. Never put a secret or a private key in one.

Theme Settings

Theme state lives in Redux (src/core/data/redux/themeSettingSlice.tsx) and is persisted to localStorage. MainLayout mirrors that state onto the <html> element as data attributes, and the SCSS keys off them.

Attribute Values
data-theme light, dark
data-layout default, mini, boxed, rtl
data-sidebar light, dark, primary, darkblack, darkblue
data-sidebarbg default, sidebarbg1sidebarbg6
data-color primary, violet, pink, orange, green, red
data-topbar white, dark, primary, grey

All of these are switched at runtime from the gear panel in the header, which is implemented in src/core/common/theme-settings. Because the values are written to localStorage, the choice survives a page reload.

How can I switch to the Dark Mode?

Open the Theme Settings panel from the gear icon in the header and choose Dark under Mode. The selection is stored in localStorage, so it is remembered on the next visit.

To make dark mode the default for every new visitor instead, change the initial value in src/core/data/redux/themeSettingSlice.tsx:

const initialState = {
  // …
  dataTheme: localStorage.getItem("dataTheme") || "dark_data_theme",
  // …
};

MainLayout maps dark_data_theme to data-theme="dark" on the <html> element, which is what the SCSS reads.

How can I switch to the RTL?

Open the Theme Settings panel and pick the RTL layout. MainLayout then sets data-layout="rtl" on the <html> element and the template stylesheet flips the layout direction.

If you want the Bootstrap grid and utilities themselves mirrored as well, swap the Bootstrap stylesheet import in src/main.tsx for the RTL build:

// Replace this line
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";

// with this one
import "../node_modules/bootstrap/dist/css/bootstrap.rtl.min.css";

RTL-specific overrides used by the template live under the .layout-mode-rtl selector in src/index.scss.

How can I change the Font?

The template uses Inter. Changing it takes two edits.

1. Swap the import in src/style/scss/components/_font.scss:
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
2. Update the family stack in src/style/scss/utils/_variables.scss:
// Font Family
$font-family-primary: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

The base size and weight scale are declared in the same file ($font-size-base, $font-weight-medium and friends), so you can adjust typography globally from one place.

How can I change the Color?

Six preset accent colors ship with the template and can be switched at runtime from the Theme Settings panel — primary, violet, pink, orange, green and red.

To change the brand color itself, edit the theme variables in src/style/scss/utils/_variables.scss:

// Theme Colors Variables
$primary: #3D5EE1;
$secondary: #6FCCD8;
$success: #1ABE17;
$info: #0F65CD;
$warning: #EAB300;
$danger: #E82646;
$dark: #202C4B;
$light: #E9EDF4;

Hover shades are derived from these with color.adjust, so changing $primary updates $primary-hover automatically. Vite recompiles the SCSS as soon as you save.

Support

Need Support?

If this documentation does not address your questions, please feel free to contact us via email at support@dreamstechnologies.com

Reach the team at GMT+5:30. Typical reply within 12–24 hours on weekdays — rarely up to 48 hrs during holidays. Support is available to verified buyers for template-related issues.

Contact Support

Important Note : We strive to offer top-notch support, but it's only available to verified buyers and for template-related issues such as bugs and errors. Custom changes and third-party module setups are not covered.

Custom Work

Do you need a customized application for your business?

If you need a customized application for your business depends on your specific requirements and goals, Please contact us. Customization can be the key to success, ensuring your project perfectly aligns with your unique goals and requirements.

Don't Miss Out on the Benefits of Customization!

Unlock the potential of your project. It's time to ensure your project isn't another cookie-cutter solution but truly unique and effective one.

Discover how customization can make a difference in your project's success. Let's create a solution that's as unique as your vision!

We'll tailor the application to meet your specific needs and preferences.

We will upload your website to the server and ensure it is live.

thanks

Thank You

Thank you once again for downloading Preskool.
We hope you're enjoying your experience, and we kindly request that you take a moment to share your valuable review and rating with us.

Review Link