/opt/canhelp/apps/mobile/lib/screens/home
NameSizeModeActions
become_specialist_screen.dart131970644editdlrm
home_screen.dart597720644editdlrm
main_shell.dart81140644editdlrm
Edit: /opt/canhelp/apps/mobile/lib/screens/home/become_specialist_screen.dart (13197B)
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; import '../../providers/auth_provider.dart'; import '../../providers/locale_provider.dart'; import '../../services/api_client.dart'; import '../../theme/app_theme.dart'; class BecomeSpecialistScreen extends StatefulWidget { const BecomeSpecialistScreen({super.key}); @override State createState() => _BecomeSpecialistScreenState(); } class _BecomeSpecialistScreenState extends State { bool _loading = false; String? _error; Future _handleCta() async { final auth = context.read(); if (!auth.isAuthenticated) { context.push('/register?role=specialist'); return; } setState(() { _loading = true; _error = null; }); try { await ApiClient().becomeSpecialist(); await auth.refreshUser(); if (mounted) context.go('/specialist-setup'); } catch (e) { setState(() { _error = context.read().t('common.error'); _loading = false; }); } } @override Widget build(BuildContext context) { final locale = context.watch(); final t = locale.t; final auth = context.watch(); final isSpecialist = auth.user?.role == 'specialist'; // Already a specialist → redirect to setup if (isSpecialist) { WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) context.go('/specialist-setup'); }); } final steps = [ ( icon: Icons.badge_outlined, title: t('become_specialist.step1.title'), desc: t('become_specialist.step1.desc'), ), ( icon: Icons.search_rounded, title: t('become_specialist.step2.title'), desc: t('become_specialist.step2.desc'), ), ( icon: Icons.payments_outlined, title: t('become_specialist.step3.title'), desc: t('become_specialist.step3.desc'), ), ]; final benefits = [ (icon: Icons.location_on_outlined, text: t('become_specialist.benefit1')), (icon: Icons.star_outline_rounded, text: t('become_specialist.benefit2')), ( icon: Icons.calendar_month_outlined, text: t('become_specialist.benefit3'), ), ( icon: Icons.favorite_outline_rounded, text: t('become_specialist.benefit4'), ), ]; return Scaffold( backgroundColor: AppTheme.background, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, scrolledUnderElevation: 0, leading: IconButton( icon: const Icon(Icons.arrow_back_ios_new_rounded, size: 20), color: AppTheme.textPrimary, style: IconButton.styleFrom( backgroundColor: Colors.white.withValues(alpha: 0.85), ), onPressed: () => context.canPop() ? context.pop() : context.go('/'), ), ), extendBodyBehindAppBar: true, body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // ── Hero ────────────────────────────────────────────────────── Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFF1A4FBA), Color(0xFF1E6AE1)], ), ), padding: const EdgeInsets.fromLTRB(24, 100, 24, 40), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 4, ), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(AppTheme.chipRadius), ), child: Text( t('become_specialist.free_badge'), style: const TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.w600, ), ), ), const SizedBox(height: 16), Text( t('become_specialist.hero.title'), style: const TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold, height: 1.2, ), ), const SizedBox(height: 12), Text( t('become_specialist.hero.subtitle'), style: TextStyle( color: Colors.white.withValues(alpha: 0.9), fontSize: 16, height: 1.5, ), ), ], ), ), // ── How it works ───────────────────────────────────────────── Padding( padding: const EdgeInsets.fromLTRB(24, 32, 24, 8), child: Text( t('become_specialist.how.title'), style: Theme.of( context, ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), ), ), for (int i = 0; i < steps.length; i++) ...[ _StepTile( number: i + 1, icon: steps[i].icon, title: steps[i].title, desc: steps[i].desc, ), ], // ── Benefits ────────────────────────────────────────────────── Padding( padding: const EdgeInsets.fromLTRB(24, 28, 24, 12), child: Text( t('become_specialist.benefits.title'), style: Theme.of( context, ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Wrap( spacing: 12, runSpacing: 12, children: [ for (final b in benefits) _BenefitChip(icon: b.icon, text: b.text), ], ), ), // ── Error ───────────────────────────────────────────────────── if (_error != null) Padding( padding: const EdgeInsets.fromLTRB(24, 20, 24, 0), child: Text( _error!, style: const TextStyle(color: AppTheme.danger, fontSize: 14), textAlign: TextAlign.center, ), ), // ── CTA ─────────────────────────────────────────────────────── Padding( padding: const EdgeInsets.fromLTRB(24, 28, 24, 48), child: FilledButton( onPressed: _loading ? null : _handleCta, style: FilledButton.styleFrom( backgroundColor: AppTheme.primary, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppTheme.buttonRadius), ), ), child: _loading ? const SizedBox( width: 22, height: 22, child: CircularProgressIndicator( strokeWidth: 2.5, color: Colors.white, ), ) : Text( auth.isAuthenticated ? t('profile.becomeSpecialist') : t('nav.register'), style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ), ], ), ), ); } } // ───────────────────────────────────────────────────────────────────────────── class _StepTile extends StatelessWidget { final int number; final IconData icon; final String title; final String desc; const _StepTile({ required this.number, required this.icon, required this.title, required this.desc, }); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), child: Container( decoration: BoxDecoration( color: AppTheme.surface, borderRadius: BorderRadius.circular(AppTheme.cardRadius), border: Border.all(color: AppTheme.border), ), padding: const EdgeInsets.all(16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( alignment: Alignment.bottomRight, children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: AppTheme.primary.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(AppTheme.smallRadius), ), child: Icon(icon, color: AppTheme.primary, size: 24), ), Container( width: 18, height: 18, decoration: const BoxDecoration( color: AppTheme.primary, shape: BoxShape.circle, ), alignment: Alignment.center, child: Text( '$number', style: const TextStyle( color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( fontWeight: FontWeight.w700, fontSize: 15, color: AppTheme.textPrimary, ), ), const SizedBox(height: 4), Text( desc, style: const TextStyle( fontSize: 13, color: AppTheme.textSecondary, height: 1.4, ), ), ], ), ), ], ), ), ); } } class _BenefitChip extends StatelessWidget { final IconData icon; final String text; const _BenefitChip({required this.icon, required this.text}); @override Widget build(BuildContext context) { final w = (MediaQuery.of(context).size.width - 16 * 2 - 12) / 2; return SizedBox( width: w, child: Container( decoration: BoxDecoration( color: AppTheme.surface, borderRadius: BorderRadius.circular(AppTheme.cardRadius), border: Border.all(color: AppTheme.border), ), padding: const EdgeInsets.all(14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(icon, color: AppTheme.primary, size: 22), const SizedBox(height: 8), Text( text, style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w600, color: AppTheme.textPrimary, height: 1.3, ), ), ], ), ), ); } }