Skip to content

Commit

Permalink
Merge pull request #32 from yihong1120/feature/dashboard-display
Browse files Browse the repository at this point in the history
Feature/dashboard display
  • Loading branch information
yihong1120 authored Dec 31, 2023
2 parents 1db2eb8 + 6e7e290 commit ee5ac78
Show file tree
Hide file tree
Showing 27 changed files with 654 additions and 157 deletions.
22 changes: 12 additions & 10 deletions lib/components/navigation_drawer.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import 'package:flutter/material.dart';

class NavigationDrawer extends StatelessWidget {
class CustomNavigationDrawer extends StatelessWidget {
const CustomNavigationDrawer({super.key});

@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
const DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
Expand All @@ -20,23 +22,23 @@ class NavigationDrawer extends StatelessWidget {
),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
leading: const Icon(Icons.home),
title: const Text('Home'),
onTap: () => _navigateTo(context, '/'), // 导航到主页,根据实际路由调整
),
ListTile(
leading: Icon(Icons.bar_chart),
title: Text('Reports'),
leading: const Icon(Icons.bar_chart),
title: const Text('Reports'),
onTap: () => _navigateTo(context, '/reports'), // 调整为实际报告页面的路由
),
ListTile(
leading: Icon(Icons.chat),
title: Text('Chatbot'),
leading: const Icon(Icons.chat),
title: const Text('Chatbot'),
onTap: () => _navigateTo(context, '/chat'), // 调整为实际聊天页面的路由
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('Accounts'),
leading: const Icon(Icons.account_circle),
title: const Text('Accounts'),
onTap: () => _navigateTo(context, '/accounts'), // 调整为实际账户页面的路由
),
],
Expand Down
12 changes: 7 additions & 5 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Future main() async {
}

class TrafficReportApp extends StatelessWidget {
const TrafficReportApp({Key? key}) : super(key: key);
const TrafficReportApp({super.key});

@override
Widget build(BuildContext context) {
Expand All @@ -29,21 +29,23 @@ class TrafficReportApp extends StatelessWidget {
...chat_routes.chatRoutes,
...account_routes.accountsRoutes,
},
home: HomeScreen(), // 设置主屏幕
home: const HomeScreen(), // 设置主屏幕
);
}
}

// HomeScreen 类
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Traffic Report System'),
title: const Text('Traffic Report System'),
),
drawer: NavigationDrawer(), // 使用新组件
body: Center(
drawer: const CustomNavigationDrawer(), // 使用新组件
body: const Center(
child: Text('Welcome to Traffic Report System'),
),
);
Expand Down
28 changes: 27 additions & 1 deletion lib/models/traffic_violation.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';

class TrafficViolation {
int? id; // 添加 id 属性
String? title; // 添加 title 属性
DateTime? date;
TimeOfDay? time;
String? licensePlate;
Expand Down Expand Up @@ -31,6 +33,8 @@ class TrafficViolation {
];

TrafficViolation({
this.id,
this.title,
this.date,
this.time,
this.licensePlate,
Expand All @@ -43,13 +47,35 @@ class TrafficViolation {
// Convert a TrafficViolation into a JSON map.
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'date': date?.toIso8601String(),
'time': time?.format(context), // This requires a BuildContext to format the time.
'time': time != null ? '${time!.hour}:${time!.minute}' : null,
'licensePlate': licensePlate,
'violation': violation,
'status': status,
'location': location,
'officer': officer,
};
}

// Create a TrafficViolation from a JSON map.
factory TrafficViolation.fromJson(Map<String, dynamic> json) {
return TrafficViolation(
id: json['id'] as int?,
title: json['title'] as String?,
date: json['date'] != null ? DateTime.parse(json['date']) : null,
time: json['time'] != null ? _parseTime(json['time']) : null,
licensePlate: json['licensePlate'] as String?,
violation: json['violation'] as String?,
status: json['status'] as String?,
location: json['location'] as String?,
officer: json['officer'] as String?,
);
}

static TimeOfDay? _parseTime(String timeStr) {
final parts = timeStr.split(':').map(int.parse).toList();
return parts.length == 2 ? TimeOfDay(hour: parts[0], minute: parts[1]) : null;
}
}
20 changes: 10 additions & 10 deletions lib/screens/accounts/account_delete_confirm_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import '../../services/auth_service.dart'; // 假設您有一個處理身份驗證的服務

class AccountDeleteConfirmPage extends StatelessWidget {
const AccountDeleteConfirmPage({Key? key}) : super(key: key);
const AccountDeleteConfirmPage({super.key});

void _deleteAccount(BuildContext context) async {
// 假設 AuthService 有一個 deleteAccount 方法來處理帳戶刪除邏輯
Expand All @@ -22,29 +22,29 @@ class AccountDeleteConfirmPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Confirm Account Deletion'),
title: const Text('Confirm Account Deletion'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
const Text(
'Are you sure you want to delete your account? This action cannot be undone.',
style: TextStyle(fontSize: 16),
textAlign: TextAlign.center,
),
SizedBox(height: 20),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () => _showDeleteConfirmationDialog(context),
child: Text('Confirm Delete'),
child: const Text('Confirm Delete'),
),
TextButton(
onPressed: () {
// Navigate back to the account page
Navigator.of(context).pop();
},
child: Text('Cancel'),
child: const Text('Cancel'),
),
],
),
Expand All @@ -57,17 +57,17 @@ class AccountDeleteConfirmPage extends StatelessWidget {
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Delete Account'),
content: Text('Are you sure you want to delete your account?'),
title: const Text('Delete Account'),
content: const Text('Are you sure you want to delete your account?'),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text('Confirm Delete'),
child: const Text('Confirm Delete'),
onPressed: () {
Navigator.of(context).pop(); // Close the dialog
_deleteAccount(context);
Expand Down
10 changes: 5 additions & 5 deletions lib/screens/accounts/account_page.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:../../services/auth_service.dart'; // 假設您有一個處理身份驗證的服務
import '../../services/auth_service.dart'; // 假設您有一個處理身份驗證的服務

class AccountPage extends StatefulWidget {
const AccountPage({Key? key}) : super(key: key);
const AccountPage({super.key});

@override
_AccountPageState createState() => _AccountPageState();
Expand Down Expand Up @@ -31,7 +31,7 @@ class _AccountPageState extends State<AccountPage> {
Widget build(BuildContext context) {
if (!_isLoggedIn) {
// 如果用戶未登入,顯示加載指示器,直到我們檢查完畢
return Scaffold(
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
Expand All @@ -41,9 +41,9 @@ class _AccountPageState extends State<AccountPage> {
// 如果用戶已登入,顯示帳戶信息
return Scaffold(
appBar: AppBar(
title: Text('Account'),
title: const Text('Account'),
),
body: Center(
body: const Center(
child: Text('Welcome to your account page!'),
),
);
Expand Down
20 changes: 11 additions & 9 deletions lib/screens/accounts/login.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:../../services/auth_service.dart'; // 假設您有一個處理身份驗證的服務
// import 'package:../../services/auth_service.dart';

import '../../services/auth_service.dart'; // 假設您有一個處理身份驗證的服務

class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
const LoginPage({super.key});

@override
_LoginPageState createState() => _LoginPageState();
Expand All @@ -28,7 +30,7 @@ class _LoginPageState extends State<LoginPage> {
} else {
// 如果登入失敗,顯示錯誤消息
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Invalid username or password')),
const SnackBar(content: Text('Invalid username or password')),
);
}

Expand All @@ -42,11 +44,11 @@ class _LoginPageState extends State<LoginPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login'),
title: const Text('Login'),
),
body: Center(
child: _isLoading
? CircularProgressIndicator()
? const CircularProgressIndicator()
: Form(
key: _formKey,
child: Padding(
Expand All @@ -55,7 +57,7 @@ class _LoginPageState extends State<LoginPage> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextFormField(
decoration: InputDecoration(labelText: 'Username'),
decoration: const InputDecoration(labelText: 'Username'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your username';
Expand All @@ -65,7 +67,7 @@ class _LoginPageState extends State<LoginPage> {
onSaved: (value) => _username = value!,
),
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
decoration: const InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
Expand All @@ -75,10 +77,10 @@ class _LoginPageState extends State<LoginPage> {
},
onSaved: (value) => _password = value!,
),
SizedBox(height: 20),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _login,
child: Text('Login'),
child: const Text('Login'),
),
],
),
Expand Down
12 changes: 6 additions & 6 deletions lib/screens/accounts/password_change_done_page.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';

class PasswordChangeDonePage extends StatefulWidget {
const PasswordChangeDonePage({Key? key}) : super(key: key);
const PasswordChangeDonePage({super.key});

@override
_PasswordChangeDonePageState createState() => _PasswordChangeDonePageState();
Expand All @@ -17,7 +17,7 @@ class _PasswordChangeDonePageState extends State<PasswordChangeDonePage> {
}

void _startCountdown() {
Future.delayed(Duration(seconds: 1), () {
Future.delayed(const Duration(seconds: 1), () {
if (_countdown > 0) {
setState(() {
_countdown--;
Expand All @@ -38,27 +38,27 @@ class _PasswordChangeDonePageState extends State<PasswordChangeDonePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Password Change Successful'),
title: const Text('Password Change Successful'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
const Text(
'Your password has been changed successfully!',
style: TextStyle(fontSize: 18),
textAlign: TextAlign.center,
),
SizedBox(height: 20),
const SizedBox(height: 20),
Text(
'You will be redirected to your account page in $_countdown seconds.',
style: TextStyle(fontSize: 16),
textAlign: TextAlign.center,
),
TextButton(
onPressed: _redirectToAccountPage,
child: Text('Click here if you are not redirected'),
child: const Text('Click here if you are not redirected'),
),
],
),
Expand Down
Loading

0 comments on commit ee5ac78

Please sign in to comment.