Production-ready single-page website for the BRAC University Natural Sciences Club (BUNSC). Built as a fast, static React application with a modern component library and a themeable design system.
- See the live preview https://bucc-x-bunsc.vercel.app/
- Present BUNSC’s mission, advisors, and leadership information.
- Showcase events, publications/blog-style content, and a media gallery.
- Provide clear contact channels and social presence links.
- Prospective members and students interested in BUNSC.
- University stakeholders (faculty, advisors, partners).
- Visitors looking for event highlights, publications, and media.
- Multi-page navigation within a single-page app (SPA).
- Home page hero with introduction video (fullscreen + minimized “picture-in-picture” experience).
- Events listing with categories/status badges and representative images.
- Publications listing (blogs and magazines) backed by curated content in code.
- Media gallery with folder grouping and lightbox viewing.
- Contact page with mailto and social links.
- Dark/light theming (class-based) and responsive navigation.
- Framework: React 18 + TypeScript
- Build tool: Vite 5
- Routing: React Router DOM
- Styling: Tailwind CSS (CSS variables + HSL token system)
- Component system: shadcn/ui patterns + Radix UI primitives
- Forms/validation utilities (available in dependencies): React Hook Form, Zod
- Icons: lucide-react
- UI feedback: Sonner + shadcn/ui Toaster
- Data fetching layer (available): @tanstack/react-query (QueryClient provided globally)
- Not included in this repository.
- The site currently runs as a static SPA; any dynamic features (forms, CMS, auth) would require an external backend.
- Not included.
- Content and media are currently stored as static assets under the source tree.
- Vercel Analytics (client-side analytics component).
- No other APIs/endpoints are currently called by the app.
- Client-side rendered SPA hosted as static files.
- Routing handled in the browser; server must rewrite all routes to /index.html.
Conceptually:
Browser
└─ loads static assets (HTML/CSS/JS/images/video)
└─ React app mounts
└─ React Router swaps page components
- On first load, the host serves built static assets (generated by
vite build). - Navigation between pages is handled by React Router (no full page reload).
- The hosting platform must support SPA rewrites:
- Vercel: configured via vercel.json rewrites.
- Netlify (or similar): configured via public/_redirects.
- The app is content-driven and currently uses:
- In-code curated data arrays (events, publications, panel members).
- Static assets loaded via Vite’s bundling.
import.meta.glob(..., { eager: true })for galleries (build-time inclusion of images).
- Runtime state is local to the client (theme toggle, video modal states, lightbox selection).
- src/: Application source code
- src/pages/: Route-level pages (Home, About, Events, Publications, Media, Contact)
- src/components/: Shared layout and feature components (Navbar, Footer, carousels)
- src/components/ui/: shadcn/ui + Radix-based UI primitives
- src/assets/: Images and video used across pages (events/media folders)
- public/: Static public assets (hosted as-is) and SPA redirect rules
- src/main.tsx: React root render + Vercel Analytics mount
- src/App.tsx: Global providers (ErrorBoundary, React Query, Tooltips, Toasts) + route table
- src/index.css: Design tokens (HSL variables), dark mode class, global utilities (glass, gradients)
- vite.config.ts: Dev server config + path alias (
@→ src) + lovable-tagger in development - vercel.json: SPA rewrite configuration for Vercel
- public/_redirects: SPA rewrite configuration for Netlify-style hosting
- Node.js (LTS recommended)
- One package manager:
- npm (works out of the box)
- bun (lockfile is present: bun.lockb)
- No required environment variables for the current codebase.
Using npm:
npm installUsing bun:
bun installnpm run dev- Dev server runs on
http://localhost:8080(see vite.config.ts).
Build and preview:
npm run build
npm run previewThis project currently does not require any environment variables.
If you later add APIs (e.g., contact form submission, CMS, image hosting), use Vite’s convention:
- Prefix client-exposed variables with
VITE_. - Store them in
.env,.env.development,.env.production.
Suggested future variables (not currently used):
VITE_API_BASE_URL: Base URL for a backend serviceVITE_CONTACT_FORM_ENDPOINT: Endpoint for contact submissionsVITE_SENTRY_DSN: Error monitoring DSN (client)
- Routes are defined in src/App.tsx and map directly to pages:
/→ Home/about→ About/events→ Events/publications→ Publications/media→ Media/contact→ Contact*→ NotFound
User flow:
- User lands on Home.
- Uses Navbar links to navigate between pages.
- Footer provides quick links and external social links.
- Displays hero image and CTA buttons.
- “Watch Introduction” opens a fullscreen video view.
- Video can be minimized and restored; closing stops playback.
Business logic overview:
- Local state controls fullscreen/minimized state and play/pause.
- Uses refs to control video elements safely.
- Event metadata is curated in code.
- Each event card includes:
- Category badge (color-coded)
- Status badge
- Representative image resolved from src/assets using
import.meta.glob.
- Blog cards and magazine cards are curated in code.
- Uses representative images from the assets folders.
- Intended as a static “publications showcase” (no CMS).
- Loads images from src/assets via Vite glob import.
- Automatically groups images by folder name.
- Lightbox view opens on click; click outside closes.
- Primary email contact via
mailto:. - Social links open in a new tab with
rel="noopener noreferrer".
Not applicable for the current repository.
- There are no implemented HTTP endpoints.
- No authentication or authorization is implemented.
If you add a backend, document:
- Base URL, endpoints, request/response schemas, error formats.
- Auth mechanism (session/JWT/OAuth) and role model.
- Fixed top Navbar with:
- Active route highlighting
- Mobile hamburger menu
- Theme toggle
- Tailwind responsive classes are used throughout.
- Navigation collapses to a mobile menu on smaller screens.
- Grid layouts adapt across breakpoints (media gallery, events grid, footer columns).
- Images generally include alt text.
- External links use safe target/rel attributes.
Recommended improvements:
- Ensure all interactive elements have visible focus states.
- Add keyboard support for lightbox close (Escape key) and video modal focus trapping.
- Prefer semantic buttons over clickable divs where possible.
- Unknown routes → NotFound page.
- Runtime React errors → ErrorBoundary fallback UI.
- ErrorBoundary prevents a full blank screen by rendering a recovery view.
- The “Go to Home” action in ErrorBoundary forces a clean navigation.
Edge cases to consider:
- Missing/invalid media assets: currently not surfaced to the user (images may render broken).
- Very large asset folders: eager imports may increase build size and memory usage.
- Static hosting platforms (Vercel/Netlify) can cache immutable build assets.
- Prefer long-cache headers for hashed JS/CSS assets (handled by most static hosts).
- Current routes are imported eagerly in src/App.tsx.
- Recommended: route-level lazy loading using
React.lazy()+Suspensefor large pages.
- Vite build pipeline (tree-shaking, minification).
- Tailwind CSS utility generation + production purge.
Potential improvements (if needed):
- Change
import.meta.glob(..., { eager: true })to non-eager loading for galleries. - Add image optimization pipeline (modern formats, responsive sizing).
- Not implemented (public site).
- No server-side input handling exists in this repo.
- Client-side validation libraries (Zod/React Hook Form) are available if forms are added.
- External links opened in a new tab typically use
rel="noopener noreferrer". - No secrets are stored in code; no env vars required.
Recommended practices for production:
- Add a Content Security Policy (CSP) via hosting headers.
- Avoid committing any future API keys into the repo; use environment variables.
- This repo is configured for SPA hosting on:
- Vercel via vercel.json
- Netlify-style hosting via public/_redirects
- Build command:
npm run build - Output directory: Vite default (
dist/)
- No CI/CD pipelines are included in this repository.
- Suggested: GitHub Actions to run
npm ci,npm run lint, andnpm run buildon pull requests.
- Pages are cleanly separated under src/pages.
- UI primitives are centralized under src/components/ui.
- React Query is already set up globally, enabling future API integration without rewiring providers.
- Add a CMS or structured content source for events/publications.
- Add a backend (or serverless function) for contact submissions.
- Add route-level code splitting and non-eager gallery loading.
- Persist theme preference (localStorage) to maintain user choice.
- Add automated image optimization and responsive sources.
- Content is hard-coded in the frontend (events/publications/panel member data).
- No backend, database, or admin tooling is present.
- Gallery imports are eager; large media libraries can increase build size.
- Theme toggle state is not persisted across reloads.
- Introduce a content management approach (CMS or JSON-based content pipeline).
- Add analytics events for key CTAs (beyond base page analytics).
- Add accessibility enhancements for modals/lightboxes.
- If you add environment variables, prefer Vite’s
VITE_prefix and document them in this README. - Keep design tokens in src/index.css; avoid hard-coding colors in components.
- Ensure hosting always rewrites unknown routes to /index.html for SPA navigation. =======