- Murattal: Spotify-style 5-button controls [Shuffle, Prev, Play, Next, Playlist] - Murattal: Animated 7-bar equalizer visualization in player circle - Murattal: Unsplash API background with frosted glass player overlay - Murattal: Transparent AppBar with backdrop blur - Murattal: Surah playlist bottom sheet with full 114 Surah list - Murattal: Auto-play disabled on screen open, enabled on navigation - Murattal: Shuffle mode for random Surah playback - Murattal: Photographer attribution per Unsplash guidelines - Dashboard: Auto-scroll prayer schedule to next active prayer - Fix: setState lifecycle errors on Reading & Murattal screens - Setup: flutter_dotenv, cached_network_image, url_launcher deps
885 lines
32 KiB
Markdown
885 lines
32 KiB
Markdown
# 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<ThemeMode>`
|
||
|
||
### 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<ChecklistItem>` |
|
||
| `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<String, bool> adhanEnabled; // {'fajr': true, 'dhuhr': true, ...}
|
||
Map<String, int> 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<String, bool> 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*
|