{"id":50789880,"url":"https://github.com/thecodedaniel/tech_gadol","last_synced_at":"2026-06-12T10:03:28.276Z","repository":{"id":344705241,"uuid":"1182762252","full_name":"TheCodeDaniel/tech_gadol","owner":"TheCodeDaniel","description":"Tech Gadol mobile app","archived":false,"fork":false,"pushed_at":"2026-03-16T02:45:48.000Z","size":350,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-16T11:39:49.639Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheCodeDaniel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-15T23:38:12.000Z","updated_at":"2026-03-16T02:45:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/TheCodeDaniel/tech_gadol","commit_stats":null,"previous_names":["thecodedaniel/tech_gadol"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/TheCodeDaniel/tech_gadol","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheCodeDaniel%2Ftech_gadol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheCodeDaniel%2Ftech_gadol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheCodeDaniel%2Ftech_gadol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheCodeDaniel%2Ftech_gadol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheCodeDaniel","download_url":"https://codeload.github.com/TheCodeDaniel/tech_gadol/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheCodeDaniel%2Ftech_gadol/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34238716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-12T10:03:27.320Z","updated_at":"2026-06-12T10:03:28.265Z","avatar_url":"https://github.com/TheCodeDaniel.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tech Gadol — Product Catalog App\n\nA Flutter application that displays a product catalog using a custom design system, consuming data from the DummyJSON Products API.\n\n## 1. Setup \u0026 Run Instructions\n\n**Flutter version:** 3.35.3 (stable channel)\n\n```bash\n# Clone the repository\ngit clone \u003crepo-url\u003e\ncd tech_gadol\n\n# Install dependencies\nflutter pub get\n\n# Run the app\nflutter run\n\n# Run tests\nflutter test\n\n# Run analysis\nflutter analyze\n```\n\nNo additional setup is required. The app uses the public DummyJSON API (`https://dummyjson.com`) — no API keys or environment variables needed.\n\n## 2. Architecture Overview\n\n### Folder Structure\n\n```\nlib/\n├── core/\n│   ├── extensions/          # BuildContext extensions (responsive breakpoints)\n│   ├── routing/             # GoRouter config + centralized route paths\n│   ├── services/\n│   │   ├── api_services/    # Dio HTTP client, connectivity wrapper, API constants\n│   │   └── local_storage_services/  # Hive-based product cache\n│   ├── theme/               # AppColors, LightTheme, DarkTheme\n│   └── widgets/             # Design system components (reusable across features)\n├── features/\n│   ├── products/\n│   │   ├── data/\n│   │   │   ├── models/      # ProductModel, ProductsResponse\n│   │   │   └── repositories/ # ProductRepository (API + cache integration)\n│   │   └── presentation/\n│   │       ├── bloc/         # ProductsBloc, events, state\n│   │       └── views/        # Screens (list, detail, responsive layout)\n│   └── showcase/\n│       └── presentation/views/  # Component showcase screen\n├── app.dart                  # Root widget with BLoC providers + MaterialApp.router\n└── main.dart                 # Entry point + Hive init\n```\n\n### Architecture Pattern\n\n**Feature-first** with clean separation of data and presentation layers per feature:\n\n- **Data layer:** Models with JSON parsing + validation, Repository pattern wrapping API calls with caching\n- **Presentation layer:** BLoC for state management, screens consume state via `BlocBuilder`\n\n### State Management\n\n**BLoC (flutter_bloc)** with Equatable for predictable, testable state:\n\n- Single `ProductsBloc` manages products, categories, search, pagination, and product selection\n- All states handled explicitly: `initial`, `loading`, `loaded`, `error`\n- Timer-based search debounce (300ms) — no extra dependency\n- Combined search + category filtering (client-side filtering when both active, since DummyJSON doesn't support this server-side)\n\n### Navigation\n\n**GoRouter** with centralized route definitions in `AppRoutes`:\n\n- `/products` — product list (responsive layout)\n- `/products/:id` — product detail (deep linking supported)\n- `/showcase` — component showcase (debug)\n- Responsive master-detail layout handled at the routing level: wide screens (≥768px) show side-by-side, narrow screens use push navigation\n\n### Networking\n\n**Dio** singleton with:\n\n- Per-request cancel tokens\n- Comprehensive error mapping (`ErrorEntity`)\n- Connectivity check before every request (via `connectivity_plus`)\n- Toast notification when offline\n- Repository-level `try/catch` with `debugPrintStack` for traceability\n\n## 3. Design System Rationale\n\n### Component API\n\nAll design system widgets live in `core/widgets/` and are theme-aware (they read colors/styles from `Theme.of(context)` rather than hardcoding values):\n\n| Component | Purpose |\n|---|---|\n| `AppSearchBar` | Text field with clear button, delegates debounce to BLoC |\n| `CategoryChip` | `FilterChip` that formats slug labels (e.g. `smart-phones` → `Smart Phones`) |\n| `ProductCard` | Horizontal card with thumbnail, title, brand, price, rating, stock indicator |\n| `PriceTag` | Displays price with discount badge; shows \"Price unavailable\" for invalid prices |\n| `RatingBar` | 5-star display with half-star support |\n| `CachedImage` | `CachedNetworkImage` wrapper with loading spinner and error placeholder |\n| `ShimmerLoading` | Skeleton placeholder cards matching `ProductCard` layout |\n| `ErrorState` | Error icon + message + retry button |\n| `EmptyState` | Empty results icon + message |\n| `StaggeredListItem` | Fade+slide animation wrapper for list items |\n\n### Theming\n\n- Full light and dark themes using Material 3 (`ColorScheme`, text theme, card/chip/input decoration themes)\n- System theme mode by default (`ThemeMode.system`)\n- Showcase screen includes an independent light/dark toggle for testing\n\n### Data Validation\n\nHandled in `ProductModel.fromJson` with sensible defaults:\n\n- Missing brand → `\"Unknown brand\"` + warning log\n- Missing/negative price → stored as `-1`, UI shows `\"Price unavailable\"` + error log\n- Invalid image URLs → filtered out + warning log\n- Missing title → `\"Untitled Product\"`\n- Rating → clamped between 0–5\n\n## 4. Limitations\n\nWith more time, I would improve:\n\n- **Domain layer:** Add use cases (e.g. `GetProductsUseCase`) and repository interfaces for full clean architecture\n- **Theme:** Better custom animations with better optimization (I was not the most productive in this few hours)\n- **Dependency injection:** Use `get_it` or `injectable` instead of manual constructor injection\n- **Search + category:** Currently does client-side filtering when both are active. Ideally the API would support this natively\n- **Offline support depth:** Currently only caches the first page of products and categories. Could cache all paginated pages and individual product details\n- **Test coverage:** Add integration tests, golden tests for design system components, and test the responsive layout breakpoints\n- **Accessibility:** Add semantic labels to images, ensure proper contrast ratios\n- **Error messages:** Make user-facing error messages more specific (network timeout vs server error vs no internet)\n\n## 5. AI Tools Usage\n\nThe AI mainly used was claude,\nit was a fair experience, used to help me cut down development time alot,\nbut it made the following mistakes:\n- Wrong theme usage on the app\n- Incomplete error handling on API calls\n- Wrong use of Hero widgets that threw exceptions all of the console\n\nSo, for some, I had to manually edit or re-query giving out specific guideliness on how to edit and go about them.\n\n\u003c!-- Fill in your own experience here --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthecodedaniel%2Ftech_gadol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthecodedaniel%2Ftech_gadol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthecodedaniel%2Ftech_gadol/lists"}