Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/l10n/app_ko.arb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"appointmentName": "약속 이름",
"appointmentNameHint": "예) 영화 보기",
"appointmentPlace": "약속 장소",
"travelTime": "이동 소요 시간",
"travelTime": "이동시간",
"hours": "시간",
"minutes": "분",
"selectTime": "시간을 선택해 주세요",
Expand Down
2 changes: 1 addition & 1 deletion lib/l10n/app_localizations_ko.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class AppLocalizationsKo extends AppLocalizations {
String get appointmentPlace => '약속 장소';

@override
String get travelTime => '이동 소요 시간';
String get travelTime => '이동시간';

@override
String get hours => '시간';
Expand Down
142 changes: 78 additions & 64 deletions lib/presentation/calendar/component/schedule_detail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,11 @@ class ScheduleDetail extends StatefulWidget {
class _ScheduleDetailState extends State<ScheduleDetail> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 6.0),
child: SwipeActionCell(
key: ValueKey<String>(widget.schedule.id),
backgroundColor: Colors.transparent,
trailingActions: _buildSwipeActions(context),
child: _buildScheduleContent(context),
),
return SwipeActionCell(
key: ValueKey<String>(widget.schedule.id),
backgroundColor: Colors.transparent,
trailingActions: _buildSwipeActions(context),
child: _buildScheduleContent(context),
);
}

Expand Down Expand Up @@ -107,14 +104,14 @@ class _ScheduleDetailState extends State<ScheduleDetail> {
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6.5),
padding: const EdgeInsets.symmetric(vertical: 8),
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: _ScheduleTimeColumn(
scheduleTime: widget.schedule.scheduleTime,
),
Expand Down Expand Up @@ -148,13 +145,13 @@ class _ScheduleTimeColumn extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
DateFormat.j(locale).format(scheduleTime),
DateFormat.Hm(locale).format(scheduleTime),
style: theme.textTheme.titleSmall,
textAlign: TextAlign.center,
),
const SizedBox(height: 4),
Text(
DateFormat('a', locale).format(scheduleTime),
DateFormat('a', 'en').format(scheduleTime),
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.outline,
),
Expand All @@ -176,61 +173,86 @@ class _ScheduleDetailsColumn extends StatelessWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0) +
const EdgeInsets.only(top: 4.0),
child: ExpansionTile(
tilePadding: EdgeInsets.zero,
childrenPadding: const EdgeInsets.only(bottom: 8.0),
shape: const Border(),
collapsedShape: const Border(),
title: Text(
schedule.scheduleName,
style: theme.textTheme.titleLarge,
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 8.0),
child: Theme(
data: Theme.of(context).copyWith(
visualDensity:
const VisualDensity(vertical: VisualDensity.minimumDensity),
listTileTheme: const ListTileThemeData(
dense: true,
minVerticalPadding: 0,
contentPadding: EdgeInsets.zero,
),
),
subtitle: Row(
children: [
const _MapPinFillSvg(),
const SizedBox(width: 4),
Text(
placeName,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.outline,
),
child: IconTheme(
data: IconTheme.of(context).copyWith(size: 32),
child: ExpansionTile(
shape: const Border(),
collapsedShape: const Border(),
iconColor:
theme.colorScheme.onSurfaceVariant, // Color when expanded
// icon size provided by IconTheme above
collapsedIconColor:
theme.colorScheme.onSurfaceVariant, // Color when collapsed
title: Text(
schedule.scheduleName,
style: theme.textTheme.titleLarge,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
children: [
Padding(
padding: const EdgeInsets.only(left: 0.0),
child: Column(
children: [
ScheduleInfoTile(
label: AppLocalizations.of(context)!.travelTime,
value: formatDuration(context, schedule.moveTime),
),
//TODO: add preparation time
ScheduleInfoTile(
label: AppLocalizations.of(context)!.spareTime,
value: formatDuration(
context, schedule.scheduleSpareTime ?? Duration.zero),
),
],
childrenPadding: const EdgeInsets.only(top: 16.0),
subtitle: Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Row(
children: [
const _MapPinFillSvg(),
const SizedBox(width: 4),
Expanded(
child: Text(
placeName,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.outline,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
children: [
Column(
children: [
_ScheduleInfoTile(
label: AppLocalizations.of(context)!.travelTime,
value: formatDuration(context, schedule.moveTime),
),
_ScheduleInfoTile(
label: AppLocalizations.of(context)!.spareTime,
value: formatDuration(
context, schedule.scheduleSpareTime ?? Duration.zero),
),
],
),
],
),
],
),
),
);
}
}

class ScheduleInfoTile extends StatelessWidget {
const ScheduleInfoTile({super.key, required this.label, required this.value});
class _ScheduleInfoTile extends StatelessWidget {
const _ScheduleInfoTile({required this.label, required this.value});

final String label;
final String value;

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final textTheme = theme.textTheme;
final colorScheme = theme.colorScheme;
return Column(
children: [
SizedBox(
Expand All @@ -244,22 +266,14 @@ class ScheduleInfoTile extends StatelessWidget {
children: [
Text(
label,
style: TextStyle(
color: const Color(0xFF777777),
fontSize: 12,
fontFamily: 'Pretendard',
fontWeight: FontWeight.w400,
height: 1.40,
style: textTheme.bodyMedium?.copyWith(
color: colorScheme.outline,
),
),
Text(
value,
style: TextStyle(
color: const Color(0xFF111111),
fontSize: 13,
fontFamily: 'Pretendard',
fontWeight: FontWeight.w400,
height: 1.40,
style: textTheme.bodyMedium?.copyWith(
color: colorScheme.onSurface,
),
),
],
Expand Down
1 change: 1 addition & 0 deletions lib/presentation/shared/theme/color_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ColorScheme _colorScheme = ColorScheme(
surfaceContainerHigh: AppColors.grey.shade300,
surfaceContainerHighest: AppColors.grey.shade400,
onSurface: AppColors.grey[950]!,
onSurfaceVariant: AppColors.grey.shade400,
outlineVariant: AppColors.grey.shade400,
outline: AppColors.grey.shade600,
);
10 changes: 3 additions & 7 deletions widgetbook/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:on_time_front/presentation/shared/theme/theme.dart';
import 'package:on_time_front/l10n/app_localizations.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;

Expand Down Expand Up @@ -33,13 +34,8 @@ class WidgetbookApp extends StatelessWidget {
max: 4,
),
LocalizationAddon(
locales: [
const Locale('en', 'US'),
],
localizationsDelegates: [
DefaultWidgetsLocalizations.delegate,
DefaultMaterialLocalizations.delegate,
],
locales: AppLocalizations.supportedLocales,
localizationsDelegates: AppLocalizations.localizationsDelegates,
),
DeviceFrameAddon(
devices: Devices.ios.all,
Expand Down
84 changes: 22 additions & 62 deletions widgetbook/lib/schedule_detail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,26 @@ Widget scheduleDetailUseCase(BuildContext context) {
latenessTime: 0,
);

return ScheduleDetail(
schedule: schedule,
onEdit: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Edit tapped')),
);
},
onDeleted: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Delete tapped')),
);
},
return Scaffold(
backgroundColor: const Color(0xFFF5F5F5),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: ScheduleDetail(
schedule: schedule,
onEdit: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Edit tapped')),
);
},
onDeleted: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Delete tapped')),
);
},
),
),
),
);
}

Expand Down Expand Up @@ -124,8 +132,9 @@ Widget multipleScheduleDetailsUseCase(BuildContext context) {
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: ListView.builder(
child: ListView.separated(
itemCount: schedules.length,
separatorBuilder: (context, index) => const SizedBox(height: 16),
itemBuilder: (context, index) {
return ScheduleDetail(
schedule: schedules[index],
Expand All @@ -150,52 +159,3 @@ Widget multipleScheduleDetailsUseCase(BuildContext context) {
),
);
}

@widgetbook.UseCase(
name: 'Long Text Content',
type: ScheduleDetail,
)
Widget longTextScheduleDetailUseCase(BuildContext context) {
final place = PlaceEntity(
id: 'place_long',
placeName: '서울특별시 강남구 테헤란로 427 위워크 선릉2호점 15층 회의실',
);

final schedule = ScheduleEntity(
id: 'schedule_long',
place: place,
scheduleName: '매우 중요한 분기별 전략 회의 및 프로젝트 진행 상황 점검 미팅',
scheduleTime: DateTime(2024, 1, 15, 16, 45),
moveTime: const Duration(hours: 2, minutes: 15),
isChanged: false,
isStarted: false,
scheduleSpareTime: const Duration(minutes: 45),
scheduleNote: '준비물: 노트북, 자료집, 프로젝트 문서, 차트, 그래프 등 모든 관련 문서',
latenessTime: 0,
);

return Scaffold(
backgroundColor: const Color(0xFFF5F5F5),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: ScheduleDetail(
schedule: schedule,
onEdit: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Edit long content schedule')),
);
},
onDeleted: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Delete long content schedule')),
);
},
),
),
),
),
);
}
Loading