Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

68 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

TicketFlow Launcher

TicketFlow

Help Desk Ticketing System

A clean, offline Flutter app for creating, tracking, and managing support tickets end-to-end.

License



Flutter Dart BLoC Feature--First Platform GetIt DI go_router

Stars Forks Issues Closed Issues Closed PRs

Repository Views

Download APK Β Β Β Β  Watch Demo


πŸ“‹ Table of Contents


πŸ”· Overview

Section
πŸ“– About the Project Overview
✨ Core Features Highlights
🎬 Demo Walkthrough

βš™οΈ Technical

Section
πŸ— Architecture Overview Feature-First Β· Cubit
πŸ“ Project Structure lib/ tree
βš’ Tech Stack & Dependencies Packages & Plugins
πŸš€ Setup Instructions Getting Started
⚠️ Assumptions & Limitations Notes

πŸ“¦ Resources

Section
πŸ“„ License All Rights Reserved

πŸ“– About the Project

TicketFlow is a mobile Help Desk Ticketing System built as a Flutter technical assessment project. It allows a user to create, browse, search, and manage support tickets from end to end β€” starting from a dashboard summarizing ticket statistics, down to full detail, edit, and delete operations on individual tickets.

Every ticket carries a subject, description, priority (Low / Medium / High), category (Technical / Billing / General), and status (Open / In Progress / Closed). All data is persisted on-device, so nothing is lost when the app is closed and reopened.

The project was built to demonstrate:

  • A scalable, feature-first project structure with clear separation of concerns
  • Predictable state management using Cubit
  • Type-safe error handling and offline-first local persistence
  • A consistent, reusable design system across screens

✨ Core Features

πŸ“Š Dashboard

  • Live summary cards: Total, Open, In Progress, and Closed tickets, computed from local storage

🎫 Ticket List & Discovery

  • Full ticket list showing ID, subject, priority, status, and created date
  • Debounced search by subject
  • Filter by status
  • Sort by created date

βž• Ticket Creation

  • Required Subject & Description fields with friendly validation errors
  • Priority selector: Low / Medium / High
  • Category selector: Technical / Billing / General
  • Auto-generated ticket number, creation date, and initial status (Open)

πŸ›  Ticket Details & Management

  • Full ticket detail view
  • Change status (Open β†’ In Progress β†’ Closed)
  • Edit subject, description, and priority
  • Delete ticket with a confirmation dialog

πŸ’Ύ Persistence & UX

  • Offline-first local storage via Hive CE β€” data survives app restarts
  • Proper loading, empty, and error states (with retry)
  • Responsive, consistent Material 3 design system

πŸ— Architecture Overview

TicketFlow follows a feature-first folder structure combined with a simplified Clean Architecture, using Cubit (from flutter_bloc) for state management and the Repository Pattern for full data-source abstraction.

                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚                       TICKETFLOW (Flutter App)                       β”‚
                  β”‚                                                                      β”‚
                  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
                  β”‚  β”‚  Feature-First  β”‚   β”‚   Cubit State    β”‚   β”‚   Hive CE Local  β”‚   β”‚
                  β”‚  β”‚  Clean Arch.    β”‚   β”‚    Management    β”‚   β”‚     Storage      β”‚   β”‚
                  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
                  β”‚                                                                      β”‚
                  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
                  β”‚  β”‚   go_router     β”‚   β”‚ Dio + Interceptorsβ”‚ β”‚    GetIt DI      β”‚    β”‚
                  β”‚  β”‚ Declarative Nav β”‚   β”‚ (wired, not yet   β”‚ β”‚ Service Locator  β”‚    β”‚
                  β”‚  β”‚                 β”‚   β”‚  connected to API)β”‚ β”‚                  β”‚    β”‚
                  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                     β”‚
                                                     β–Ό
                                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                      β”‚       On-Device Hive Boxes      β”‚
                                      β”‚    ticketsBox Β· settingsBox     β”‚
                                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Dependency direction: Views β†’ Cubits β†’ Repositories β†’ Data Sources β†’ Storage (Hive) β€” all dependencies point inward, and concrete implementations are injected via GetIt.

State Management Philosophy

Business logic is fully separated from the UI using Cubit, chosen over full Bloc since the app's actions are simple method calls (getAllTickets(), deleteTicketById(id)) with no need for explicit event classes. Each feature owns its own Cubit, registered as a Factory in GetIt so every route gets a fresh instance β€” preventing stale state between screens. BlocProviders are attached at the route level inside app_router.dart, not the widget tree.

Navigation

go_router handles all declarative routing, including passing data (like a selected TicketModel) via state.extra.

Dependency Injection

get_it manages all bindings: data sources and repositories are registered as LazySingleton (shared, stateless), while Cubits are registered as Factory (fresh per route).

Error Handling

Repositories wrap data-source calls and return Either<String, T> (from dartz), so Cubits never need to know about exception types β€” they simply fold on Left(error) or Right(data).


πŸ“ Project Structure

lib/
β”œβ”€β”€ app/                        # Root MaterialApp.router widget + sequential app initializer
β”‚
β”œβ”€β”€ core/                       # App-wide shared resources
β”‚   β”œβ”€β”€ common/                  # Reusable dialogs, snackbars, debouncer
β”‚   β”œβ”€β”€ constants/               # API endpoints, keys, app constants
β”‚   β”œβ”€β”€ di/                      # GetIt service locator setup
β”‚   β”œβ”€β”€ enums/                   # Rich enums: TicketPriority, TicketCategory, TicketStatus
β”‚   β”œβ”€β”€ errors/                  # Exceptions, handlers, unified ErrorModel
β”‚   β”œβ”€β”€ functions/               # Small utility helpers (date formatting, token building, etc.)
β”‚   β”œβ”€β”€ logging/                 # AppLogger + global BlocObserver
β”‚   β”œβ”€β”€ models/                  # Core TicketModel (Hive-annotated)
β”‚   β”œβ”€β”€ routes/                  # GoRouter configuration + navigation helpers
β”‚   β”œβ”€β”€ services/                # Hive & secure storage services, Dio network layer
β”‚   β”œβ”€β”€ utils/                   # Assets, colors, typography, spacing, radius, shadows, theme
β”‚   β”œβ”€β”€ validators/              # Form validators (subject, description, email, password)
β”‚   └── widgets/                 # Shared UI: chips, buttons, inputs, loading/empty/error states
β”‚
└── features/                   # Independent, self-contained feature modules
    β”œβ”€β”€ splash/                  # Animated splash β†’ navigates to Home
    β”œβ”€β”€ home/                    # Dashboard + ticket list entry screen
    β”œβ”€β”€ dashboard/               # Ticket statistics (data/presentation)
    β”œβ”€β”€ tickets/                 # Ticket list & ticket details (data/presentation)
    β”œβ”€β”€ ticket_form/             # Create/Edit ticket form (data/presentation)
    └── search/                  # Ticket search (data/presentation)

Feature Module Pattern

Every feature follows the same internal structure to ensure consistency and discoverability:

feature_name/
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ data_sources/          # Abstract interface + implementation (Hive/API)
β”‚   β”œβ”€β”€ models/                 # Feature-specific data models (if any)
β”‚   └── repos/                  # Abstract repository + implementation (returns Either)
└── presentation/
    β”œβ”€β”€ view_models/            # Cubits + States (business logic)
    └── views/                  # Screens & feature-specific widgets

βš’ Tech Stack & Dependencies

Core

Package Purpose
flutter_bloc State management (Cubit)
bloc Core bloc library required by flutter_bloc
go_router Declarative routing & deep linking
get_it Dependency injection (Service Locator)
dartz Functional programming β€” Either<L, R> types

Networking

Package Purpose
dio HTTP client with interceptors & timeouts β€” wired for future API use

Storage

Package Purpose
hive_ce / hive_ce_flutter Local NoSQL database β€” offline-first ticket persistence
flutter_secure_storage Encrypted storage reserved for auth tokens

UI & UX

Package Purpose
google_fonts Inter typography
flutter_svg SVG icon rendering
fl_chart Dashboard statistics charts
lottie Loading/empty state animations
device_preview Responsive testing across devices in dev

Utilities

Package Purpose
logger Color-coded console logging
intl Date formatting
uuid Unique ticket ID generation
meta Static analysis annotations (@immutable)
cupertino_icons iOS-style icon pack

Dev Dependencies

Package Purpose
flutter_lints Lint rules
build_runner Code generation orchestrator
hive_ce_generator Hive type adapter generator

πŸš€ Setup Instructions

Prerequisites

  • Flutter SDK with Dart β‰₯ 3.12.2
  • Android Studio or VS Code with the Flutter & Dart plugins
  • An Android/iOS emulator or a physical device

Steps

  1. Clone the repository

    git clone https://github.com/mohamed-dev-404/ticketflow.git
    cd ticketflow
  2. Install dependencies

    flutter pub get
  3. Generate Hive adapters (required β€” the app depends on generated *.g.dart files)

    dart run build_runner build --delete-conflicting-outputs
  4. Run the app

    flutter run

No .env file or backend configuration is required β€” TicketFlow runs fully offline out of the box.


🎬 Demo

πŸŽ₯ Watch the full app walkthrough (Google Drive)

Dashboard, ticket list with search/filter/sort, ticket creation, and full ticket detail/edit/delete flow.


⚠️ Assumptions & Limitations

  • Offline-first by design: all ticket data is persisted locally via Hive CE. The Dio-based network layer (interceptors, auth handling, endpoints) is fully wired but intentionally not connected to a live backend yet β€” it's scaffolded for future API integration.
  • Light theme only: dark mode is not implemented in the current version; the design system (colors, typography, spacing) is structured to support it later with minimal changes.
  • Ticket numbers are generated client-side via uuid, not by a remote server.
  • Text scaling is locked to 1.0 app-wide so ticket cards and chips stay consistent regardless of the device's system font-size setting.
  • Single device, no sync: since there's no backend in use, tickets live only in the Hive box on the device the app is installed on.
  • No authentication or roles yet: the app currently has no permission system β€” there's a single implicit role, and the user who opens a ticket is the same one expected to close it themselves. Multi-role permissions (e.g. agent vs. requester) will be introduced once a backend and authentication layer are added.

πŸ“„ License

All Rights Reserved Β© 2026 β€” Mohamed Ibrahim

This project β€” including all source code and documentation β€” was developed as part of a Flutter developer technical assessment and is shared for review and evaluation purposes only.

No part of this project may be copied, modified, redistributed, or reused for academic or commercial purposes without prior written permission from the author.


Made with ❀️ using Flutter

About

Flutter technical assessment project implementing a Help Desk Ticketing System with BLoC, Repository Pattern, Hive, and scalable Feature-First architecture.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages