Initial commit

This commit is contained in:
kihong.kim
2026-01-24 19:41:19 +09:00
commit 807df3d678
90 changed files with 6411 additions and 0 deletions

View File

@@ -0,0 +1,133 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../widgets/digital_clock_widget.dart';
import '../../widgets/weather_widget.dart';
import '../../widgets/calendar_widget.dart';
import '../../widgets/schedule_list_widget.dart';
import '../../widgets/announcement_widget.dart';
import '../../widgets/photo_slideshow_widget.dart';
import '../../widgets/todo_list_widget.dart';
import '../../widgets/bible_verse_widget.dart';
class TvDashboardScreen extends StatefulWidget {
const TvDashboardScreen({super.key});
@override
State<TvDashboardScreen> createState() => _TvDashboardScreenState();
}
class _TvDashboardScreenState extends State<TvDashboardScreen> {
// Timer for periodic refresh (every 5 minutes for data, 1 second for clock)
Timer? _dataRefreshTimer;
@override
void initState() {
super.initState();
// Initial data fetch could be triggered here or within widgets
_startDataRefresh();
}
void _startDataRefresh() {
_dataRefreshTimer = Timer.periodic(const Duration(minutes: 5), (timer) {
// Trigger refreshes if needed, or let widgets handle their own polling
// For simplicity, we assume widgets or providers handle their data
setState(() {}); // Rebuild to refresh UI state if needed
});
}
@override
void dispose() {
_dataRefreshTimer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
// 1920x1080 reference
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(32.0), // Outer margin safe zone
child: Column(
children: [
// Header: Time and Weather
SizedBox(
height: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [const DigitalClockWidget(), const WeatherWidget()],
),
),
const SizedBox(height: 24),
// Main Content Grid
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Left Column: Calendar, Schedule, Announcement
Expanded(
flex: 3,
child: Column(
children: [
const Expanded(flex: 4, child: CalendarWidget()),
const SizedBox(height: 16),
const Expanded(flex: 4, child: ScheduleListWidget()),
const SizedBox(height: 16),
const Expanded(flex: 2, child: AnnouncementWidget()),
],
),
),
const SizedBox(width: 24),
// Center Column: Photo Slideshow
Expanded(
flex: 4,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 20,
offset: const Offset(0, 10),
),
],
),
clipBehavior: Clip.antiAlias,
child: const PhotoSlideshowWidget(),
),
),
const SizedBox(width: 24),
// Right Column: Todos, Bible Verse
Expanded(
flex: 3,
child: Column(
children: [
const Expanded(flex: 6, child: TodoListWidget()),
const SizedBox(height: 16),
const Expanded(flex: 3, child: BibleVerseWidget()),
],
),
),
],
),
),
// Hidden trigger for admin/mobile view (e.g. long press corner)
GestureDetector(
onLongPress: () {
Navigator.of(context).pushNamed('/admin');
},
child: Container(
width: 50,
height: 50,
color: Colors.transparent,
),
),
],
),
),
),
);
}
}