import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/auth/auth_notifier.dart'; import '../../core/theme/halo_tokens.dart'; import '../home/widgets/halo_tab_bar.dart'; /// "Kamu" tab — profile screen. /// /// Mirrors Figma `SProfile` (see `requirement/Figma/screens/extras.jsx::SProfile`): /// user card → menu list (kontak / syarat / privasi) → action button → version. /// /// The action button differs from Figma: we ship **logout** here instead of /// the "hapus akun" CTA from the mockup. Account deletion is a deeper flow /// (confirmation, server-side data removal, refund policy) and is not in /// scope yet. class ProfileScreen extends ConsumerWidget { const ProfileScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final authData = ref.watch(authProvider).valueOrNull; final (name, phone) = switch (authData) { AuthAuthenticatedData d => ( (d.profile['display_name'] as String?) ?? 'kamu', _maskPhone(d.profile['phone'] as String?), ), AuthAnonymousData d => ( d.displayName.isEmpty ? 'kamu' : d.displayName, 'akun anonim', ), _ => ('kamu', null), }; return Scaffold( backgroundColor: HaloTokens.bg, body: SafeArea( bottom: false, child: Column( children: [ Expanded( child: ListView( padding: const EdgeInsets.fromLTRB(24, 20, 24, 16), children: [ const Text( 'kamu', style: TextStyle( fontFamily: HaloTokens.fontDisplay, fontSize: 26, fontWeight: FontWeight.w700, color: HaloTokens.brandDark, letterSpacing: -0.52, ), ), const SizedBox(height: 18), _UserCard(name: name, phone: phone), const SizedBox(height: 20), _MenuCard(items: [ _MenuItemData( icon: Icons.mail_outline, label: 'kontak kami', sub: 'halo@halobestie.id', onTap: () {}, ), _MenuItemData( icon: Icons.description_outlined, label: 'syarat & ketentuan', onTap: () {}, ), _MenuItemData( icon: Icons.lock_outline, label: 'kebijakan privasi', onTap: () {}, ), ]), const SizedBox(height: 16), _LogoutButton( onTap: () => _confirmLogout(context, ref), ), const SizedBox(height: 20), const Center( child: Text( 'HaloBestie · v1.0.0', style: TextStyle( fontFamily: HaloTokens.fontBody, fontSize: 11, color: HaloTokens.inkMuted, ), ), ), ], ), ), const HaloTabBar(active: 'kamu'), ], ), ), ); } Future _confirmLogout(BuildContext context, WidgetRef ref) async { final ok = await showDialog( context: context, builder: (ctx) => AlertDialog( backgroundColor: HaloTokens.surface, shape: const RoundedRectangleBorder(borderRadius: HaloRadius.lg), title: const Text( 'keluar dari akun?', style: TextStyle( fontFamily: HaloTokens.fontDisplay, fontWeight: FontWeight.w700, color: HaloTokens.brandDark, ), ), content: const Text( 'kamu harus login lagi buat lanjutin curhatan.', style: TextStyle( fontFamily: HaloTokens.fontBody, color: HaloTokens.inkSoft, ), ), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(false), child: const Text( 'batal', style: TextStyle(color: HaloTokens.inkMuted), ), ), TextButton( onPressed: () => Navigator.of(ctx).pop(true), child: const Text( 'keluar', style: TextStyle( color: HaloTokens.danger, fontWeight: FontWeight.w600, ), ), ), ], ), ); if (ok != true) return; await ref.read(authProvider.notifier).logout(); // RouterNotifier observes the resulting AuthInitialData and sends the user // to /home (SHome1st), so no manual navigation is needed here. } static String? _maskPhone(String? raw) { if (raw == null || raw.length < 6) return raw; final tail = raw.substring(raw.length - 4); final head = raw.substring(0, raw.length - 8); return '$head ••••$tail'; } } class _UserCard extends StatelessWidget { final String name; final String? phone; const _UserCard({required this.name, this.phone}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: HaloTokens.surface, borderRadius: HaloRadius.xl, border: Border.all(color: HaloTokens.border), ), child: Row( children: [ Container( width: 56, height: 56, decoration: const BoxDecoration( gradient: RadialGradient( colors: [HaloTokens.brand, HaloTokens.lilac], ), shape: BoxShape.circle, ), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontFamily: HaloTokens.fontDisplay, fontSize: 18, fontWeight: FontWeight.w700, color: HaloTokens.ink, letterSpacing: -0.18, ), ), if (phone != null) ...[ const SizedBox(height: 2), Text( phone!, style: const TextStyle( fontFamily: HaloTokens.fontBody, fontSize: 12, color: HaloTokens.inkSoft, ), ), ], ], ), ), ], ), ); } } class _MenuItemData { final IconData icon; final String label; final String? sub; final VoidCallback onTap; const _MenuItemData({ required this.icon, required this.label, this.sub, required this.onTap, }); } class _MenuCard extends StatelessWidget { final List<_MenuItemData> items; const _MenuCard({required this.items}); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: HaloTokens.surface, borderRadius: HaloRadius.lg, border: Border.all(color: HaloTokens.border), ), clipBehavior: Clip.antiAlias, child: Column( children: [ for (var i = 0; i < items.length; i++) ...[ _MenuItemRow(item: items[i]), if (i < items.length - 1) const Divider(height: 1, thickness: 1, color: HaloTokens.border), ], ], ), ); } } class _MenuItemRow extends StatelessWidget { final _MenuItemData item; const _MenuItemRow({required this.item}); @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: InkWell( onTap: item.onTap, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Row( children: [ Container( width: 36, height: 36, decoration: const BoxDecoration( color: HaloTokens.brandSofter, borderRadius: BorderRadius.all(Radius.circular(10)), ), alignment: Alignment.center, child: Icon(item.icon, size: 18, color: HaloTokens.brandDark), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( item.label, style: const TextStyle( fontFamily: HaloTokens.fontBody, fontSize: 14, fontWeight: FontWeight.w500, color: HaloTokens.ink, ), ), if (item.sub != null) ...[ const SizedBox(height: 2), Text( item.sub!, style: const TextStyle( fontFamily: HaloTokens.fontBody, fontSize: 11.5, color: HaloTokens.inkMuted, ), ), ], ], ), ), const Icon( Icons.chevron_right, size: 18, color: HaloTokens.inkMuted, ), ], ), ), ), ); } } class _LogoutButton extends StatelessWidget { final VoidCallback onTap; const _LogoutButton({required this.onTap}); @override Widget build(BuildContext context) { return Material( color: HaloTokens.surface, borderRadius: HaloRadius.lg, child: InkWell( onTap: onTap, borderRadius: HaloRadius.lg, child: Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 16), decoration: BoxDecoration( borderRadius: HaloRadius.lg, border: Border.all( color: HaloTokens.danger.withValues(alpha: 0.25), ), ), child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.logout, size: 18, color: HaloTokens.danger), SizedBox(width: 8), Text( 'keluar', style: TextStyle( fontFamily: HaloTokens.fontBody, fontSize: 14, fontWeight: FontWeight.w500, color: HaloTokens.danger, ), ), ], ), ), ), ); } }