Files
TPSchedule/mobile/lib/features/profile/import_preview.dart
T

136 lines
5.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import '../../app/app_controller.dart';
import '../../app/app_theme.dart';
import '../../data/json_schedule_import.dart';
import '../../domain/course.dart';
class ImportPreview extends StatefulWidget {
const ImportPreview({
super.key,
required this.draft,
required this.controller,
});
final ImportDraft draft;
final AppController controller;
@override
State<ImportPreview> createState() => _ImportPreviewState();
}
class _ImportPreviewState extends State<ImportPreview> {
bool _clearConfirmed = false, _busy = false;
@override
Widget build(BuildContext context) {
final draft = widget.draft, empty = draft.courses.isEmpty;
final allowed =
!_busy && (!empty || (draft.explicitlyEmpty && _clearConfirmed));
return SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(24, 8, 24, 28),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'确认你的课表',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w700),
),
const SizedBox(height: 8),
Text(
'${draft.courses.length} 条课程安排 · ${draft.source == CourseSource.demo ? '示例体验' : '导入预览'}',
style: const TextStyle(color: river),
),
const SizedBox(height: 18),
if (empty)
Text(draft.explicitlyEmpty ? '此操作会清空当前课表。' : '没有识别到课程,当前课表保持不变。'),
if (empty && draft.explicitlyEmpty)
CheckboxListTile(
value: _clearConfirmed,
onChanged: (v) => setState(() => _clearConfirmed = v ?? false),
title: const Text('确认清空当前课表'),
contentPadding: EdgeInsets.zero,
),
for (final c in draft.courses)
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: SurfaceCard(
padding: const EdgeInsets.all(14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
c.name,
style: const TextStyle(fontWeight: FontWeight.w700),
),
const SizedBox(height: 5),
Text(
'${c.teacher} · ${c.room}',
style: const TextStyle(fontSize: 12),
),
const SizedBox(height: 4),
Text(
'周${const ['一', '二', '三', '四', '五', '六', '日'][c.weekday - 1]} · 第 ${c.startPeriod}–${c.endPeriod} 节',
style: TextStyle(
fontSize: 12,
color: ink.withValues(alpha: 0.5),
),
),
],
),
),
),
if (widget.controller.snapshot.settings.semester == null &&
draft.source != CourseSource.demo)
const Padding(
padding: EdgeInsets.only(bottom: 16),
child: Text(
'导入后请在设置中选择真实学期开始日,课表与提醒才会显示。',
style: TextStyle(fontSize: 12, height: 1.6),
),
),
SizedBox(
width: double.infinity,
child: FilledButton(
onPressed: allowed
? () async {
setState(() => _busy = true);
await widget.controller.applyImport(
draft,
confirmedEmpty: _clearConfirmed,
);
if (!context.mounted) return;
if (widget.controller.lastError == null) {
Navigator.pop(context, true);
} else {
setState(() => _busy = false);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(widget.controller.lastError!),
),
);
}
}
: null,
child: Text(
_busy
? '正在保存…'
: draft.source == CourseSource.demo
? '开始体验'
: '确认导入',
),
),
),
const SizedBox(height: 8),
Center(
child: TextButton(
onPressed: _busy ? null : () => Navigator.pop(context, false),
child: const Text('取消'),
),
),
],
),
),
);
}
}