feat: improve patient flow and pricing workflow
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '../l10n/app_strings.dart';
|
||||
import '../providers/locale_provider.dart';
|
||||
import '../theme/app_theme.dart';
|
||||
import '../widgets/tooth_logo.dart';
|
||||
import '../providers/auth_provider.dart';
|
||||
@@ -213,63 +215,60 @@ class _ClinicShell extends ConsumerStatefulWidget {
|
||||
class _ClinicShellState extends ConsumerState<_ClinicShell> {
|
||||
String _selectedRoute = routeClinicDashboard;
|
||||
|
||||
// Top-level singles before groups
|
||||
static final _topSingles = [
|
||||
_NavItem(route: routeClinicDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: 'Ana Sayfa', visible: (_) => true),
|
||||
_NavItem(route: routeClinicJobs, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: 'İşler', visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeClinicPatients, icon: const Icon(Icons.people_outline_rounded), selectedIcon: const Icon(Icons.people_rounded), label: 'Hastalar', visible: (m) => m?.showPatients ?? true),
|
||||
_NavItem(route: routeClinicFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: 'Finans', visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeClinicAi, icon: const Icon(Icons.auto_awesome_outlined), selectedIcon: const Icon(Icons.auto_awesome_rounded), label: 'AI Sohbet', visible: (_) => true),
|
||||
];
|
||||
List<_NavItem> _clinicTopSingles(AppStrings s) => [
|
||||
_NavItem(route: routeClinicDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: s.homeTitle, visible: (_) => true),
|
||||
_NavItem(route: routeClinicJobs, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: s.jobsTitle, visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeClinicPatients, icon: const Icon(Icons.people_outline_rounded), selectedIcon: const Icon(Icons.people_rounded), label: s.patientsTitle, visible: (m) => m?.showPatients ?? true),
|
||||
_NavItem(route: routeClinicFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: s.finance, visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeClinicAi, icon: const Icon(Icons.auto_awesome_outlined), selectedIcon: const Icon(Icons.auto_awesome_rounded), label: s.aiAssistant, visible: (_) => true),
|
||||
];
|
||||
|
||||
// Dropdown groups
|
||||
static final _groups = [
|
||||
_NavGroup(
|
||||
title: 'Yönetim',
|
||||
icon: Icons.tune_rounded,
|
||||
selectedIcon: Icons.tune_rounded,
|
||||
items: [
|
||||
_NavItem(route: routeClinicConnections, icon: const Icon(Icons.link_rounded), selectedIcon: const Icon(Icons.link_rounded), label: 'Bağlantılar', visible: (_) => true),
|
||||
_NavItem(route: routeClinicReports, icon: const Icon(Icons.bar_chart_outlined), selectedIcon: const Icon(Icons.bar_chart_rounded), label: 'Raporlar', visible: (_) => true),
|
||||
],
|
||||
),
|
||||
];
|
||||
List<_NavGroup> _clinicGroups(AppStrings s) => [
|
||||
_NavGroup(
|
||||
title: s.management,
|
||||
icon: Icons.tune_rounded,
|
||||
selectedIcon: Icons.tune_rounded,
|
||||
items: [
|
||||
_NavItem(route: routeClinicConnections, icon: const Icon(Icons.link_rounded), selectedIcon: const Icon(Icons.link_rounded), label: s.connections, visible: (_) => true),
|
||||
_NavItem(route: routeClinicReports, icon: const Icon(Icons.bar_chart_outlined), selectedIcon: const Icon(Icons.bar_chart_rounded), label: s.reports, visible: (_) => true),
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
// Singles after groups
|
||||
static final _bottomSingles = [
|
||||
_NavItem(route: routeClinicSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: 'Ayarlar', visible: (_) => true),
|
||||
];
|
||||
List<_NavItem> _clinicBottomSingles(AppStrings s) => [
|
||||
_NavItem(route: routeClinicSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: s.settings, visible: (_) => true),
|
||||
];
|
||||
|
||||
// Mobile bottom nav: core items; others accessed from settings
|
||||
static final _mobileItems = [
|
||||
_NavItem(route: routeClinicDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: 'Ana Sayfa', visible: (_) => true),
|
||||
_NavItem(route: routeClinicJobs, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: 'İşler', visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeClinicPatients, icon: const Icon(Icons.people_outline_rounded), selectedIcon: const Icon(Icons.people_rounded), label: 'Hastalar', visible: (m) => m?.showPatients ?? true),
|
||||
_NavItem(route: routeClinicFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: 'Finans', visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeClinicSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: 'Ayarlar', visible: (_) => true),
|
||||
];
|
||||
List<_NavItem> _clinicMobileItems(AppStrings s) => [
|
||||
_NavItem(route: routeClinicDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: s.homeTitle, visible: (_) => true),
|
||||
_NavItem(route: routeClinicJobs, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: s.jobsTitle, visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeClinicPatients, icon: const Icon(Icons.people_outline_rounded), selectedIcon: const Icon(Icons.people_rounded), label: s.patientsTitle, visible: (m) => m?.showPatients ?? true),
|
||||
_NavItem(route: routeClinicFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: s.finance, visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeClinicSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: s.settings, visible: (_) => true),
|
||||
];
|
||||
|
||||
List<_SidebarEntry> _allEntries() {
|
||||
List<_SidebarEntry> _allEntries(AppStrings s) {
|
||||
final membership = ref.read(authProvider).activeTenant;
|
||||
final entries = <_SidebarEntry>[];
|
||||
for (final s in _topSingles) {
|
||||
if (s.visible(membership)) entries.add(_SidebarSingleEntry(s));
|
||||
for (final item in _clinicTopSingles(s)) {
|
||||
if (item.visible(membership)) entries.add(_SidebarSingleEntry(item));
|
||||
}
|
||||
for (final g in _groups) {
|
||||
if (g.hasVisible(membership)) entries.add(_SidebarGroupEntry(g));
|
||||
for (final group in _clinicGroups(s)) {
|
||||
if (group.hasVisible(membership)) entries.add(_SidebarGroupEntry(group));
|
||||
}
|
||||
for (final s in _bottomSingles) {
|
||||
if (s.visible(membership)) entries.add(_SidebarSingleEntry(s));
|
||||
for (final item in _clinicBottomSingles(s)) {
|
||||
if (item.visible(membership)) entries.add(_SidebarSingleEntry(item));
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = ref.watch(stringsProvider);
|
||||
final isDesktop = MediaQuery.sizeOf(context).width > AppLayout.sidebarBreakpoint;
|
||||
|
||||
if (isDesktop) {
|
||||
final entries = _allEntries();
|
||||
final entries = _allEntries(s);
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: Row(
|
||||
@@ -290,7 +289,7 @@ class _ClinicShellState extends ConsumerState<_ClinicShell> {
|
||||
|
||||
// Mobile: only core items in bottom nav
|
||||
final membership = ref.read(authProvider).activeTenant;
|
||||
final items = _mobileItems.where((it) => it.visible(membership)).toList();
|
||||
final items = _clinicMobileItems(s).where((it) => it.visible(membership)).toList();
|
||||
final flatIndex = items.indexWhere((it) => it.route == _selectedRoute);
|
||||
final clampedIndex = flatIndex >= 0 ? flatIndex : 0;
|
||||
|
||||
@@ -339,64 +338,61 @@ class _LabShell extends ConsumerStatefulWidget {
|
||||
class _LabShellState extends ConsumerState<_LabShell> {
|
||||
String _selectedRoute = routeLabDashboard;
|
||||
|
||||
// Top-level singles before groups
|
||||
static final _topSingles = [
|
||||
_NavItem(route: routeLabDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: 'Ana Sayfa', visible: (_) => true),
|
||||
_NavItem(route: routeLabJobsAll, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: 'İşler', visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeLabProducts, icon: const Icon(Icons.inventory_2_outlined), selectedIcon: const Icon(Icons.inventory_2_rounded), label: 'Ürünler', visible: (m) => m?.showProducts ?? true),
|
||||
_NavItem(route: routeLabFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: 'Finans', visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeLabAi, icon: const Icon(Icons.auto_awesome_outlined), selectedIcon: const Icon(Icons.auto_awesome_rounded), label: 'AI Sohbet', visible: (_) => true),
|
||||
];
|
||||
List<_NavItem> _labTopSingles(AppStrings s) => [
|
||||
_NavItem(route: routeLabDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: s.homeTitle, visible: (_) => true),
|
||||
_NavItem(route: routeLabJobsAll, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: s.jobsTitle, visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeLabProducts, icon: const Icon(Icons.inventory_2_outlined), selectedIcon: const Icon(Icons.inventory_2_rounded), label: s.productsTitle, visible: (m) => m?.showProducts ?? true),
|
||||
_NavItem(route: routeLabFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: s.finance, visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeLabAi, icon: const Icon(Icons.auto_awesome_outlined), selectedIcon: const Icon(Icons.auto_awesome_rounded), label: s.aiAssistant, visible: (_) => true),
|
||||
];
|
||||
|
||||
// Dropdown groups
|
||||
static final _groups = [
|
||||
_NavGroup(
|
||||
title: 'Yönetim',
|
||||
icon: Icons.tune_rounded,
|
||||
selectedIcon: Icons.tune_rounded,
|
||||
items: [
|
||||
_NavItem(route: routeLabConnections, icon: const Icon(Icons.link_rounded), selectedIcon: const Icon(Icons.link_rounded), label: 'Bağlantılar', visible: (_) => true),
|
||||
_NavItem(route: routeLabDiscounts, icon: const Icon(Icons.local_offer_outlined), selectedIcon: const Icon(Icons.local_offer_rounded), label: 'İndirimler', visible: (_) => true),
|
||||
_NavItem(route: routeLabReports, icon: const Icon(Icons.bar_chart_outlined), selectedIcon: const Icon(Icons.bar_chart_rounded), label: 'Raporlar', visible: (_) => true),
|
||||
],
|
||||
),
|
||||
];
|
||||
List<_NavGroup> _labGroups(AppStrings s) => [
|
||||
_NavGroup(
|
||||
title: s.management,
|
||||
icon: Icons.tune_rounded,
|
||||
selectedIcon: Icons.tune_rounded,
|
||||
items: [
|
||||
_NavItem(route: routeLabConnections, icon: const Icon(Icons.link_rounded), selectedIcon: const Icon(Icons.link_rounded), label: s.connections, visible: (_) => true),
|
||||
_NavItem(route: routeLabDiscounts, icon: const Icon(Icons.local_offer_outlined), selectedIcon: const Icon(Icons.local_offer_rounded), label: s.discounts, visible: (_) => true),
|
||||
_NavItem(route: routeLabReports, icon: const Icon(Icons.bar_chart_outlined), selectedIcon: const Icon(Icons.bar_chart_rounded), label: s.reports, visible: (_) => true),
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
// Singles after groups
|
||||
static final _bottomSingles = [
|
||||
_NavItem(route: routeLabSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: 'Ayarlar', visible: (_) => true),
|
||||
];
|
||||
List<_NavItem> _labBottomSingles(AppStrings s) => [
|
||||
_NavItem(route: routeLabSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: s.settings, visible: (_) => true),
|
||||
];
|
||||
|
||||
// Mobile bottom nav: core items; others accessed from settings
|
||||
static final _mobileItems = [
|
||||
_NavItem(route: routeLabDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: 'Ana Sayfa', visible: (_) => true),
|
||||
_NavItem(route: routeLabJobsAll, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: 'İşler', visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeLabProducts, icon: const Icon(Icons.inventory_2_outlined), selectedIcon: const Icon(Icons.inventory_2_rounded), label: 'Ürünler', visible: (m) => m?.showProducts ?? true),
|
||||
_NavItem(route: routeLabFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: 'Finans', visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeLabSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: 'Ayarlar', visible: (_) => true),
|
||||
];
|
||||
List<_NavItem> _labMobileItems(AppStrings s) => [
|
||||
_NavItem(route: routeLabDashboard, icon: const Icon(Icons.home_outlined), selectedIcon: const Icon(Icons.home_rounded), label: s.homeTitle, visible: (_) => true),
|
||||
_NavItem(route: routeLabJobsAll, icon: const Icon(Icons.work_outline_rounded), selectedIcon: const Icon(Icons.work_rounded), label: s.jobsTitle, visible: (m) => m?.showJobs ?? true),
|
||||
_NavItem(route: routeLabProducts, icon: const Icon(Icons.inventory_2_outlined), selectedIcon: const Icon(Icons.inventory_2_rounded), label: s.productsTitle, visible: (m) => m?.showProducts ?? true),
|
||||
_NavItem(route: routeLabFinance, icon: const Icon(Icons.account_balance_outlined), selectedIcon: const Icon(Icons.account_balance_rounded), label: s.finance, visible: (m) => m?.showFinance ?? true),
|
||||
_NavItem(route: routeLabSettings, icon: const Icon(Icons.settings_outlined), selectedIcon: const Icon(Icons.settings_rounded), label: s.settings, visible: (_) => true),
|
||||
];
|
||||
|
||||
List<_SidebarEntry> _allEntries() {
|
||||
List<_SidebarEntry> _allEntries(AppStrings s) {
|
||||
final membership = ref.read(authProvider).activeTenant;
|
||||
final entries = <_SidebarEntry>[];
|
||||
for (final s in _topSingles) {
|
||||
if (s.visible(membership)) entries.add(_SidebarSingleEntry(s));
|
||||
for (final item in _labTopSingles(s)) {
|
||||
if (item.visible(membership)) entries.add(_SidebarSingleEntry(item));
|
||||
}
|
||||
for (final g in _groups) {
|
||||
if (g.hasVisible(membership)) entries.add(_SidebarGroupEntry(g));
|
||||
for (final group in _labGroups(s)) {
|
||||
if (group.hasVisible(membership)) entries.add(_SidebarGroupEntry(group));
|
||||
}
|
||||
for (final s in _bottomSingles) {
|
||||
if (s.visible(membership)) entries.add(_SidebarSingleEntry(s));
|
||||
for (final item in _labBottomSingles(s)) {
|
||||
if (item.visible(membership)) entries.add(_SidebarSingleEntry(item));
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = ref.watch(stringsProvider);
|
||||
final isDesktop = MediaQuery.sizeOf(context).width > AppLayout.sidebarBreakpoint;
|
||||
|
||||
if (isDesktop) {
|
||||
final entries = _allEntries();
|
||||
final entries = _allEntries(s);
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.background,
|
||||
body: Row(
|
||||
@@ -417,7 +413,7 @@ class _LabShellState extends ConsumerState<_LabShell> {
|
||||
|
||||
// Mobile: only core items in bottom nav
|
||||
final membership = ref.read(authProvider).activeTenant;
|
||||
final items = _mobileItems.where((it) => it.visible(membership)).toList();
|
||||
final items = _labMobileItems(s).where((it) => it.visible(membership)).toList();
|
||||
final flatIndex = items.indexWhere((it) => it.route == _selectedRoute);
|
||||
final clampedIndex = flatIndex >= 0 ? flatIndex : 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user