Skip to content

Commit ac8e57c

Browse files
client: workbook WIP
1 parent 67bd174 commit ac8e57c

6 files changed

Lines changed: 172 additions & 121 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -1,101 +1,65 @@
11
import 'package:flutter/material.dart';
22
import 'package:gap/gap.dart';
3-
import 'package:school_data_hub_flutter/common/theme/app_colors.dart';
4-
import 'package:school_data_hub_flutter/features/learning/domain/competence_helper.dart';
5-
import 'package:school_data_hub_flutter/features/learning/domain/enums.dart';
63
import 'package:school_data_hub_flutter/features/pupil/domain/models/pupil_proxy.dart';
4+
import 'package:school_data_hub_flutter/features/workbooks/domain/workbook_enums.dart'
5+
as workbook_enum;
76

8-
class WorkbooksCompetenceOverview extends StatelessWidget {
7+
class WorkbooksOverview extends StatelessWidget {
98
final PupilProxy pupil;
10-
const WorkbooksCompetenceOverview({super.key, required this.pupil});
9+
const WorkbooksOverview({super.key, required this.pupil});
1110

12-
String _getShortName(RootCompetenceType type) {
13-
switch (type) {
14-
case RootCompetenceType.math:
15-
return 'MA';
16-
case RootCompetenceType.german:
17-
return 'DE';
18-
case RootCompetenceType.science:
19-
return 'SU';
20-
case RootCompetenceType.english:
21-
return 'EN';
22-
case RootCompetenceType.art:
23-
return 'KU';
24-
case RootCompetenceType.music:
25-
return 'MU';
26-
case RootCompetenceType.sport:
27-
return 'SP';
28-
case RootCompetenceType.religion:
29-
return 'RE';
30-
case RootCompetenceType.socialAndWorkSkills:
31-
return 'AV';
32-
case RootCompetenceType.motherLanguage:
33-
return 'SV';
34-
case RootCompetenceType.daz:
35-
return 'DaZ';
11+
workbook_enum.SubjectEnum? _resolveSubject(String subjectName) {
12+
for (final subject in workbook_enum.SubjectEnum.values) {
13+
if (subject.name == subjectName) {
14+
return subject;
15+
}
3616
}
17+
return null;
3718
}
3819

3920
@override
4021
Widget build(BuildContext context) {
4122
final pupilWorkbooks = pupil.pupilWorkbooks ?? [];
42-
final Map<RootCompetenceType, int> counts = {};
23+
final Map<workbook_enum.SubjectEnum, int> counts = {};
4324

4425
for (final pw in pupilWorkbooks) {
45-
final subject = pw.workbook?.subject;
46-
if (subject == null) continue;
26+
final subjectName = pw.workbook?.subject;
27+
if (subjectName == null) continue;
4728

48-
final type = RootCompetenceType.stringToValue[subject];
49-
if (type != null) {
50-
counts[type] = (counts[type] ?? 0) + 1;
29+
final workbookSubject = _resolveSubject(subjectName);
30+
if (workbookSubject != null) {
31+
counts[workbookSubject] = (counts[workbookSubject] ?? 0) + 1;
5132
}
5233
}
5334

5435
final List<Widget> widgetList = [];
55-
counts.forEach((type, count) {
56-
final Color competenceColor = CompetenceHelper.getRootCompetenceColor(
57-
rootCompetenceType: type,
58-
);
36+
counts.forEach((subject, count) {
37+
final imagePath = subject.imagePath;
5938
widgetList.add(
60-
Padding(
61-
padding: const EdgeInsets.only(bottom: 5.0),
62-
child: Column(
63-
mainAxisSize: MainAxisSize.min,
64-
children: [
65-
Text(
66-
_getShortName(type),
67-
style: const TextStyle(
68-
color: Colors.black,
69-
fontSize: 11,
70-
fontWeight: FontWeight.bold,
71-
),
39+
Row(
40+
mainAxisSize: MainAxisSize.min,
41+
children: [
42+
if (imagePath != null)
43+
SizedBox(
44+
width: 30,
45+
height: 30,
46+
child: Image.asset(imagePath, fit: BoxFit.contain),
47+
)
48+
else
49+
const Icon(Icons.menu_book_rounded, size: 20),
50+
const Gap(4),
51+
Text(
52+
count.toString(),
53+
style: const TextStyle(
54+
color: Colors.black,
55+
fontSize: 15,
56+
fontWeight: FontWeight.bold,
7257
),
73-
const Gap(2),
74-
Container(
75-
width: 21.0,
76-
height: 21.0,
77-
decoration: BoxDecoration(
78-
color: competenceColor,
79-
shape: BoxShape.circle,
80-
),
81-
child: Center(
82-
child: Text(
83-
count.toString(),
84-
style: TextStyle(
85-
color: AppColors.bestContrastCompetenceFontColor(
86-
competenceColor,
87-
),
88-
fontSize: 15,
89-
fontWeight: FontWeight.bold,
90-
),
91-
),
92-
),
93-
),
94-
],
95-
),
58+
),
59+
],
9660
),
9761
);
98-
widgetList.add(const Gap(5));
62+
widgetList.add(const Gap(10));
9963
});
10064

10165
if (widgetList.isEmpty) {
@@ -112,11 +76,9 @@ class WorkbooksCompetenceOverview extends StatelessWidget {
11276
);
11377
}
11478

115-
return Wrap(
116-
spacing: 5,
117-
direction: Axis.horizontal,
118-
alignment: WrapAlignment.end,
119-
children: widgetList,
79+
return SingleChildScrollView(
80+
scrollDirection: Axis.horizontal,
81+
child: Row(children: widgetList),
12082
);
12183
}
12284
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_it/flutter_it.dart';
23
import 'package:school_data_hub_flutter/features/learning/presentation/pupil_list_learning_page/widgets/learning_list_card/workbooks_competence_overview.dart';
34
import 'package:school_data_hub_flutter/features/pupil/domain/models/pupil_proxy.dart';
4-
import 'package:flutter_it/flutter_it.dart';
55

66
class WorkbooksInfoSwitch extends WatchingWidget {
77
final PupilProxy pupil;
@@ -10,6 +10,6 @@ class WorkbooksInfoSwitch extends WatchingWidget {
1010
@override
1111
Widget build(BuildContext context) {
1212
watch(pupil);
13-
return WorkbooksCompetenceOverview(pupil: pupil);
13+
return WorkbooksOverview(pupil: pupil);
1414
}
1515
}

school_data_hub_flutter/lib/features/workbooks/domain/workbook_enums.dart

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,34 @@
1-
enum Subject {
2-
german('Deutsch', 'D'),
3-
english('Englisch', 'E'),
4-
math('Mathematik', 'M'),
5-
physics('Physik', 'P'),
6-
chemistry('Chemie', 'C'),
7-
biology('Biologie', 'B'),
8-
history('Geschichte', 'H'),
9-
geography('Geografie', 'G'),
10-
music('Musik', 'M'),
11-
art('Kunst', 'K');
1+
enum SubjectEnum {
2+
english('Englisch', 'E', 'assets/images/learning_icons/english.png'),
3+
englishWorkbook(
4+
'Englisch Arbeitsheft',
5+
'EW',
6+
'assets/images/learning_icons/english_workbook.png',
7+
),
8+
math('Mathematik', 'M', 'assets/images/learning_icons/math.png'),
9+
mathWorkbook(
10+
'Mathematik Arbeitsheft',
11+
'MW',
12+
'assets/images/learning_icons/math_workbook.png',
13+
),
14+
music('Musik', 'M', 'assets/images/learning_icons/music.png'),
15+
art('Kunst', 'K', 'assets/images/learning_icons/art.png'),
16+
grammar('Rechtschreibung', 'G', 'assets/images/learning_icons/grammar.png'),
17+
writing('Schreiben', 'S', 'assets/images/learning_icons/writing.png'),
18+
reading('Lesen', 'L', 'assets/images/learning_icons/reading.png'),
19+
20+
germanSupport(
21+
'Deutsch Förderheft',
22+
'DF',
23+
'assets/images/learning_icons/daz.png',
24+
),
25+
science('Sachunterricht', 'SU', 'assets/images/learning_icons/science.png');
1226

1327
final String name;
1428
final String code;
29+
final String? imagePath;
1530

16-
const Subject(this.name, this.code);
31+
const SubjectEnum(this.name, this.code, [this.imagePath]);
1732
}
1833

1934
enum Grade {

school_data_hub_flutter/lib/features/workbooks/presentation/new_workbook_page/new_workbook_page.dart

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ class NewWorkbookPage extends WatchingWidget {
3131
final workbookNameTextFieldController = createOnce(
3232
() => TextEditingController(),
3333
);
34-
final selectedSubject = createOnce<ValueNotifier<workbookEnum.Subject?>>(
35-
() => ValueNotifier(null),
36-
dispose: (notifier) => notifier.dispose(),
37-
);
34+
final selectedSubject =
35+
createOnce<ValueNotifier<workbookEnum.SubjectEnum?>>(
36+
() => ValueNotifier(null),
37+
dispose: (notifier) => notifier.dispose(),
38+
);
3839
final selectedGrades = createOnce<ValueNotifier<Set<workbookEnum.Grade>>>(
3940
() => ValueNotifier(<workbookEnum.Grade>{}),
4041
dispose: (notifier) => notifier.dispose(),
@@ -51,8 +52,8 @@ class NewWorkbookPage extends WatchingWidget {
5152
if (isEdit) {
5253
workbookNameTextFieldController.text = workbook!.name ?? '';
5354
if (workbook!.subject != null) {
54-
selectedSubject.value = workbookEnum.Subject.values
55-
.cast<workbookEnum.Subject?>()
55+
selectedSubject.value = workbookEnum.SubjectEnum.values
56+
.cast<workbookEnum.SubjectEnum?>()
5657
.firstWhere(
5758
(s) =>
5859
s?.name == workbook!.subject ||
@@ -138,22 +139,52 @@ class NewWorkbookPage extends WatchingWidget {
138139
),
139140
const Gap(20),
140141

141-
DropdownButtonFormField<workbookEnum.Subject>(
142+
DropdownButtonFormField<workbookEnum.SubjectEnum>(
142143
initialValue: currentSubject,
143-
decoration: AppStyles.textFieldDecoration(
144-
labelText: 'Fach',
145-
),
144+
isDense: false,
145+
itemHeight: 50,
146+
decoration: AppStyles.textFieldDecoration(labelText: 'Fach')
147+
.copyWith(
148+
contentPadding: const EdgeInsets.symmetric(
149+
horizontal: 12,
150+
vertical: 14,
151+
),
152+
),
146153
style: const TextStyle(
147154
color: Colors.black,
148155
fontWeight: FontWeight.bold,
149156
),
150-
items: workbookEnum.Subject.values.map((subject) {
151-
return DropdownMenuItem<workbookEnum.Subject>(
157+
items: workbookEnum.SubjectEnum.values.map((subject) {
158+
return DropdownMenuItem<workbookEnum.SubjectEnum>(
152159
value: subject,
153-
child: Text(subject.name),
160+
child: Row(
161+
children: [
162+
if (subject.imagePath != null) ...[
163+
_SubjectIcon(imagePath: subject.imagePath!),
164+
const Gap(8),
165+
],
166+
Text(subject.name),
167+
],
168+
),
154169
);
155170
}).toList(),
156-
onChanged: (workbookEnum.Subject? newValue) {
171+
selectedItemBuilder: (context) {
172+
return workbookEnum.SubjectEnum.values.map((subject) {
173+
return SizedBox(
174+
height: 56,
175+
child: Row(
176+
children: [
177+
if (subject.imagePath != null) ...[
178+
_SubjectIcon(imagePath: subject.imagePath!),
179+
const Gap(8),
180+
],
181+
Text(subject.name),
182+
],
183+
),
184+
);
185+
}).toList();
186+
},
187+
onChanged: (workbookEnum.SubjectEnum? newValue) {
157188
selectedSubject.value = newValue;
158189
},
159190
),
@@ -239,3 +270,25 @@ class NewWorkbookPage extends WatchingWidget {
239270
);
240271
}
241272
}
273+
274+
class _SubjectIcon extends StatelessWidget {
275+
final String imagePath;
276+
277+
const _SubjectIcon({required this.imagePath});
278+
279+
@override
280+
Widget build(BuildContext context) {
281+
return SizedBox(
282+
width: 40,
283+
height: 40,
284+
child: ClipRect(
285+
child: Align(
286+
alignment: Alignment.center,
287+
widthFactor: 0.75,
288+
heightFactor: 0.75,
289+
child: Image.asset(imagePath, fit: BoxFit.contain),
290+
),
291+
),
292+
);
293+
}
294+
}

school_data_hub_flutter/lib/features/workbooks/presentation/workbook_list_page/widgets/pupil_workbook_card.dart

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:io';
22

3+
import 'package:collection/collection.dart';
34
import 'package:flutter/material.dart';
45
import 'package:flutter_it/flutter_it.dart';
56
import 'package:gap/gap.dart';
@@ -16,8 +17,8 @@ import 'package:school_data_hub_flutter/common/widgets/grades_widget.dart';
1617
import 'package:school_data_hub_flutter/common/widgets/unencrypted_image_in_card.dart';
1718
import 'package:school_data_hub_flutter/core/models/datetime_extensions.dart';
1819
import 'package:school_data_hub_flutter/core/session/hub_session_manager.dart';
19-
import 'package:school_data_hub_flutter/features/learning/domain/enums.dart';
2020
import 'package:school_data_hub_flutter/features/workbooks/domain/pupil_workbook_manager.dart';
21+
import 'package:school_data_hub_flutter/features/workbooks/domain/workbook_enums.dart';
2122
import 'package:school_data_hub_flutter/features/workbooks/presentation/new_workbook_page/new_workbook_page.dart';
2223

2324
class PupilWorkbookCard extends WatchingWidget {
@@ -188,19 +189,22 @@ class PupilWorkbookCard extends WatchingWidget {
188189
children: [
189190
Row(
190191
children: [
191-
Text(
192+
Image.asset(
192193
workbook.subject != null
193-
? RootCompetenceType
194-
.stringToValue[workbook
195-
.subject]!
196-
.value
197-
: 'Fach nicht bekannt',
198-
overflow: TextOverflow.fade,
199-
style: const TextStyle(
200-
fontSize: 16,
201-
fontWeight: FontWeight.bold,
202-
),
194+
? SubjectEnum.values
195+
.firstWhereOrNull(
196+
(element) =>
197+
element.name ==
198+
workbook
199+
.subject,
200+
)
201+
?.imagePath ??
202+
'assets/images/learning_icons/unknown.png'
203+
: 'assets/images/learning_icons/unknown.png',
204+
width: 25,
205+
height: 25,
203206
),
207+
204208
const Gap(5),
205209
workbook.level != null
206210
? GradesWidget(

0 commit comments

Comments
 (0)