Bayan QA is a bilingual (English and Arabic) government-services assistant for Qatar.
Fanar API is used in three places: pages/api/chat.js for AI assistant replies, pages/api/translate.js for Arabic UI translation, and pages/api/analytics.js for AI-generated dashboard insights. All three routes use the Fanar model Fanar-C-2-27B.
It combines:
- AI chat guidance for citizen questions
- Service navigation pages for common procedures
- User feedback capture
- Live analytics dashboard for service demand and satisfaction trends
The app is built with Next.js (Pages Router), React, Chart.js, and a Fanar LLM backend integration.
- AI assistant widget with step-by-step responses
- Arabic translation mode for UI content
- Quick service navigation cards
- Citizen feedback collection (chat and survey)
- Analytics dashboard with service demand and satisfaction charts
- Home page: /
- Main landing page: /homePage
- Feedback page: /feedback
- Citizen analytics page: /citizen-feedback
- Service pages: /services/*
- Next.js 16 (Pages Router)
- React 19
- Chart.js + react-chartjs-2
- Lucide icons
- React Markdown (for assistant message rendering)
- Node.js 18+ (Node 20+ recommended)
- npm 9+
Run from the project root:
npm installCreate a file named .env.local in the project root.
Add:
FANAR_API_KEY=your_fanar_api_key_hereThis key is required by:
- pages/api/chat.js
- pages/api/translate.js
- pages/api/analytics.js
npm run devOpen:
npm run build
npm run start- npm run dev: start local development server
- npm run build: create optimized production build
- npm run start: start production server
- User opens AI widget and sends a message.
- Frontend posts conversation to /api/chat.
- API sends prompt + user messages to Fanar model.
- Reply is rendered in chat (Markdown supported).
- User can mark response helpful/not helpful.
- Feedback is saved locally and posted to /api/feedback.
- User switches language to Arabic.
- LanguageContext gathers UI strings from UI_STRINGS.
- Strings are batched and sent to /api/translate.
- API requests numbered translations from Fanar model.
- Translations are cached in memory and UI rerenders in Arabic.
- Feedback events are saved in localStorage (client source of truth).
- Feedback is also posted to data files through /api/feedback:
- data/survey-feedback.json
- data/chat-feedback.json
- CitizenInsightsDashboard reads feedback and computes:
- service demand counts
- average satisfaction ratings
- CitizenInsightsDashboard sends the aggregated stats to /api/analytics.
- The analytics route uses Fanar to generate a short AI insight summary.
- Charts and the AI summary update live when feedback changes.
pages/_app.js wraps all pages with:
- LanguageProvider
- ChatProvider
- Navbar
- AiAgentWidget
- Footer
- context/LanguageContext.js: i18n state and translation orchestration
- context/ChatContext.jsx: assistant open/close state
- components/AiAgentWidget.jsx: chat UI and feedback actions
- components/CitizenInsightsDashboard.jsx: analytics charts
- utils/feedback.js: feedback normalization, storage, and aggregations
- pages/api/chat.js: AI responses
- pages/api/translate.js: UI translation batching
- pages/api/analytics.js: AI-generated dashboard insights
- pages/api/feedback.js: feedback persistence and reset
- Survey feedback key: bayan_feedback_data
- Chat feedback key: bayan_chat_feedback
- data/survey-feedback.json
- data/chat-feedback.json
If API persistence fails, the app still functions using localStorage.
The frontend utility resetFeedbackData triggers:
- localStorage cleanup
- DELETE /api/feedback to reset JSON files
You can also call this endpoint manually during development.
- components/: reusable UI blocks
- context/: global state providers
- pages/: routes and API endpoints
- pages/services/: service-specific pages
- styles/: global and component style sheets
- utils/: shared utility logic
- data/: persisted feedback records
- public/: static assets
- Set FANAR_API_KEY in the deployment environment.
- Ensure the runtime has write permissions to the data directory if using file persistence in production.
- For serverless deployments, consider replacing file persistence with a database.
- Verify FANAR_API_KEY in .env.local.
- Check API route errors in server logs.
- Confirm exact text key exists in UI_STRINGS.
- Translation keys are exact-match, including punctuation.
- Confirm feedback exists in localStorage.
- Confirm data files are writable if relying on API persistence.
Use this lightweight flow for contributors:
- Pull latest changes and install deps.
- Run npm run dev and validate core pages.
- Implement feature in small commits.
- Run npm run build before pushing.
- Update this README when behavior or setup changes.