그룹 스터디 멤버 프로필에 30분 단위 색상 테두리 연출 추가

오늘 공부 시간이 30분씩 늘어날 때마다 프로필 원형 테두리가
흰→노랑→주황→빨강→보라 순으로 진해지도록(2시간 이상은 보라 고정)
꾸며서 누가 얼마나 공부하고 있는지 한눈에 보이게 함. 범례도 추가.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 05:12:55 +00:00
co-authored by Claude Sonnet 5
parent 51a106faf4
commit 206eec03bc
+64 -9
View File
@@ -217,6 +217,21 @@ class _GroupDetailScreenState extends State<GroupDetailScreen> {
return '$s초';
}
/// 🎨 오늘 공부 시간 30분 단위로 프로필 테두리 색이 흰→노랑→주황→빨강→보라로
/// 진해진다. 2시간(4단계) 넘으면 보라색에서 멈춘다.
static const List<Color> _studyFrameColors = [
Color(0xFFE0E0E0), // 흰(기본)
Color(0xFFFFC107), // 노랑
Color(0xFFFF9800), // 주황
Color(0xFFE53935), // 빨강
Color(0xFF8E24AA), // 보라
];
Color _studyFrameColor(int todaySeconds) {
final tier = (todaySeconds ~/ 1800).clamp(0, _studyFrameColors.length - 1);
return _studyFrameColors[tier];
}
void _openTimer() {
pushLaunchpad(
context,
@@ -423,6 +438,31 @@ class _GroupDetailScreenState extends State<GroupDetailScreen> {
color: Colors.grey[500],
),
),
const SizedBox(height: 4),
Row(
children: [
Text(
'프로필 테두리는 30분마다 색이 진해져요',
style: TextStyle(
fontSize: 11.5,
color: Colors.grey[500],
),
),
const SizedBox(width: 6),
for (final c in _studyFrameColors)
Padding(
padding: const EdgeInsets.only(left: 2),
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: c,
),
),
),
],
),
const SizedBox(height: 10),
GridView.builder(
shrinkWrap: true,
@@ -438,6 +478,8 @@ class _GroupDetailScreenState extends State<GroupDetailScreen> {
itemBuilder: (context, index) {
final m = members[index];
final attended = m['attendedToday'] == true;
final todaySeconds =
(m['todaySeconds'] as num?)?.toInt() ?? 0;
return Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
@@ -454,14 +496,29 @@ class _GroupDetailScreenState extends State<GroupDetailScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
attended
? Icons.check_circle_rounded
: Icons.radio_button_unchecked_rounded,
Container(
width: 30,
height: 30,
padding: const EdgeInsets.all(2.5),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: _studyFrameColor(todaySeconds),
width: 3,
),
),
child: CircleAvatar(
backgroundColor: attended
? Colors.white24
: AppPalette.linen,
child: Icon(
Icons.person_rounded,
size: 13,
color: attended
? Colors.white
: Colors.grey[350],
size: 18,
: AppPalette.ink,
),
),
),
const Spacer(),
Text(
@@ -488,9 +545,7 @@ class _GroupDetailScreenState extends State<GroupDetailScreen> {
),
const SizedBox(height: 2),
Text(
_formatMinutes(
(m['todaySeconds'] as num?)?.toInt() ?? 0,
),
_formatMinutes(todaySeconds),
style: TextStyle(
fontSize: 11,
color: attended