import 'package:flutter/material.dart'; import 'package:friendly_map/modules/app/app.dart'; import 'package:friendly_map/modules/core/core.dart'; import '../theme.dart'; import '../widgets/async_view.dart'; import '../widgets/common.dart'; import '../widgets/pin_dialog.dart'; import '../widgets/ring_view.dart'; import 'circle_group_screen.dart'; import 'group_detail_screen.dart'; import 'person_screen.dart'; class _Data { const _Data(this.hub, this.me); final CircleHub hub; final String me; } /// 학교·회사 원형 보기: 나를 가운데 두고 둘레에 초·중·고·대(또는 회사들)를 놓고, /// 그 옆에 대화·통화가 많은 가까운 사람을 보여 준다. 칸을 누르면 그 칸 사람들이 원 모양으로 펼쳐진다. class CircleHubScreen extends StatelessWidget { const CircleHubScreen({super.key, required this.rootId}); final String rootId; @override Widget build(BuildContext context) { return AsyncView<_Data>( load: (a) async => _Data(await a.circles.hub(rootId), (await a.profile.me())?.name ?? '나'), builder: (context, d) { final root = d.hub.root; if (root == null) return Scaffold(appBar: AppBar(), body: const EmptyNote('지워진 그룹이에요.')); final kind = root.group.kind; final color = Pal.ofKind(kind); if (!root.open) { return Scaffold( appBar: AppBar(title: Text(root.group.name)), body: Center( child: Column(mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.lock, size: 48, color: Pal.muted), const SizedBox(height: 12), FilledButton(onPressed: () => openGroup(context, root), child: const Text('비밀번호로 열기')), ]), ), ); } final levels = d.hub.levels; return Scaffold( appBar: AppBar( title: Text(root.group.name), actions: [IconButton(tooltip: '목록으로 보기', onPressed: () => pushPage(context, GroupDetailScreen(groupId: rootId)), icon: const Icon(Icons.list))], ), body: ListView(padding: const EdgeInsets.only(bottom: 32), children: [ if (levels.isEmpty) const EmptyNote('아래에 칸이 없어요.\n목록으로 보기에서 하위 그룹을 만들어 보세요.') else RingView( center: MeDot(d.me), rings: [ [ for (final l in levels) RingDot( label: l.view.group.name, sub: '${l.count}명', color: l.count == 0 ? Pal.muted : color, faded: l.count == 0, onTap: () => pushPage(context, CircleGroupScreen(groupId: l.view.group.id)), ), ], ], ), const SectionHeader('가까운 사람'), if (d.hub.closest.isEmpty) const EmptyNote('대화나 통화가 쌓이면 가까운 사람이 여기 보여요.'), for (final c in d.hub.closest) ListTile( leading: Avatar(c.person.name, size: 40, color: color), title: Text(c.person.name), subtitle: Text([ if (c.subgroup != null) c.subgroup!, if (kind == CardKinds.school && c.cohortDiff != null) c.cohort, if (kind == CardKinds.company && c.position != null) c.position!, ].join(' · ')), trailing: c.score > 0 ? Text('${c.score}', style: const TextStyle(color: Pal.accent, fontWeight: FontWeight.w700)) : null, onTap: () => pushPage(context, PersonScreen(personId: c.person.id)), ), ]), ); }, ); } }