Initial commit: TimeReg Flutter app med Firebase backend

- Opprettet Flutter-prosjekt med alle nødvendige avhengigheter
- Implementert datamodeller (User, TimeRegistration, TariffProfile, Deviation, AuditLog)
- Implementert tjenester (AuthService, TimeService)
- Implementert Riverpod providers for state management
- Opprettet autentiseringsskjermer (login, signup, reset password)
- Opprettet hjemmeskjerm med timer-funksjonalitet
- Opprettet placeholder-skjermer for historikk, rapporter og profil
- Lagt til norsk dokumentasjon i README
This commit is contained in:
steinhelge
2025-11-24 20:52:27 +01:00
commit c829f78984
148 changed files with 8462 additions and 0 deletions
+144
View File
@@ -0,0 +1,144 @@
import 'package:cloud_firestore/cloud_firestore.dart';
enum UserRole {
employee,
admin,
systemAdmin,
}
class UserModel {
final String uid;
final String email;
final String displayName;
final UserRole role;
final String tariffProfileId;
final String organizationId;
final String? departmentId;
final DateTime createdAt;
final DateTime updatedAt;
final bool isActive;
final UserPreferences preferences;
UserModel({
required this.uid,
required this.email,
required this.displayName,
required this.role,
required this.tariffProfileId,
required this.organizationId,
this.departmentId,
required this.createdAt,
required this.updatedAt,
this.isActive = true,
required this.preferences,
});
factory UserModel.fromFirestore(DocumentSnapshot doc) {
final data = doc.data() as Map<String, dynamic>;
return UserModel(
uid: doc.id,
email: data['email'] ?? '',
displayName: data['displayName'] ?? '',
role: _parseRole(data['role']),
tariffProfileId: data['tariffProfileId'] ?? '',
organizationId: data['organizationId'] ?? '',
departmentId: data['departmentId'],
createdAt: (data['createdAt'] as Timestamp).toDate(),
updatedAt: (data['updatedAt'] as Timestamp).toDate(),
isActive: data['isActive'] ?? true,
preferences: UserPreferences.fromMap(data['preferences'] ?? {}),
);
}
Map<String, dynamic> toFirestore() {
return {
'email': email,
'displayName': displayName,
'role': role.name,
'tariffProfileId': tariffProfileId,
'organizationId': organizationId,
'departmentId': departmentId,
'createdAt': Timestamp.fromDate(createdAt),
'updatedAt': Timestamp.fromDate(updatedAt),
'isActive': isActive,
'preferences': preferences.toMap(),
};
}
static UserRole _parseRole(String? roleString) {
switch (roleString) {
case 'admin':
return UserRole.admin;
case 'systemAdmin':
return UserRole.systemAdmin;
default:
return UserRole.employee;
}
}
UserModel copyWith({
String? email,
String? displayName,
UserRole? role,
String? tariffProfileId,
String? organizationId,
String? departmentId,
DateTime? updatedAt,
bool? isActive,
UserPreferences? preferences,
}) {
return UserModel(
uid: uid,
email: email ?? this.email,
displayName: displayName ?? this.displayName,
role: role ?? this.role,
tariffProfileId: tariffProfileId ?? this.tariffProfileId,
organizationId: organizationId ?? this.organizationId,
departmentId: departmentId ?? this.departmentId,
createdAt: createdAt,
updatedAt: updatedAt ?? this.updatedAt,
isActive: isActive ?? this.isActive,
preferences: preferences ?? this.preferences,
);
}
}
class UserPreferences {
final bool notificationsEnabled;
final bool emailNotifications;
final bool pushNotifications;
UserPreferences({
this.notificationsEnabled = true,
this.emailNotifications = true,
this.pushNotifications = true,
});
factory UserPreferences.fromMap(Map<String, dynamic> map) {
return UserPreferences(
notificationsEnabled: map['notificationsEnabled'] ?? true,
emailNotifications: map['emailNotifications'] ?? true,
pushNotifications: map['pushNotifications'] ?? true,
);
}
Map<String, dynamic> toMap() {
return {
'notificationsEnabled': notificationsEnabled,
'emailNotifications': emailNotifications,
'pushNotifications': pushNotifications,
};
}
UserPreferences copyWith({
bool? notificationsEnabled,
bool? emailNotifications,
bool? pushNotifications,
}) {
return UserPreferences(
notificationsEnabled: notificationsEnabled ?? this.notificationsEnabled,
emailNotifications: emailNotifications ?? this.emailNotifications,
pushNotifications: pushNotifications ?? this.pushNotifications,
);
}
}