# croustillant-developpement/croustillantweb architecture

> Architecture diagram of the GitHub repository croustillant-developpement/croustillantweb, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/croustillant-developpement/croustillantweb
- Repository: https://github.com/croustillant-developpement/croustillantweb

## Overview

CROUStillant is a multilingual web app for discovering CROUS restaurants and their menus. The central visitor workflow is restaurant discovery and filtering, followed by restaurant details and date-based menu browsing; the API supplies the restaurant, menu, dish, and statistics data. The graph also preserves documented capabilities for embeds, TV screen mode, favorites, calendar feeds, mobile-app information, and analytics. Several feature implementations are represented by their exact enclosing paths because their source was not sampled; uncertain call wiring is omitted.

Main entry points: [`src/services/api-request.ts`](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/api-request.ts) (API client), [`src/services/restaurant-service.ts`](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/restaurant-service.ts) (Restaurant queries), [`src/services/stats-services.ts`](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/stats-services.ts) (Dish and stats queries), [`src/hooks/useRestaurantFilters.ts`](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/hooks/useRestaurantFilters.ts) (Restaurant filters)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["Web experience"]
  node_localized_pages["Localized pages"]
  node_i18n["Locale routing<br/>[routing.ts]"]
  node_dishes["Dish catalogue<br/>[page.tsx]"]
  node_statistics["Statistics page<br/>[page.tsx]"]
end

subgraph group_restaurant["Restaurant discovery"]
  node_restaurant_list["Restaurant list<br/>[page.tsx]"]
  node_filters_hook["Restaurant filters"]
  node_filter_logic["Filter and sort<br/>[filters.ts]"]
  node_restaurant_detail["Restaurant detail<br/>[page.tsx]"]
  node_menu_hook["Menu navigation"]
  node_favorites[("Favorites and preferences")]
end

subgraph group_data["Data services"]
  node_restaurant_service["Restaurant queries"]
  node_menu_service["Menu queries<br/>[menu-service.ts]"]
  node_stats_service["Dish and stats queries<br/>[stats-services.ts]"]
  node_api_client["API client<br/>[api-request.ts]"]
end

subgraph group_extensions["Sharing and insights"]
  node_embed_builder["Widget builder"]
  node_embed_state[("Widget configuration")]
  node_screen_mode["TV screen mode<br/>[page.tsx]"]
  node_calendar_feed["Calendar subscriptions<br/>[calendar.ts]"]
  node_mobile_info["Mobile app information"]
  node_analytics["Umami analytics<br/>[umami-service.ts]"]
end

node_visitor(("Visitor"))
node_croustillant_api{{"CROUStillant API"}}
node_umami{{"Umami service"}}

node_visitor -->|"opens"| node_localized_pages
node_localized_pages -->|"routes by locale"| node_i18n
node_visitor -->|"browses"| node_restaurant_list
node_restaurant_list -->|"loads restaurants"| node_restaurant_service
node_filters_hook -->|"filters and sorts"| node_filter_logic
node_filters_hook -->|"reads preferences"| node_favorites
node_visitor -->|"opens restaurant"| node_restaurant_detail
node_restaurant_detail -->|"loads details"| node_restaurant_service
node_menu_hook -->|"loads menus and dates"| node_menu_service
node_restaurant_service -->|"requests data"| node_api_client
node_menu_service -->|"requests data"| node_api_client
node_stats_service -->|"requests dishes and stats"| node_api_client
node_api_client -->|"fetches"| node_croustillant_api
node_visitor -->|"browses dishes"| node_dishes
node_dishes -->|"loads dish data"| node_stats_service
node_visitor -->|"views statistics"| node_statistics
node_statistics -->|"loads statistics"| node_stats_service
node_visitor -->|"configures widget"| node_embed_builder
node_embed_builder -->|"updates configuration"| node_embed_state
node_visitor -->|"views signage"| node_screen_mode
node_visitor -->|"subscribes to menus"| node_calendar_feed
node_calendar_feed -.->|"serves calendar data"| node_croustillant_api
node_visitor -->|"finds app links"| node_mobile_info
node_analytics -->|"requests analytics"| node_api_client
node_api_client -.->|"fetches"| node_umami

click node_localized_pages "https://github.com/croustillant-developpement/croustillantweb/tree/main/src/app/%5Blocale%5D"
click node_i18n "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/i18n/routing.ts"
click node_restaurant_list "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/restaurants/(list)/page.tsx"
click node_filters_hook "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/hooks/useRestaurantFilters.ts"
click node_filter_logic "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/lib/filters.ts"
click node_restaurant_detail "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/restaurants/%5Bslug%5D/page.tsx"
click node_menu_hook "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/hooks/useRestaurantMenu.ts"
click node_restaurant_service "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/restaurant-service.ts"
click node_menu_service "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/menu-service.ts"
click node_stats_service "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/stats-services.ts"
click node_api_client "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/api-request.ts"
click node_favorites "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/store/userPreferencesStore.ts"
click node_dishes "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/dishes/page.tsx"
click node_statistics "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/stats/page.tsx"
click node_embed_builder "https://github.com/croustillant-developpement/croustillantweb/tree/main/src/components/iframe-builder"
click node_embed_state "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/store/iframeBuilderStore.ts"
click node_screen_mode "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/restaurants/%5Bslug%5D/screen/page.tsx"
click node_calendar_feed "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/lib/calendar.ts"
click node_mobile_info "https://github.com/croustillant-developpement/croustillantweb/tree/main/src/components/mobile"
click node_analytics "https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/umami-service.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_localized_pages,node_i18n,node_dishes,node_statistics toneBlue
class node_restaurant_list,node_filters_hook,node_filter_logic,node_restaurant_detail,node_menu_hook,node_favorites toneAmber
class node_restaurant_service,node_menu_service,node_stats_service,node_api_client,node_croustillant_api toneMint
class node_embed_builder,node_embed_state,node_screen_mode,node_calendar_feed,node_mobile_info,node_analytics toneRose
class node_visitor,node_umami toneIndigo
```

## Components

### Web experience

- [Localized pages](https://github.com/croustillant-developpement/croustillantweb/tree/main/src/app/%5Blocale%5D): `src/app/[locale]`
- [Locale routing](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/i18n/routing.ts): `src/i18n/routing.ts`
- [Dish catalogue](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/dishes/page.tsx): `src/app/[locale]/dishes/page.tsx`
- [Statistics page](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/stats/page.tsx): `src/app/[locale]/stats/page.tsx`

### Restaurant discovery

- [Restaurant list](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/restaurants/(list)/page.tsx): `src/app/[locale]/restaurants/(list)/page.tsx`
- [Restaurant filters](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/hooks/useRestaurantFilters.ts): `src/hooks/useRestaurantFilters.ts`
- [Filter and sort](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/lib/filters.ts): `src/lib/filters.ts`
- [Restaurant detail](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/restaurants/%5Bslug%5D/page.tsx): `src/app/[locale]/restaurants/[slug]/page.tsx`
- [Menu navigation](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/hooks/useRestaurantMenu.ts): `src/hooks/useRestaurantMenu.ts`
- [Favorites and preferences](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/store/userPreferencesStore.ts): `src/store/userPreferencesStore.ts`

### Data services

- [Restaurant queries](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/restaurant-service.ts): `src/services/restaurant-service.ts`
- [Menu queries](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/menu-service.ts): `src/services/menu-service.ts`
- [Dish and stats queries](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/stats-services.ts): `src/services/stats-services.ts`
- [API client](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/api-request.ts): `src/services/api-request.ts`

### Sharing and insights

- [Widget builder](https://github.com/croustillant-developpement/croustillantweb/tree/main/src/components/iframe-builder): `src/components/iframe-builder`
- [Widget configuration](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/store/iframeBuilderStore.ts): `src/store/iframeBuilderStore.ts`
- [TV screen mode](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/app/%5Blocale%5D/restaurants/%5Bslug%5D/screen/page.tsx): `src/app/[locale]/restaurants/[slug]/screen/page.tsx`
- [Calendar subscriptions](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/lib/calendar.ts): `src/lib/calendar.ts`
- [Mobile app information](https://github.com/croustillant-developpement/croustillantweb/tree/main/src/components/mobile): `src/components/mobile`
- [Umami analytics](https://github.com/croustillant-developpement/croustillantweb/blob/main/src/services/umami-service.ts): `src/services/umami-service.ts`

### Other components

- **Visitor**
- **CROUStillant API**
- **Umami service**

## Connections

- Visitor → Localized pages: opens
- Localized pages → Locale routing: routes by locale
- Visitor → Restaurant list: browses
- Restaurant list → Restaurant queries: loads restaurants
- Restaurant filters → Filter and sort: filters and sorts
- Restaurant filters → Favorites and preferences: reads preferences
- Visitor → Restaurant detail: opens restaurant
- Restaurant detail → Restaurant queries: loads details
- Menu navigation → Menu queries: loads menus and dates
- Restaurant queries → API client: requests data
- Menu queries → API client: requests data
- Dish and stats queries → API client: requests dishes and stats
- API client → CROUStillant API: fetches
- Visitor → Dish catalogue: browses dishes
- Dish catalogue → Dish and stats queries: loads dish data
- Visitor → Statistics page: views statistics
- Statistics page → Dish and stats queries: loads statistics
- Visitor → Widget builder: configures widget
- Widget builder → Widget configuration: updates configuration
- Visitor → TV screen mode: views signage
- Visitor → Calendar subscriptions: subscribes to menus
- Calendar subscriptions → CROUStillant API: serves calendar data
- Visitor → Mobile app information: finds app links
- Umami analytics → API client: requests analytics
- API client → Umami service: fetches
