# Product Requirements Document ## Jamshalat Diary — Islamic Worship Companion App **Version:** 1.0 **Date:** March 2026 **Platform:** Flutter (iOS + Android) **Status:** Draft --- ## Table of Contents 1. [Overview](#1-overview) 2. [Target Users](#2-target-users) 3. [Design System](#3-design-system) 4. [App Architecture](#4-app-architecture) 5. [Navigation](#5-navigation) 6. [Feature Specifications](#6-feature-specifications) - 6.1 Dashboard - 6.2 Prayer Calendar (Imsakiyah) - 6.3 Daily Checklist - 6.4 Dzikir - 6.5 Reports (Laporan) - 6.6 Qibla Finder - 6.7 Quran Reading - 6.8 Quran Murattal - 6.9 Settings 7. [Data Model](#7-data-model) 8. [Third-Party Dependencies](#8-third-party-dependencies) 9. [Non-Functional Requirements](#9-non-functional-requirements) 10. [Permissions](#10-permissions) 11. [Out of Scope (v1.0)](#11-out-of-scope-v10) --- ## 1. Overview **Jamshalat Diary** is an offline-first Muslim daily worship companion app built in Flutter. It helps Muslim users track their daily prayers, worship habits, and spiritual growth with a clean, modern UI that supports both light and dark themes. **Core value proposition:** - Never miss a prayer — real-time prayer time countdowns with Adhan/Iqamah notifications - Track daily worship completion — checklist for Sholat, Tilawah, Dzikir - Build consistent habits — weekly/monthly progress reports - All-in-one Islamic toolkit — Qibla compass, Quran reader, Murattal player, Dzikir counter --- ## 2. Target Users **Primary:** Muslim adults (18–45) who want to improve consistency in daily worship **Secondary:** Parents tracking worship habits for the family **User goals:** - Know exact prayer times for their location, offline - Get reminded for Adhan and Iqamah - Log daily ibadah (worship) completion - Read Quran and perform guided Dzikir - Find Qibla direction while traveling - Review worship quality over time --- ## 3. Design System ### 3.1 Color Tokens | Token | Light Value | Dark Value | Usage | |---|---|---|---| | `primary` | `#70df20` | `#70df20` | Active states, CTAs, progress fills | | `background` | `#f7f8f6` | `#182111` | App background | | `surface` | `#ffffff` | `#1e2a14` | Cards, bottom nav | | `sage` | `#728764` | `#728764` | Secondary text, section labels | | `cream` | `#f2f4f0` | — | Dividers, borders (light mode) | | `on-primary` | `#0a1a00` | `#0a1a00` | Text on primary bg | | `text-primary` | `#1a2a0a` | `#f2f4f0` | Body text | | `text-secondary` | `#64748b` | `#94a3b8` | Captions, labels | | `error` | `#ef4444` | `#f87171` | Error states | | `success` | `#22c55e` | `#4ade80` | Success/completed states | ### 3.2 Typography | Style | Font | Weight | Size | Usage | |---|---|---|---|---| | `displayLarge` | Plus Jakarta Sans | 800 (ExtraBold) | 32sp | Hero numbers (next prayer) | | `headlineMedium` | Plus Jakarta Sans | 700 (Bold) | 24sp | Screen titles, section headers | | `titleMedium` | Plus Jakarta Sans | 600 (SemiBold) | 16sp | Card titles, nav labels | | `bodyLarge` | Plus Jakarta Sans | 400 (Regular) | 16sp | Body text | | `bodySmall` | Plus Jakarta Sans | 400 (Regular) | 12sp | Captions, timestamps | | `labelSmall` | Plus Jakarta Sans | 700 (Bold) | 10sp | Uppercase tags, section labels | | `arabicBody` | Amiri | 400 (Regular) | 24sp | Quran verses, Dzikir Arabic text | | `arabicLarge` | Amiri | 700 (Bold) | 28sp | Surah headings in Arabic | ### 3.3 Spacing & Shape | Token | Value | Flutter | |---|---|---| | `radiusSm` | 8dp | `BorderRadius.circular(8)` | | `radiusMd` | 12dp | `BorderRadius.circular(12)` | | `radiusLg` | 16dp | `BorderRadius.circular(16)` | | `radiusXl` | 24dp | `BorderRadius.circular(24)` | | `radiusFull` | 9999dp | `StadiumBorder()` | | `spacingXs` | 4dp | — | | `spacingSm` | 8dp | — | | `spacingMd` | 16dp | — | | `spacingLg` | 24dp | — | | `spacingXl` | 32dp | — | ### 3.4 Iconography - **Library:** Material Symbols Outlined (via `material_symbols_icons` Flutter package) - **Filled variant:** Used for active bottom nav tab icons only - **Size:** 24dp default, 20dp for compact rows, 32dp for feature section icons ### 3.5 Dark Mode - Toggled via user preference in Settings (stored locally) - Options: **Light**, **Dark**, **System (Auto)** - Implemented via Flutter `ThemeMode` — `ThemeMode.light`, `ThemeMode.dark`, `ThemeMode.system` - All color tokens have explicit light and dark values; no transparency hacks --- ## 4. App Architecture ### 4.1 Structure ``` lib/ ├── main.dart ├── app/ │ ├── app.dart # MaterialApp.router + theme + locale │ ├── router.dart # GoRouter — shell route for bottom nav │ └── theme/ │ ├── app_theme.dart # ThemeData light + dark │ ├── app_colors.dart # AppColors class with static consts │ └── app_text_styles.dart # TextTheme definitions ├── core/ │ ├── widgets/ │ │ ├── bottom_nav_bar.dart │ │ ├── prayer_time_card.dart │ │ ├── section_header.dart │ │ ├── ios_toggle.dart │ │ ├── progress_bar.dart │ │ └── circular_progress_indicator_custom.dart │ ├── utils/ │ │ ├── date_utils.dart │ │ ├── prayer_utils.dart # Hijri date conversion helpers │ │ └── arabic_utils.dart # RTL text helpers │ └── providers/ │ └── theme_provider.dart # ThemeMode state via Riverpod ├── features/ │ ├── dashboard/ │ │ ├── data/ │ │ ├── domain/ │ │ └── presentation/ │ │ ├── dashboard_screen.dart │ │ └── widgets/ │ ├── imsakiyah/ │ ├── checklist/ │ ├── dzikir/ │ ├── laporan/ │ ├── qibla/ │ ├── quran/ │ │ ├── presentation/ │ │ │ ├── quran_screen.dart # Surah list │ │ │ ├── quran_reading_screen.dart │ │ │ └── quran_murattal_screen.dart │ └── settings/ └── data/ ├── local/ │ ├── hive_boxes.dart # Box names constants │ └── adapters/ # Hive TypeAdapters └── services/ ├── prayer_service.dart # Adhan calculation ├── location_service.dart # GPS + last known ├── notification_service.dart └── quran_service.dart # Local JSON asset ``` ### 4.2 State Management **Riverpod** (flutter_riverpod + riverpod_annotation + riverpod_generator) - Every feature has its own `*_provider.dart` - Async data via `AsyncNotifierProvider` - UI state (loading, error, data) handled via `AsyncValue` - Theme mode via `StateProvider` ### 4.3 Local Storage **Hive** for offline-first persistence: | Box | Key | Value type | |---|---|---| | `settings` | String key | dynamic | | `checklist_items` | date string (yyyy-MM-dd) | `List` | | `worship_logs` | date string | `WorshipLog` | | `dzikir_counters` | dzikir ID | int count | | `cached_prayer_times` | `lat_lng_date` | `PrayerTimes` | --- ## 5. Navigation ### 5.1 Bottom Navigation Bar (5 tabs) | Index | Label | Icon (inactive) | Icon (active) | Route | |---|---|---|---|---| | 0 | Home | `home_outlined` | `home` (filled) | `/` | | 1 | Calendar | `calendar_today_outlined` | `calendar_today` | `/imsakiyah` | | 2 | Checklist | `rule_outlined` | `rule` (filled) | `/checklist` | | 3 | Reports | `bar_chart_outlined` | `bar_chart` | `/laporan` | | 4 | Tools | `auto_fix_high_outlined` | `auto_fix_high` (filled) | `/tools` | - Bottom nav is persistent across all 5 tabs (shell route via GoRouter) - Safe area padding (bottom) applied to nav bar (`pb: 24dp`) - Active tab: `primary` text + filled icon - Inactive tab: `text-secondary` color ### 5.2 Full Route Map ``` / → DashboardScreen /qibla → QiblaScreen (push, no bottom nav) /imsakiyah → ImsakiyahScreen /checklist → ChecklistScreen /laporan → LaporanScreen /tools → ToolsScreen (hub for Dzikir, Quran, Qibla) /tools/dzikir → DzikirScreen /tools/quran → QuranListScreen /tools/quran/:surahId → QuranReadingScreen /tools/quran/:surahId/murattal → QuranMurattalScreen /tools/qibla → QiblaScreen /settings → SettingsScreen (push from Dashboard header) ``` --- ## 6. Feature Specifications --- ### 6.1 Dashboard **Route:** `/` **Description:** App home screen showing next prayer, daily prayer schedule, checklist summary, and weekly progress. #### UI Components **Header (sticky)** - Left: Circular user avatar (40dp, primary border 2dp) + greeting text ("Welcome back," / user name "Assalamu'alaikum, [Name]") - Right: Notification bell `IconButton` → opens notification settings **Next Prayer Hero Card** - Full-width card, `bg-primary`, `borderRadius: 24dp`, `padding: 20dp`, `boxShadow: lg` - Content: - Label: "Next Prayer" with `schedule` icon - Title: `"{PrayerName} at {HH:mm}"` — `displayLarge` weight 800 - Subtitle: `"Countdown: HH:mm:ss"` — live countdown timer updating every second - Actions row: - "View Qibla" button (`black bg`, `white text`, `explore icon`, `borderRadius: full`) - Volume/mute toggle button (`white/30 backdrop-blur`, `rounded-full`) - Decorative: white/20 blurred circle blob (top-right, size 120dp) **Prayer Times Horizontal Scroll** - Section title: "Daily Prayer Times" + "Today" chip (`primary/10 bg`, `primary text`) - Horizontal `ListView.builder`, no scroll indicator, `padding: 16dp horizontal` - Each card: `width: 112dp`, `borderRadius: 16dp`, `border: primary/10` - Icon (Material Symbol): Fajr→`wb_twilight`, Dhuhr→`wb_sunny`, Asr→`filter_drama`, Maghrib→`wb_twilight`, Isha→`dark_mode` - Prayer name (`sm font-bold`) - Time string (`xs text-secondary`) - **Active prayer card:** `bg-primary/10`, `border-2 border-primary`, primary text color - **Adhan/Iqamah variant:** Active card shows notification badge (small bell icon, white circle, shadow, absolute top-right) **Daily Checklist Summary Card** - Title: "Today's Checklist" + subtitle "{n} dari {total} Ibadah selesai" - Circular SVG progress indicator (48dp, `strokeWidth: 4`, `primary` stroke) - Percentage text centered inside circle - 2 preview items: "Sholat Fardhu (4 of 5)" and "Tilawah Quran (1 Juz)" - Completed items: `check_circle` icon in `primary` color - "View Full Checklist" CTA button → navigates to `/checklist` **Weekly Progress Chart** - Title: "Weekly Progress" - `Container` with `bg-surface`, `borderRadius: 16dp`, `padding: 20dp` - 7 vertical bars (Mon–Sun): each bar is `Expanded`, `bg-primary/20`, with `primary` fill overlay proportional to completion % - Day labels below each bar: `10sp`, `font-bold`, `text-secondary` #### Behavior - Countdown timer refreshes every 1 second via `Timer.periodic` - Prayer times are calculated from device location via `adhan` package on app start - If location unavailable, use last cached location; if none, prompt user - Notification badge on prayer card: shown when Adhan has been called (within current window) - Tapping the Next Prayer card → navigates to Imsakiyah screen #### Acceptance Criteria - [ ] Correct prayer times displayed for device's current GPS location - [ ] Countdown shows real-time seconds tick - [ ] Active prayer card highlighted with `primary` border and color - [ ] Checklist summary reflects today's actual completion state from local storage - [ ] Weekly chart bars reflect daily worship logs from past 7 days - [ ] Works fully offline (cached prayer times used when no internet) --- ### 6.2 Prayer Calendar (Imsakiyah) **Route:** `/imsakiyah` **Description:** Full Hijri-calendar view of prayer times, organized by month, with location selection. #### UI Components **Header** - Back arrow + "Prayer Calendar" (centered, `headlineMedium`) + `more_vert` menu button **Month Selector** - Horizontal scrolling chip row (no scrollbar) - Selected: `bg-primary`, `text-slate-900`, `font-semibold`, `borderRadius: full` - Unselected: `bg-surface`, `text-secondary`, `borderRadius: full` - Months shown in Hijri format: "Ramadan 1445H", "Shawwal 1445H", etc. **Location Card** - `bg-surface`, `borderRadius: 16dp`, `border: 1dp` - `location_on` icon (primary) + "Your Location" label + city name (e.g., "Jakarta, Indonesia") - `expand_more` chevron — tapping opens city search/picker **Prayer Times Table** - 7-column grid: Day | Fajr | Sunrise | Dhuhr | Asr | Maghrib | Isha - Header row: `bg-primary/10`, `10sp font-bold uppercase tracking-wider text-secondary` - Data rows: alternating subtle bg for readability - Today's row: highlighted with `primary/5` background, bold text #### Behavior - Loads prayer times for entire selected month using `adhan` package - Location defaults to last GPS fix; editable via city search - City search: local bundled list of major Indonesian cities (offline), Geocoding API optional - Changing month or location recalculates and re-renders table - Scroll position resets to today's row on initial load #### Acceptance Criteria - [ ] Displays complete monthly prayer timetable for selected Hijri month - [ ] Today's row is visually highlighted - [ ] Month chip scroll updates table data - [ ] Location change triggers recalculation - [ ] Works offline with bundled city coordinates --- ### 6.3 Daily Checklist **Route:** `/checklist` **Description:** Daily worship completion tracker with custom checklist items and progress visualization. #### UI Components **Header** - "Daily Worship" (`headlineMedium`) + date string ("Tuesday, 24 Oct") + calendar icon button (date picker) **Progress Card** - `bg-slate-900 / bg-primary/10 (dark)`, `borderRadius: 16dp`, `padding: 20dp` - Decorative `auto_awesome` icon (64sp, opacity 10%, top-right) - "Today's Goal" label (`xs uppercase tracking-wider text-slate-400`) - Percentage: "{n}% Complete" (`displayLarge font-bold white`) - "{completed} / {total} Tasks" (`primary color xs`) - Progress bar: `h-12dp`, `bg-white/10`, `primary fill`, `borderRadius: full` - Motivational quote text below bar (`xs text-slate-300`) **Task List** Section header: "Religious Tasks" (`sm font-bold uppercase tracking-widest text-secondary`) Each checklist item: - `Container` with `bg-surface / bg-primary/5 (dark)`, `borderRadius: 12dp`, `border: 1dp` - Custom checkbox: 24dp square, `border-2 border-primary/30`, `borderRadius: 6dp` - Checked state: `bg-primary`, white checkmark SVG inside - Task label: `bodyLarge font-medium` - Optional: sub-label (e.g., target count for Tilawah) **Default checklist items (seeded on first launch):** | Item | Category | Default Target | |---|---|---| | Sholat Fajr | Sholat Fardhu | 1x | | Sholat Dhuhr | Sholat Fardhu | 1x | | Sholat Asr | Sholat Fardhu | 1x | | Sholat Maghrib | Sholat Fardhu | 1x | | Sholat Isha | Sholat Fardhu | 1x | | Tilawah Quran | Tilawah | 1 Juz | | Dzikir Pagi | Dzikir | 1 session | | Dzikir Petang | Dzikir | 1 session | | Sholat Sunnah Rawatib | Sunnah | 1x | | Shodaqoh | Charity | 1x | #### Behavior - Checklist resets daily at midnight (new date key in Hive) - Checking/unchecking an item updates Hive immediately (no "save" button) - Progress card and percentage update reactively via Riverpod - Motivational quotes rotate from a bundled list - User can add/remove/reorder checklist items (edit mode) - Completion data written to `worship_logs` for use by Reports feature #### Acceptance Criteria - [ ] Default 10 items seeded on first launch - [ ] Checking item updates progress bar + percentage in real time - [ ] Data persists across app restarts (Hive) - [ ] New empty checklist created automatically on date change - [ ] Historical completion accessible by Reports feature --- ### 6.4 Dzikir **Route:** `/tools/dzikir` **Description:** Guided morning and evening remembrance (Dzikir) with Arabic text, transliteration, translation, and tap counter. #### UI Components **Header (sticky)** - `back arrow` + "Dzikir Pagi & Petang" (centered, `titleLarge font-bold`) + `info` icon button - `bg-surface/80`, `backdropFilter: blur(12dp)`, `borderBottom: 1dp primary/10` **Tab Bar** - 2 tabs: "Pagi" (Morning) and "Petang" (Evening) - Active tab: `border-bottom-2 border-primary`, `text-primary`, `font-semibold` - Inactive tab: `text-secondary` **Hero Banner** - `text-center`, `padding: 32dp vertical` - `bg-gradient(primary/5 → transparent, top → bottom)` - Title: "Dzikir Pagi / Petang" (`headlineMedium font-bold`) - Subtitle: context text in Indonesian (`bodySmall text-secondary max-width: 280dp`) **Dzikir Cards (scrollable list)** - Each card: `bg-surface`, `borderRadius: 16dp`, `border: 1dp primary/10`, `padding: 20dp`, `margin: 8dp bottom` - **Arabic text** (`Amiri font`, `24sp`, `RTL direction`, `line-height: 2.0`, `text-right`) - **Transliteration** (`bodySmall`, `italic`, `text-secondary`, `mt: 12dp`) - **Translation (Indonesian)** (`bodyMedium`, `text-primary`, `mt: 8dp`) - **Counter row:** - "Dibaca: {count} / {target}x" label - `+` tap button (`bg-primary/10`, `text-primary`, `borderRadius: full`, `size: 40dp`) - Counter increments on tap; fills to target - When target reached: button becomes `check_circle` (green), card shows completion glow #### Behavior - Default content: bundled local JSON with standard Dzikir Pagi (~20 items) and Dzikir Petang (~20 items) - Counter state persisted per dzikir per session in Hive (`dzikir_counters` box) - Counter resets daily (tied to date) - "Pagi" tab auto-selected between Fajr and Dhuhr; "Petang" between Maghrib and Isha; user can override - Info button → bottom sheet with brief explanation of dzikir practice #### Acceptance Criteria - [ ] Arabic text renders correctly with Amiri font, RTL direction - [ ] Tap counter increments and persists within the day - [ ] Counter resets the next day - [ ] Tab switches between Pagi and Petang content - [ ] Completion state shown when all counters reach target --- ### 6.5 Reports (Laporan) **Route:** `/laporan` **Description:** Visual analytics of worship completion across weekly, monthly, and yearly timeframes. #### UI Components **Header** - Back arrow + "Worship Quality Report" (centered) + `share` icon button **Tab Bar** - 3 tabs: Weekly · Monthly · Yearly - Active: `border-bottom-2 border-primary text-primary` - Tab bar: `border-bottom: 1dp` **Main Chart Card** - `bg-surface`, `borderRadius: 16dp`, `border: 1dp`, `padding: 20dp` - Header row: - Left: `analytics` icon badge (`bg-primary/10`, `primary`, `borderRadius: 12dp`, `40dp size`) - Center: "Daily Completion" label (`bodySmall text-secondary`) + percentage (`displayLarge font-bold`) - Right: trend chip: `trending_up` icon + delta % (`text-emerald-500` if positive) - **Bar Chart:** - `height: 160dp`, flex row of 7 bars (weekly) or 30/12 bars - Each bar: `Expanded`, `bg-primary/20` track, `bg-primary` fill overlay (proportional to % complete) - `borderRadius: top only (full)` - Day/date labels below (`10sp font-bold text-secondary uppercase`) - Tapping a bar → shows tooltip with exact date + completion % **Summary Stats Row (below chart)** - 3 stat cards in a row: - Best streak: "{n} days" + `local_fire_department` icon - Average: "{n}%" + `percent` icon - Total completed: "{n} tasks" + `check_circle` icon #### Behavior - Weekly: shows past 7 days (Mon–Sun of current week) - Monthly: shows all days of current month (30/31 bars, may need scroll) - Yearly: shows 12 months as bars - Data sourced from `worship_logs` Hive box (daily completion records) - Share button: generates a shareable image/text summary of current period stats #### Acceptance Criteria - [ ] Correct bar heights proportional to actual daily completion % - [ ] Tab switching updates chart data and labels - [ ] Tooltip on bar tap shows date + details - [ ] Summary stats calculated correctly from logs - [ ] Empty state when no logs exist ("Start tracking to see your progress") --- ### 6.6 Qibla Finder **Route:** `/tools/qibla` or `/qibla` (accessible from Dashboard hero card) **Description:** Compass-based Qibla direction finder showing the direction of Mecca. #### UI Components **Header** - Back arrow + "Qibla Finder" (centered) + `my_location` button (top-right, re-centers GPS) **Main Content (centered)** - Location display: `location_on` icon (primary) + city name + Qibla degree ("142.3° from North") - **Compass widget:** - Circular compass with N/S/E/W labels - Rotating needle pointing to Qibla direction - Mosque silhouette icon overlaid at compass center (fade-to-transparent mask top) - Green pointer / arrow indicating Qibla direction - Accuracy indicator: "High accuracy" / "Low accuracy" based on sensor confidence #### Behavior - Uses `flutter_qiblah` package for Qibla calculation + `flutter_compass` for device heading - Rotates compass ring based on device orientation (sensor stream) - Displays degree from North - If location permission denied → prompt to enable, fallback to manual city entry - Mosque silhouette uses a local SVG/image asset with `ShaderMask` fade #### Acceptance Criteria - [ ] Compass rotates smoothly with device orientation - [ ] Qibla arrow points to correct direction based on GPS coordinates - [ ] Works offline (no internet needed for calculation) - [ ] Graceful fallback if compass sensor unavailable --- ### 6.7 Quran Reading **Route:** `/tools/quran` → `/tools/quran/:surahId` **Description:** Full Quran reader with Arabic text, Indonesian translation, and verse-by-verse display. #### UI Components **Surah List Screen (`/tools/quran`)** - Search bar at top - `ListView` of 114 Surahs: number badge + Arabic name + Latin name + verse count + Juz info **Reading Screen (`/tools/quran/:surahId`)** Header (sticky, `bg-surface/80 backdrop-blur`): - Back arrow - Center column: Surah name (Arabic, `Amiri`) + "Juz {n}" label + verse count - `more_vert` menu (bookmarks, jump to verse, settings) **Bismillah banner:** Centered, Arabic font, before verse 1 (except Surah 9) **Verse Cards:** - Each verse: `Container`, `bg-surface`, `borderRadius: 12dp`, `padding: 16dp`, `border: 1dp` - Verse number badge: small circle, `bg-primary/10`, `primary text`, left-aligned - **Arabic text:** `Amiri`, `28sp`, `RTL`, `line-height: 2.2`, right-aligned, full width - **Transliteration** (optional, toggled in settings): `bodySmall italic text-secondary` - **Indonesian translation:** `bodyMedium text-primary`, left-aligned, `mt: 8dp` - Verse action row: `bookmark`, `share`, `play` (Murattal) icons #### Behavior - Quran data: bundled local JSON asset (`assets/quran/quran_id.json`) — 114 surahs, Arabic + Indonesian translation - Reading position persisted per Surah (last verse read) - Bookmarks stored in Hive - "Play" icon on verse → navigates to Murattal screen for that Surah starting at that verse - Font size adjustable via settings (stored preference) #### Acceptance Criteria - [ ] All 114 Surahs accessible - [ ] Arabic text renders with Amiri font, correct RTL layout - [ ] Indonesian translation displayed below each verse - [ ] Reading position saved across app restarts - [ ] Bookmarking a verse persists in Hive - [ ] Works fully offline --- ### 6.8 Quran Murattal **Route:** `/tools/quran/:surahId/murattal` **Description:** Audio recitation player synchronized with Quran text display. #### UI Components **Header:** Same as Quran Reading (Surah name + Juz info) **Quran Text:** Same as Reading screen — synchronized verse highlight follows audio playback **Audio Player (bottom persistent panel)** - Reciter name + surah name - Progress slider (current position / total duration) - `skip_previous` | `replay_10` | Play/Pause (`play_circle` / `pause_circle`, 56dp) | `forward_10` | `skip_next` - Playback speed selector (0.75x, 1x, 1.25x, 1.5x) - Sleep timer button #### Behavior - Audio source: Bundled MP3s for commonly used Surahs (short ones: Al-Fatihah, Juz Amma) — OR streamed from a free Quran audio API (e.g., mp3quran.net) - Currently playing verse highlighted with `primary/10 bg` + left border accent - Auto-scrolls to current verse during playback - Background audio playback (continues when app backgrounded) - Notification media controls shown in system tray during playback #### Acceptance Criteria - [ ] Audio plays and pauses correctly - [ ] Current verse highlighted in sync with audio (best effort with timed segments) - [ ] Background playback works (audio continues when screen off) - [ ] System notification with media controls displayed during playback - [ ] Playback speed adjustment works --- ### 6.9 Settings **Route:** `/settings` **Description:** User profile, notification preferences, display preferences, and app info. #### UI Components **Header (sticky)** - Back arrow + "Settings" (`titleLarge font-bold`) + no right action **Profile Section** - Avatar: 64dp circle, `bg-primary/20`, `border-2 border-primary`, initials or photo - Name: (`titleMedium font-bold`) - Email: (`bodySmall text-secondary`) - Edit button (`text-primary`, `edit` icon, top-right of card) → edit name/email inline **Notification Settings Group** Label: "NOTIFICATIONS" (`labelSmall uppercase tracking-wider sage color`) Rows (separated by thin divider): - **Adhan Notification** — per prayer toggle: Fajr, Dhuhr, Asr, Maghrib, Isha - **Iqamah Reminder** — offset in minutes (default: 10 min, stepper or picker) - **Daily Checklist Reminder** — time picker (default: 9:00 AM) Each row: `leading icon (bg-primary/10, rounded-lg, 40dp)` + `label + subtitle` + **iOS-style toggle** **iOS-style toggle spec:** - Size: `51dp × 31dp` - Track: `bg-cream (off)` / `bg-primary (on)`, `borderRadius: full` - Thumb: `27dp` white circle, `shadow-md`, animates left↔right on toggle - Implemented via `AnimatedContainer` + `GestureDetector` **Display Settings Group** Label: "DISPLAY" Rows: - **Dark Mode**: Light / Dark / Auto (3-way segmented control or cycle toggle) - **Font Size**: Small / Medium / Large (affects Quran + Dzikir text) - **Language**: Indonesian / English (UI language, not Quran translation) **About Group** Label: "ABOUT" Rows: - App Version: "Jamshalat Diary v1.0.0" - Privacy Policy (launches in-app browser) - Rate the App (links to store) - Contact / Feedback #### Behavior - All settings persisted in Hive `settings` box immediately on change - Dark mode change applies instantly (no restart needed) via ThemeMode Riverpod provider - Notification toggles register/unregister `flutter_local_notifications` channels - Iqamah offset: default 10 minutes, adjustable per prayer - Profile name/email stored locally only (no backend account system in v1.0) #### Acceptance Criteria - [ ] All toggle states persisted and restored on restart - [ ] Dark mode applies instantly with animation - [ ] Adhan/Iqamah notifications schedule correctly based on calculated prayer times - [ ] Notifications cancel when their toggle is turned off - [ ] iOS-style toggle animation is smooth (no jank) --- ## 7. Data Model ### 7.1 Hive Boxes & Schemas ```dart // Settings box (key-value) class AppSettings { String userName; // 'Alex Rivers' String userEmail; // 'alex@example.com' ThemeMode themeMode; // ThemeMode.system double arabicFontSize; // 24.0 String uiLanguage; // 'id' | 'en' Map adhanEnabled; // {'fajr': true, 'dhuhr': true, ...} Map iqamahOffset; // {'fajr': 15, 'dhuhr': 10, ...} in minutes DateTime? checklistReminderTime; double? lastLat; double? lastLng; String? lastCityName; } // Checklist box @HiveType(typeId: 1) class ChecklistItem { String id; // UUID String title; // 'Sholat Fajr' String category; // 'sholat_fardhu' String? subtitle; // '1 Juz' int sortOrder; bool isCustom; // false for default items } // Daily log box (keyed by 'yyyy-MM-dd') @HiveType(typeId: 2) class DailyWorshipLog { String date; // '2026-03-06' Map completedItems; // {'item_id': true} int totalItems; int completedCount; double completionPercent; } // Dzikir counter box (keyed by 'dzikir_id:yyyy-MM-dd') @HiveType(typeId: 3) class DzikirCounter { String dzikirId; String date; int count; int target; } // Bookmarks box @HiveType(typeId: 4) class QuranBookmark { int surahId; int verseId; String surahName; String verseText; // Arabic snippet DateTime savedAt; } // Cached prayer times box (keyed by 'lat_lng_yyyy-MM-dd') @HiveType(typeId: 5) class CachedPrayerTimes { String key; double lat; double lng; String date; DateTime fajr; DateTime sunrise; DateTime dhuhr; DateTime asr; DateTime maghrib; DateTime isha; } ``` --- ## 8. Third-Party Dependencies | Package | Version | Purpose | |---|---|---| | `flutter_riverpod` | ^2.x | State management | | `riverpod_annotation` | ^2.x | Code gen for providers | | `go_router` | ^13.x | Declarative navigation | | `hive_flutter` | ^1.x | Local key-value storage | | `hive_generator` | ^2.x | Hive TypeAdapter codegen | | `adhan` | ^1.x | Prayer time calculation (offline) | | `geolocator` | ^11.x | GPS location | | `geocoding` | ^3.x | Reverse geocoding (city name) | | `flutter_qiblah` | ^2.x | Qibla direction calculation | | `flutter_compass` | ^0.x | Device compass heading | | `flutter_local_notifications` | ^17.x | Adhan + Iqamah notifications | | `just_audio` | ^0.x | Quran Murattal audio playback | | `audio_service` | ^0.x | Background audio + media controls | | `google_fonts` | ^6.x | Plus Jakarta Sans | | `material_symbols_icons` | ^4.x | Material Symbols icon set | | `build_runner` | ^2.x | Code generation runner | **Quran Data Sources:** - Arabic text + Indonesian translation: bundled as `assets/quran/quran_id.json` (local, offline) - Audio (Murattal): streamed from `https://server6.mp3quran.net/` (Mishari Al-Afasy) or bundled short Surahs --- ## 9. Non-Functional Requirements ### 9.1 Performance - App cold start: < 2 seconds on mid-range devices (Snapdragon 700 series / Apple A14) - Bottom nav tab switch: < 150ms - Prayer time calculation: < 50ms (synchronous, offline) - Quran verse list render: use `ListView.builder` (lazy loading), never `ListView` with all children ### 9.2 Offline-First - Core features work with no internet: Dashboard, Checklist, Dzikir, Reports, Qibla, Quran Reading, Settings - Quran Murattal: short Surahs bundled; longer Surahs require connectivity (graceful fallback shown) - Prayer times: cached per location+date in Hive; recalculated on location change ### 9.3 Accessibility - Minimum touch target: 48×48dp for all interactive elements - All icons have semantic labels (`Semantics(label: ...)`) - Arabic text has `textDirection: TextDirection.rtl` explicitly set - Sufficient contrast ratios for both light and dark themes (WCAG AA) ### 9.4 Dark Mode - All screens must look correct in both light and dark mode - No hardcoded `Colors.white` or `Colors.black` — use `AppColors` tokens only - Theme transitions are animated (Material 3 `AnimatedTheme`) ### 9.5 Localization - v1.0: Indonesian (id) as primary language, English (en) as secondary - Use `flutter_localizations` + `intl` package for date/number formatting - All UI strings in `AppLocalizations` (ARB files); no hardcoded Indonesian strings in widgets --- ## 10. Permissions | Permission | Reason | Timing | |---|---|---| | `ACCESS_FINE_LOCATION` (Android) / `NSLocationWhenInUseUsageDescription` (iOS) | Prayer time calculation, Qibla direction | On first Dashboard load | | `POST_NOTIFICATIONS` (Android 13+) | Adhan and Iqamah notifications | On Settings → Notifications first toggle | | `SCHEDULE_EXACT_ALARM` (Android 12+) | Exact Adhan notification timing | When notification enabled | | Background audio (iOS: `audio` background mode) | Murattal background playback | On Murattal first play | **Permission UX:** - Never request permission without explaining why first (show rationale bottom sheet) - Graceful degradation: if location denied → manual city picker; if notifications denied → remind once, then respect --- ## 11. Out of Scope (v1.0) The following features are **explicitly excluded** from v1.0 to keep scope focused: - User accounts / cloud sync (no backend, local-only) - Social features (sharing worship progress to social media, leaderboards) - Full Quran audio library (only short Surahs bundled/streamed) - Quran memorization (Hafalan) mode - Hijri calendar widget beyond Imsakiyah - Community / forum features - Multi-user / family tracking - Wear OS / watchOS companion - Widgets (home screen app widget) - Apple Watch prayer time complication - In-app purchases or subscriptions - Push notifications from a server (only local scheduled notifications) --- *PRD v1.0 — Jamshalat Diary — March 2026*