그룹 스터디 멤버 프로필에 30분 단위 색상 테두리 연출 추가
오늘 공부 시간이 30분씩 늘어날 때마다 프로필 원형 테두리가 흰→노랑→주황→빨강→보라 순으로 진해지도록(2시간 이상은 보라 고정) 꾸며서 누가 얼마나 공부하고 있는지 한눈에 보이게 함. 범례도 추가. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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,
|
||||
color: attended
|
||||
? Colors.white
|
||||
: Colors.grey[350],
|
||||
size: 18,
|
||||
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
|
||||
: 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
|
||||
|
||||
Reference in New Issue
Block a user