Skip to content

Repository files navigation

FOSSEE Workshop Booking Portal — UI/UX Redesign

This is my submission for the FOSSEE Python Screening Task. The goal was to redesign the existing workshop_booking Django site using React, with a focus on mobile usability, clean visual hierarchy, and accessibility.


Getting Started

git clone <your-repo-url>
cd fossee-redesign
npm install
npm run dev

Opens at http://localhost:5173

To build for production:

npm run build
npm run preview

Node 18+ required.


What I Built

Five pages, all navigable from a single persistent navbar:

  • Home — hero section with platform stats, featured workshop cards, a step-by-step how-it-works, testimonials from coordinators, and a bottom CTA
  • Workshops — full listing with a search input and two filter rows (by topic and by status)
  • Book a Workshop — a three-section form that groups fields logically: workshop details first, then institution info, then coordinator contact. Submitting shows a confirmation panel explaining what happens next
  • Dashboard — for instructors. Shows four stat cards at the top, then a tabbed panel (upcoming vs past workshops) and a side panel with pending booking requests that can be accepted or rejected
  • Login / Register — single card with a tab switcher between sign-in and register, a role selector (coordinator vs instructor), and a Google OAuth button

Navigation is handled via a simple useState in App.jsx — no React Router. For a five-page app where deep linking isn't needed, it keeps things simpler and the bundle smaller.


Folder Structure

fossee-redesign/
├── index.html
├── package.json
├── vite.config.js
└── src/
    ├── main.jsx
    ├── App.jsx
    ├── App.css
    ├── components/
    │   └── Navbar.jsx
    └── pages/
        ├── HomePage.jsx
        ├── WorkshopsPage.jsx
        ├── BookWorkshopPage.jsx
        ├── DashboardPage.jsx
        └── LoginPage.jsx

I kept the structure flat. There are no extracted shared UI components beyond the Navbar because the pages don't have enough repeated structure to justify a Button or Card abstraction at this stage — that would be premature here.


Design Decisions

Typography

I used Syne for headings and display text, and DM Sans for body copy and UI labels. The combination came from wanting something that felt academic but not stiff — Syne has weight and presence that suits the IIT Bombay context without looking like a generic SaaS product. DM Sans is highly readable at small sizes, which mattered a lot since this is primarily a mobile-use portal.

I specifically avoided Inter and Roboto. They've lost all character at this point.

Color

The primary color is a deep navy (#0a1628) with an accent orange (#e85d26). The reasoning: FOSSEE is an IIT Bombay initiative so the identity should feel institutional and trustworthy, but the actual users are students — the orange keeps it from feeling like a government portal. I debated using a warmer off-white (#f4f2ed) for page backgrounds and ended up keeping it because pure white felt too clinical next to the dark navbar.

Status badges (open / upcoming / closed) use green / yellow / red. Obvious, but clarity matters more than originality here — a coordinator checking whether a workshop is available shouldn't have to think about what a color means.

Layout Choices

The homepage is a vertical stack: hero → workshops → how-it-works → testimonials → CTA. I considered putting how-it-works before the cards but it made more sense to show what's actually available first, then explain the process. Most people scanning a new site want to know "what is this?" before "how does it work?".

The booking form is split into three cards. The original Django form is a single flat list of fields — functional, but it feels like a lot all at once. Grouping by context (what workshop → where is your college → who are you) makes the cognitive load lighter, especially on mobile where you're reading everything top to bottom.

The dashboard uses a two-column grid on wider screens with the sidebar (quick actions + pending requests) as secondary content. On mobile the sidebar drops below the main panel since the pending requests are less time-sensitive than seeing your upcoming schedule.


Responsiveness

Everything is mobile-first. The main breakpoints:

  • ≤ 640px — single column, hamburger nav, hero stats in a 2×2 grid
  • 641px – 900px — workshop cards go to 2 columns, hero stats to 3
  • ≥ 901px — full 3-column card grid, 4-column stats row, dashboard sidebar appears beside main panel

I used clamp() for heading sizes so they scale fluidly instead of jumping at breakpoints. The hero heading goes from about 2.2rem on a small phone to 3.8rem on a wide screen with no media query needed for the font itself.

The navbar collapses to a hamburger at 640px. The mobile menu slides in inline below the bar — I considered a full overlay drawer but it felt like overkill for five navigation items. Simpler is better here.

Form rows (two fields side by side on desktop) collapse to single column on mobile so inputs are full width and easy to tap.


Accessibility

Things I specifically paid attention to:

  • Every page section has an aria-label or aria-labelledby tied to a visible heading
  • Workshop card grids use role="list" and role="listitem" — without this, screen readers don't announce the item count
  • The hamburger button has aria-expanded and aria-label="Toggle menu"
  • All form inputs are associated with <label> elements via htmlFor, not just placeholder text
  • Dashboard tab buttons use role="tab" and aria-selected
  • The booking success banner uses aria-live="polite" so screen readers announce the confirmation message
  • Hero stat items have descriptive aria-label attributes so "24" reads as "24 Total Workshops" not just a number
  • Color is never the only indicator of state — status badges always include text, not just color

I manually tested the tab focus order on each page. There was one spot in the mobile menu where focus jumped out of order that I fixed by adjusting the DOM structure.


Performance

  • No component library (no MUI, Chakra, or Tailwind) — CSS is hand-written and only includes what's used
  • Zero image assets — all visuals are CSS or emoji, meaning zero image requests on load
  • Google Fonts loads with display=swap so it never blocks rendering
  • window.scrollTo(0, 0) on every page switch prevents landing mid-scroll on a new page
  • The full bundle stays well under 200KB uncompressed with Vite's defaults

The two moderate severity warnings from npm audit are inside Vite and esbuild dev dependencies. They have no effect on the production build or runtime.


Trade-offs I Made

Design vs Performance: Google Fonts is the one external network request I kept. The typography quality difference is significant enough to justify the ~30KB. Everything else (icons, illustrations, backgrounds) is pure CSS.

No React Router: Simpler code, smaller bundle, but no shareable URLs or browser back-button support. For a screening task this is fine. A production deployment would need React Router.

Static data: All workshop listings and dashboard stats are hardcoded. In a real integration these would come from the Django REST API with loading states and error handling. I didn't build that layer because the task was about UI/UX, not API integration.

Filter logic: The workshops search re-renders on every keystroke. With six cards it's imperceptible. For a real dataset of 60+ workshops it would need useMemo or debouncing.


What I'd Improve Given More Time

The thing I'm least happy with is the dashboard. The pending requests panel is functional but it doesn't have any confirmation step before accepting or rejecting — in a real app rejecting a workshop request from a college has real consequences and should at minimum ask "are you sure?" with an optional reason field.

I also wanted to build the India map view that the original site has (workshops plotted on a map of India). It's one of the more interesting features of the original portal and I think a React version with hover tooltips per state would look great. I cut it because building an accurate SVG India map from scratch was going to take longer than the rest of the UI combined.

The booking form validation is shallow — just HTML required attributes. A proper version would check that date 2 isn't before date 1, that the phone number is a valid Indian format, and that the email looks institutional (not a Gmail address).


Before / After

Before — original Django site:

  • Bootstrap 3 table-based layouts
  • No mobile responsiveness — horizontal scroll on small screens
  • Single flat form with no logical grouping
  • No visual differentiation between workshop statuses
  • Plain top navigation with no active state indicator

After — this redesign:

  • Mobile-first layout tested down to 375px
  • Workshop cards with status badges, instructor info, and direct booking button
  • Booking form split into three grouped sections with a post-submit confirmation flow
  • Instructor dashboard with stats, tabbed workshop history, and a request management panel
  • Sticky navbar with active page highlight and a collapsing mobile menu

Tech Stack

Version Reason
React 18.3 Component model, useState for page state
Vite 5.4 Fast HMR in dev, clean production builds
Google Fonts Syne + DM Sans
Vanilla CSS No framework overhead, full control

License

GPL-3.0 — same as the original FOSSEE workshop_booking repository.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages