diff --git a/.github/workflows/make_binaries.yml b/.github/workflows/make_binaries.yml index 76dd9e4..c025c06 100644 --- a/.github/workflows/make_binaries.yml +++ b/.github/workflows/make_binaries.yml @@ -27,7 +27,7 @@ jobs: - name: Build Web Version run: flutter build web --release --dart-define=APP_ENV=prod - name: Accept Android SDK licenses - run: yes | sdkmanager --licenses + run: echo yes | sdkmanager --licenses - name: Build APK run: | diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3dc8312 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.sourceDirectory": "/home/engon/rbo/ins/windows/runner" +} \ No newline at end of file diff --git a/deployfirebase.jl b/deployfirebase.jl deleted file mode 100644 index a61e7fc..0000000 --- a/deployfirebase.jl +++ /dev/null @@ -1,50 +0,0 @@ -const gtag = """ - -""" - -function addgtag(html::String)::String - location = findfirst("", html) - if location === nothing - error("simple head tag not found, could not add google tag") - end - pos = location[end] - html[1:pos] * "\n$gtag\n" * html[pos+1:end] -end - -function copylogo() - println("- Copying logo") - open("./build/web/favicon.png", "w") do output - write(output, open("./logo.png") do input - read(input, String) - end) - end -end - -function main() - println("- Building for web") - run(`flutter build web`) - println("- Adding google tag") - tag_added = open("./build/web/index.html") do input - addgtag(read(input, String)) - end - open("./build/web/index.html", "w") do output - write(output, tag_added) - end - copylogo() - println("Deploying") - try - run(`firebase deploy --non-interactive`) - catch - print("faild") - end -end - -if (@__MODULE__) == Main - main() -end diff --git a/l10n.yaml b/l10n.yaml index 6cd858e..f631c8c 100644 --- a/l10n.yaml +++ b/l10n.yaml @@ -2,4 +2,5 @@ arb-dir: lib/l10n template-arb-file: app_en.arb output-localization-file: app_localizations.dart import-line: "import 'package:flutter_gen/gen_l10n/app_localizations.dart';" -translate: false \ No newline at end of file +translate: false +synthetic-package: false \ No newline at end of file diff --git a/lib/app.dart b/lib/app.dart index 69aea2f..2ddfe74 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -7,7 +7,6 @@ import './backend/sessions.dart'; import './pages/dashboard/dashboard.dart'; import './analytics.dart' as analytics; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class InS extends StatelessWidget { const InS({super.key}); @@ -30,7 +29,6 @@ class InS extends StatelessWidget { themeMode: themeManager.themeMode, localizationsDelegates: [ GlobalMaterialLocalizations.delegate, - AppLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], @@ -61,10 +59,7 @@ class InS extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ ErrorPage( - title: - AppLocalizations.of( - context, - )!.errorLoadingYourSession, + title: "Error loading your session", description: snapshot.error!.toString(), icon: Icon( Icons.signal_wifi_off, @@ -87,9 +82,7 @@ class InS extends StatelessWidget { ), ), icon: Icon(Icons.refresh), - label: Text( - AppLocalizations.of(context)!.reload, - ), + label: Text("Reload"), ), ), ), @@ -110,18 +103,14 @@ class InS extends StatelessWidget { }, ), ), - child: Text( - AppLocalizations.of(context)!.logout, - ), + child: Text("logout"), ), ), ), ], ), ), - appBar: AppBar( - title: Text(AppLocalizations.of(context)!.error), - ), + appBar: AppBar(title: Text("Error")), ); } else if (!snapshot.hasData) { return Scaffold( @@ -133,11 +122,7 @@ class InS extends StatelessWidget { color: Theme.of(context).primaryColor, ), SizedBox(height: 30), - Text( - AppLocalizations.of( - context, - )!.loadingYourOnlineAccounts, - ), + Text("Loading your online accounts..."), ], ), ), @@ -151,12 +136,7 @@ class InS extends StatelessWidget { }, ); } else { - return WelcomePage( - title: - AppLocalizations.of( - context, - )!.welcomeToTheIntranetOfSchools, - ); + return WelcomePage(title: "Welcome to the Intranet of Schools"); } }, ), diff --git a/lib/backend/models.dart b/lib/backend/models.dart index 50ffeb2..d4cb48a 100644 --- a/lib/backend/models.dart +++ b/lib/backend/models.dart @@ -4,3 +4,6 @@ export './models/user.dart'; export './models/session.dart'; export './models/classroom.dart'; export './models/school.dart'; +export './models/schoolapplicationform.dart'; +export './models/schoolapplicationformattempt.dart'; +export './models/schoolmember.dart'; diff --git a/lib/backend/models/classroom.dart b/lib/backend/models/classroom.dart index 24cb879..6d45d63 100644 --- a/lib/backend/models/classroom.dart +++ b/lib/backend/models/classroom.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import '../model.dart'; import './profile.dart'; @@ -24,17 +26,36 @@ class ClassroomMember implements Model { } } +class ClassroomInfo implements Model { + final String name; + final String description; + const ClassroomInfo({required this.name, this.description = ""}); + + @override + Map toJson() { + return {'name': name, 'description': description}; + } + + static ClassroomInfo fromJson(Map json) { + return ClassroomInfo(name: json['name'], description: json['description']); + } +} + class Classroom implements Model { final String id; - final String name; + final String classroomName; final String role; + final ClassroomInfo info; + final List tags; final Profile profile; final String schoolId; const Classroom({ required this.id, - required this.name, + required this.classroomName, required this.role, + required this.info, + required this.tags, required this.profile, required this.schoolId, }); @@ -43,18 +64,22 @@ class Classroom implements Model { Map toJson() { return { 'id': id, - 'name': name, + 'classroom_name': classroomName, 'role': role, 'profile': profile.toJson(), 'school_id': schoolId, + 'tags': tags, + 'info': info.toJson(), }; } factory Classroom.fromJson(Map json) { var cls = Classroom( id: json['id'], - name: json['name'], + classroomName: json['classroom_name'], role: json['role'], + info: ClassroomInfo.fromJson(json['info']), + tags: List.from(json['tags'].map((tag) => tag.toString())), profile: Profile.fromJson(json['profile']), schoolId: json['school_id'], ); diff --git a/lib/backend/models/school.dart b/lib/backend/models/school.dart index 03522f2..ae8634e 100644 --- a/lib/backend/models/school.dart +++ b/lib/backend/models/school.dart @@ -2,298 +2,10 @@ import '../model.dart'; import './profile.dart'; import '../backend.dart'; import './session.dart'; -import './user.dart'; - -enum SchoolMemberRole { student, teacher, admin, parent } - -extension SchoolMemberRoleExtension on SchoolMemberRole { - String toJson() { - switch (this) { - case SchoolMemberRole.student: - return "student"; - case SchoolMemberRole.teacher: - return "teacher"; - case SchoolMemberRole.admin: - return "admin"; - case SchoolMemberRole.parent: - return "parent"; - } - } -} - -extension SchoolMemberRoleStringExtension on String { - SchoolMemberRole? toSchoolMemberRole() { - switch (this) { - case "student": - return SchoolMemberRole.student; - case "teacher": - return SchoolMemberRole.teacher; - case "admin": - return SchoolMemberRole.admin; - case "parent": - return SchoolMemberRole.parent; - default: - return null; - } - } -} - -class SchoolApplicationFormQuestion implements Model { - final int number; - final String question; - final String type; - final bool required; - const SchoolApplicationFormQuestion({ - required this.number, - required this.question, - required this.type, - required this.required, - }); - - factory SchoolApplicationFormQuestion.fromJson(Map json) { - return SchoolApplicationFormQuestion( - number: json['number'], - question: json['question'], - type: json['type'], - required: json['required'] ?? false, - ); - } - - @override - Map toJson() { - return { - 'number': number, - 'question': question, - 'type': type, - 'required': required, - }; - } -} - -class SchoolApplicationForm implements Model { - final String id; - final String schoolId; - final String userId; - final String status; - final String description; - final String title; - final String instructions; - final List questions; - const SchoolApplicationForm({ - required this.id, - required this.schoolId, - required this.title, - required this.userId, - required this.status, - required this.description, - required this.instructions, - required this.questions, - }); - - factory SchoolApplicationForm.fromJson(Map json) { - return SchoolApplicationForm( - id: json['id'], - title: json['title'], - schoolId: json['school_id'], - userId: json['user_id'], - status: json['status'], - description: json['description'], - instructions: json['instructions'], - questions: - (json['questions'] as List) - .map( - (question) => SchoolApplicationFormQuestion.fromJson(question), - ) - .toList(), - ); - } - - @override - Map toJson() { - return { - 'id': id, - 'school_id': schoolId, - 'title': title, - 'user_id': userId, - 'status': status, - 'description': description, - 'instructions': instructions, - 'questions': questions.map((question) => question.toJson()).toList(), - }; - } -} - -class SchoolApplicationFormAttemptAnswer implements Model { - final int questionNumber; - final String content; - const SchoolApplicationFormAttemptAnswer({ - required this.questionNumber, - required this.content, - }); - - @override - Map toJson() { - return {'question_number': questionNumber, 'content': content}; - } - - factory SchoolApplicationFormAttemptAnswer.fromJson( - Map json, - ) { - return SchoolApplicationFormAttemptAnswer( - questionNumber: json['question_number'], - content: json['content'], - ); - } -} - -class AttempteeNApplicationForm { - final User attemptee; - final SchoolApplicationForm applicationForm; - const AttempteeNApplicationForm({ - required this.attemptee, - required this.applicationForm, - }); -} - -class SchoolApplicationFormAttempt implements Model { - final String id; - final String attempteeId; - final String applicationId; - final bool reviewed; - final bool accepted; - final List answers; - const SchoolApplicationFormAttempt({ - required this.id, - required this.attempteeId, - required this.applicationId, - required this.answers, - required this.accepted, - required this.reviewed, - }); - factory SchoolApplicationFormAttempt.fromJson(Map json) { - return SchoolApplicationFormAttempt( - id: json['id'], - attempteeId: json['attemptee_id'], - applicationId: json['application_id'], - accepted: json['accepted'] ?? false, - reviewed: json['reviewed'] ?? false, - answers: - (json['answers'] as List) - .map( - (answer) => SchoolApplicationFormAttemptAnswer.fromJson(answer), - ) - .toList(), - ); - } - @override - Map toJson() { - return { - 'id': id, - 'attemptee_id': attempteeId, - 'application_id': applicationId, - 'answers': answers.map((answer) => answer.toJson()).toList(), - 'accepted': accepted, - 'reviewed': reviewed, - }; - } - - Future getApplicationForm(Session session) async { - final res = await cacheableQuery( - "schoolapplicationform/$applicationId", - "schoolapplicationform/$applicationId", - {}, - session, - ); - if (res['status'] < 0) { - throw Exception(res['message']); - } - return SchoolApplicationForm.fromJson(res['form']); - } - - Future accept(Session session, String role) async { - final res = await apiQuery("schoolapplicationformattempt/$id/accept", { - 'role': role, - }, session); - if (res['status'] < 0) { - throw Exception(res['message']); - } - } - - Future decline(Session session) async { - final res = await apiQuery( - "schoolapplicationformattempt/$id/decline", - {}, - session, - ); - if (res['status'] < 0) { - throw Exception(res['message']); - } - } - - Future getAttemptee(Session session) async { - final res = await cacheableQuery( - "user/$attempteeId", - "user/$attempteeId", - {}, - session, - ); - if (res['status'] < 0) { - throw Exception(res['message']); - } - return User.fromJson(res['user']); - } - - Future getAttempteeNApplicationForm( - Session session, - ) async { - return AttempteeNApplicationForm( - attemptee: await getAttemptee(session), - applicationForm: await getApplicationForm(session), - ); - } -} - -class SchoolMember implements Model { - final String id; - final String userId; - final String schoolId; - final SchoolMemberRole role; - const SchoolMember({ - required this.id, - required this.userId, - required this.schoolId, - required this.role, - }); - - factory SchoolMember.fromJson(Map json) { - return SchoolMember( - id: json['id'], - userId: json['user_id'], - schoolId: json['school_id'], - role: - json['role'].toString().toSchoolMemberRole() ?? - SchoolMemberRole.student, - ); - } - - Future getUser(Session session) async { - final res = await cacheableQuery( - "user/$userId", - "user/$userId", - {}, - session, - ); - if (res['status'] < 0) { - throw Exception(res['message']); - } - return User.fromJson(res['user']); - } - - @override - Map toJson() { - return {'id': id, 'user_id': userId, 'school_id': schoolId, 'role': role}; - } -} +import 'schoolapplicationform.dart'; +import 'schoolapplicationformattempt.dart'; +import 'schoolmember.dart'; +import 'classroom.dart'; class SchoolInfo implements Model { final String name; @@ -418,4 +130,19 @@ class School implements Model { 'profile': profile.toJson(), }; } + + Future> getClassrooms(Session session) async { + final res = await cacheableQuery( + "school/$id/classrooms", + "school/$id/classrooms", + {}, + session, + ); + if (res['status'] < 0) { + throw Exception(res['message']); + } + return (res['classrooms'] as List) + .map((classroom) => Classroom.fromJson(classroom)) + .toList(); + } } diff --git a/lib/backend/models/schoolapplicationform.dart b/lib/backend/models/schoolapplicationform.dart new file mode 100644 index 0000000..e118131 --- /dev/null +++ b/lib/backend/models/schoolapplicationform.dart @@ -0,0 +1,86 @@ +import '../model.dart'; + +class SchoolApplicationFormQuestion implements Model { + final int number; + final String question; + final String type; + final bool required; + const SchoolApplicationFormQuestion({ + required this.number, + required this.question, + required this.type, + required this.required, + }); + + factory SchoolApplicationFormQuestion.fromJson(Map json) { + return SchoolApplicationFormQuestion( + number: json['number'], + question: json['question'], + type: json['type'], + required: json['required'] ?? false, + ); + } + + @override + Map toJson() { + return { + 'number': number, + 'question': question, + 'type': type, + 'required': required, + }; + } +} + +class SchoolApplicationForm implements Model { + final String id; + final String schoolId; + final String userId; + final String status; + final String description; + final String title; + final String instructions; + final List questions; + const SchoolApplicationForm({ + required this.id, + required this.schoolId, + required this.title, + required this.userId, + required this.status, + required this.description, + required this.instructions, + required this.questions, + }); + + factory SchoolApplicationForm.fromJson(Map json) { + return SchoolApplicationForm( + id: json['id'], + title: json['title'], + schoolId: json['school_id'], + userId: json['user_id'], + status: json['status'], + description: json['description'], + instructions: json['instructions'], + questions: + (json['questions'] as List) + .map( + (question) => SchoolApplicationFormQuestion.fromJson(question), + ) + .toList(), + ); + } + + @override + Map toJson() { + return { + 'id': id, + 'school_id': schoolId, + 'title': title, + 'user_id': userId, + 'status': status, + 'description': description, + 'instructions': instructions, + 'questions': questions.map((question) => question.toJson()).toList(), + }; + } +} diff --git a/lib/backend/models/schoolapplicationformattempt.dart b/lib/backend/models/schoolapplicationformattempt.dart new file mode 100644 index 0000000..ff1c8ec --- /dev/null +++ b/lib/backend/models/schoolapplicationformattempt.dart @@ -0,0 +1,144 @@ +import 'dart:convert'; + +import '../backend.dart'; +import '../model.dart'; +import 'schoolapplicationform.dart'; +import 'session.dart'; +import 'user.dart'; + +class SchoolApplicationFormAttemptAnswer implements Model { + final int questionNumber; + final String content; + const SchoolApplicationFormAttemptAnswer({ + required this.questionNumber, + required this.content, + }); + + @override + Map toJson() { + return {'question_number': questionNumber, 'content': content}; + } + + factory SchoolApplicationFormAttemptAnswer.fromJson( + Map json, + ) { + return SchoolApplicationFormAttemptAnswer( + questionNumber: json['question_number'], + content: json['content'], + ); + } +} + +class AttempteeNApplicationForm { + final User attemptee; + final SchoolApplicationForm applicationForm; + const AttempteeNApplicationForm({ + required this.attemptee, + required this.applicationForm, + }); +} + +class SchoolApplicationFormAttempt implements Model { + final String id; + final String attempteeId; + final String applicationId; + final bool reviewed; + final bool accepted; + final List answers; + const SchoolApplicationFormAttempt({ + required this.id, + required this.attempteeId, + required this.applicationId, + required this.answers, + required this.accepted, + required this.reviewed, + }); + factory SchoolApplicationFormAttempt.fromJson(Map json) { + return SchoolApplicationFormAttempt( + id: json['id'], + attempteeId: json['attemptee_id'], + applicationId: json['application_id'], + accepted: json['accepted'] ?? false, + reviewed: json['reviewed'] ?? false, + answers: + (json['answers'] as List) + .map( + (answer) => SchoolApplicationFormAttemptAnswer.fromJson(answer), + ) + .toList(), + ); + } + @override + Map toJson() { + return { + 'id': id, + 'attemptee_id': attempteeId, + 'application_id': applicationId, + 'answers': answers.map((answer) => answer.toJson()).toList(), + 'accepted': accepted, + 'reviewed': reviewed, + }; + } + + Future getApplicationForm(Session session) async { + final res = await cacheableQuery( + "schoolapplicationform/$applicationId", + "schoolapplicationform/$applicationId", + {}, + session, + ); + if (res['status'] < 0) { + throw Exception(res['message']); + } + return SchoolApplicationForm.fromJson(res['form']); + } + + Future accept( + Session session, + String role, + List classroomsIds, + List tags, + ) async { + final res = await apiQuery("schoolapplicationformattempt/$id/accept", { + 'role': role, + 'classrooms': jsonEncode(classroomsIds), + 'tags': jsonEncode(tags), + }, session); + if (res['status'] < 0) { + throw Exception(res['message']); + } + } + + Future decline(Session session) async { + final res = await apiQuery( + "schoolapplicationformattempt/$id/decline", + {}, + session, + ); + if (res['status'] < 0) { + throw Exception(res['message']); + } + } + + Future getAttemptee(Session session) async { + final res = await cacheableQuery( + "user/$attempteeId", + "user/$attempteeId", + {}, + session, + ); + if (res['status'] < 0) { + throw Exception(res['message']); + } + return User.fromJson(res['user']); + } + + Future getAttempteeNApplicationForm( + Session session, + ) async { + return AttempteeNApplicationForm( + attemptee: await getAttemptee(session), + applicationForm: await getApplicationForm(session), + ); + } +} diff --git a/lib/backend/models/schoolmember.dart b/lib/backend/models/schoolmember.dart new file mode 100644 index 0000000..555e96b --- /dev/null +++ b/lib/backend/models/schoolmember.dart @@ -0,0 +1,80 @@ +import '../backend.dart'; +import '../model.dart'; +import './session.dart'; +import './user.dart'; + +enum SchoolMemberRole { student, teacher, admin, parent } + +extension SchoolMemberRoleExtension on SchoolMemberRole { + String toJson() { + switch (this) { + case SchoolMemberRole.student: + return "student"; + case SchoolMemberRole.teacher: + return "teacher"; + case SchoolMemberRole.admin: + return "admin"; + case SchoolMemberRole.parent: + return "parent"; + } + } +} + +extension SchoolMemberRoleStringExtension on String { + SchoolMemberRole? toSchoolMemberRole() { + switch (this) { + case "student": + return SchoolMemberRole.student; + case "teacher": + return SchoolMemberRole.teacher; + case "admin": + return SchoolMemberRole.admin; + case "parent": + return SchoolMemberRole.parent; + default: + return null; + } + } +} + +class SchoolMember implements Model { + final String id; + final String userId; + final String schoolId; + final SchoolMemberRole role; + const SchoolMember({ + required this.id, + required this.userId, + required this.schoolId, + required this.role, + }); + + factory SchoolMember.fromJson(Map json) { + return SchoolMember( + id: json['id'], + userId: json['user_id'], + schoolId: json['school_id'], + role: + json['role'].toString().toSchoolMemberRole() ?? + SchoolMemberRole.student, + ); + } + + Future getUser(Session session) async { + final res = await cacheableQuery( + "user/$userId", + "user/$userId", + {}, + session, + ); + if (res['status'] < 0) { + throw Exception(res['message']); + } + return User.fromJson(res['user']); + } + + @override + Map toJson() { + return {'id': id, 'user_id': userId, 'school_id': schoolId, 'role': role}; + } +} diff --git a/lib/backend/models/user.dart b/lib/backend/models/user.dart index 6e4ef06..234e6a5 100644 --- a/lib/backend/models/user.dart +++ b/lib/backend/models/user.dart @@ -235,7 +235,7 @@ class User implements Model { session, ); if (data['status'] < 0) { - throw Exception("Error geting to your classrooms"); + throw Exception("Error geting your classrooms, ${data['message']}"); } if (data['classrooms'] == null) return []; return (data['classrooms'] as List) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart new file mode 100644 index 0000000..88fd8b1 --- /dev/null +++ b/lib/l10n/app_localizations.dart @@ -0,0 +1,951 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_en.dart'; +import 'app_localizations_fr.dart'; + +// ignore_for_file: type=lint + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'l10n/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations? of(BuildContext context) { + return Localizations.of(context, AppLocalizations); + } + + static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('en'), + Locale('fr') + ]; + + /// The conventional newborn programmer greeting + /// + /// In en, this message translates to: + /// **'Hello World!'** + String get helloWorld; + + /// Error message when the user's session fails to load + /// + /// In en, this message translates to: + /// **'Error loading your session'** + String get errorLoadingYourSession; + + /// Action to reload the current page or data + /// + /// In en, this message translates to: + /// **'Reload'** + String get reload; + + /// Action to log out the user + /// + /// In en, this message translates to: + /// **'logout'** + String get logout; + + /// Generic error message + /// + /// In en, this message translates to: + /// **'Error'** + String get error; + + /// Message indicating that the user's online accounts are being loaded + /// + /// In en, this message translates to: + /// **'Loading your online accounts...'** + String get loadingYourOnlineAccounts; + + /// Welcome message for the Intranet of Schools platform + /// + /// In en, this message translates to: + /// **'Welcome to the Intranet of Schools'** + String get welcomeToTheIntranetOfSchools; + + /// Error message including a snapshot of the error + /// + /// In en, this message translates to: + /// **'Error: {error}'** + String errorSnapshotError(Object error); + + /// Label for the user's schools + /// + /// In en, this message translates to: + /// **'Your schools'** + String get yourSchools; + + /// Label for the main dashboard + /// + /// In en, this message translates to: + /// **'Dashboard'** + String get dashboard; + + /// Label for the schedule section + /// + /// In en, this message translates to: + /// **'Schedule'** + String get schedule; + + /// Label for the classrooms section + /// + /// In en, this message translates to: + /// **'Classrooms'** + String get classrooms; + + /// Label for the user's profile + /// + /// In en, this message translates to: + /// **'Profile'** + String get profile; + + /// Label for the application settings + /// + /// In en, this message translates to: + /// **'Settings'** + String get settings; + + /// Action to sign out + /// + /// In en, this message translates to: + /// **'Sign Out'** + String get signOut; + + /// Welcome back message + /// + /// In en, this message translates to: + /// **'Welcome back'** + String get welcomeBack; + + /// Base content for the dashboard + /// + /// In en, this message translates to: + /// **'Dashboard Base Content'** + String get dashboardBaseContent; + + /// Generic welcome + /// + /// In en, this message translates to: + /// **'Welcome!'** + String get welcome; + + /// Label to connect + /// + /// In en, this message translates to: + /// **'Connect'** + String get connect; + + /// Label to register + /// + /// In en, this message translates to: + /// **'Register'** + String get register; + + /// Label for schools + /// + /// In en, this message translates to: + /// **'Schools'** + String get schools; + + /// Label for home + /// + /// In en, this message translates to: + /// **'Home'** + String get home; + + /// Label for Intranet of Schools + /// + /// In en, this message translates to: + /// **'Intranet of Schools'** + String get intranetOfSchools; + + /// Message when there are no schools + /// + /// In en, this message translates to: + /// **'No schools'** + String get noSchools; + + /// Message when the user is not a member of any school + /// + /// In en, this message translates to: + /// **'You are a member of no school yet'** + String get noSchoolMembership; + + /// Label to explore + /// + /// In en, this message translates to: + /// **'Explore'** + String get explore; + + /// Message indicating the user is not a member of a school + /// + /// In en, this message translates to: + /// **'You are a member of no school yet'** + String get youAreAMemberOfNoSchoolYet; + + /// Message indicating a waiting period + /// + /// In en, this message translates to: + /// **'Wait a little bit ...'** + String get waitALittleBit; + + /// Label for manual signup + /// + /// In en, this message translates to: + /// **'Manual Signup >'** + String get manualSignup; + + /// Message after successful signup + /// + /// In en, this message translates to: + /// **'Successfully signed up'** + String get successfullySignedUp; + + /// Label for name input + /// + /// In en, this message translates to: + /// **'Your Name'** + String get yourName; + + /// Label for password input + /// + /// In en, this message translates to: + /// **'Your password'** + String get yourPassword; + + /// Label for sign in + /// + /// In en, this message translates to: + /// **'Signin >'** + String get signin; + + /// Question asking the user's role + /// + /// In en, this message translates to: + /// **'What role best fits you?'** + String get whatRoleBestFitsYou; + + /// Label for student role + /// + /// In en, this message translates to: + /// **'Student'** + String get student; + + /// Label for instructor role + /// + /// In en, this message translates to: + /// **'Instructor'** + String get instructor; + + /// Label for administrator role + /// + /// In en, this message translates to: + /// **'Administrator'** + String get administrator; + + /// Label for parent role + /// + /// In en, this message translates to: + /// **'Parent'** + String get parent; + + /// Label for role selection + /// + /// In en, this message translates to: + /// **'Role'** + String get role; + + /// Label for weak password strength + /// + /// In en, this message translates to: + /// **'Weak'** + String get weak; + + /// Label for moderate password strength + /// + /// In en, this message translates to: + /// **'Moderate'** + String get moderate; + + /// Label for strong password strength + /// + /// In en, this message translates to: + /// **'Strong'** + String get strong; + + /// Label for suggested password + /// + /// In en, this message translates to: + /// **'Suggested Password'** + String get suggestedPassword; + + /// Label to cancel + /// + /// In en, this message translates to: + /// **'Cancel'** + String get cancel; + + /// Label to copy + /// + /// In en, this message translates to: + /// **'Copy'** + String get copy; + + /// Label to use + /// + /// In en, this message translates to: + /// **'Use This'** + String get useThis; + + /// Label for password + /// + /// In en, this message translates to: + /// **'Password'** + String get password; + + /// Label to generate password + /// + /// In en, this message translates to: + /// **'Generate password'** + String get generatePassword; + + /// Label for minimum password length + /// + /// In en, this message translates to: + /// **'Minimum 8 characters'** + String get minimum8Characters; + + /// Label for number requirement in password + /// + /// In en, this message translates to: + /// **'Number (0-9)'** + String get number09; + + /// Label for lowercase requirement in password + /// + /// In en, this message translates to: + /// **'Lowercase letter (a-z)'** + String get lowercaseLetterAZ; + + /// Label for special character requirement in password + /// + /// In en, this message translates to: + /// **'Special character (!@#...)'** + String get specialCharacter; + + /// Label for uppercase requirement in password + /// + /// In en, this message translates to: + /// **'Uppercase letter (A-Z)'** + String get uppercaseLetterAZ; + + /// Label to continue + /// + /// In en, this message translates to: + /// **'Continue'** + String get continuer; + + /// Label for password strength + /// + /// In en, this message translates to: + /// **'\$_strengthLabel password'** + String strengthlabelPassword(Object _strengthLabel); + + /// Label to create user profile + /// + /// In en, this message translates to: + /// **'Create Your Profile'** + String get createYourProfile; + + /// Label for full name input + /// + /// In en, this message translates to: + /// **'Full Name'** + String get fullName; + + /// Label for username input + /// + /// In en, this message translates to: + /// **'Username'** + String get username; + + /// Label for profile setup section + /// + /// In en, this message translates to: + /// **'Profile Setup'** + String get profileSetup; + + /// Message indicating username availability check + /// + /// In en, this message translates to: + /// **'Checking username availability...'** + String get checkingUsernameAvailability; + + /// Message indicating username requirements + /// + /// In en, this message translates to: + /// **'Username must be at least 3 characters and can only contain:\\nlowercase letters, numbers, underscores (_), and periods (.)'** + String get usernameMustBeAtLeast3CharactersAndCanOnlyContainNlowercaseLettersNumbersUnderscoresAndPeriods; + + /// Message indicating username is taken + /// + /// In en, this message translates to: + /// **'This username is already taken'** + String get thisUsernameIsAlreadyTaken; + + /// Message prompting user to select date of birth + /// + /// In en, this message translates to: + /// **'Please select a date of birth.'** + String get pleaseSelectADateOfBirth; + + /// Label for date of birth + /// + /// In en, this message translates to: + /// **'Date of Birth'** + String get dateOfBirth; + + /// Label to choose date of birth + /// + /// In en, this message translates to: + /// **'Choose your date of birth'** + String get chooseYourDateOfBirth; + + /// Label to select a date + /// + /// In en, this message translates to: + /// **'Select date'** + String get selectDate; + + /// Message indicating new account setup + /// + /// In en, this message translates to: + /// **'Setting up your new account...'** + String get settingUpYourNewAccount; + + /// Message indicating workspace preparation + /// + /// In en, this message translates to: + /// **'Preparing your workspace...'** + String get preparingYourWorkspace; + + /// Message indicating settings configuration + /// + /// In en, this message translates to: + /// **'Configuring settings...'** + String get configuringSettings; + + /// Message indicating nearing completion + /// + /// In en, this message translates to: + /// **'Almost there...'** + String get almostThere; + + /// Message indicating a short wait + /// + /// In en, this message translates to: + /// **'Just a few more moments...'** + String get justAFewMoreMoments; + + /// Message indicating profile creation + /// + /// In en, this message translates to: + /// **'Creating your profile...'** + String get creatingYourProfile; + + /// Message indicating preference setup + /// + /// In en, this message translates to: + /// **'Setting up your preferences...'** + String get settingUpYourPreferences; + + /// Message indicating account finalization + /// + /// In en, this message translates to: + /// **'Finalizing your account...'** + String get finalizingYourAccount; + + /// Message indicating dashboard loading + /// + /// In en, this message translates to: + /// **'Loading your dashboard...'** + String get loadingYourDashboard; + + /// Message indicating account creation + /// + /// In en, this message translates to: + /// **'Creating your account'** + String get creatingYourAccount; + + /// Message indicating account creation failure + /// + /// In en, this message translates to: + /// **'Account creation failed'** + String get accountCreationFailed; + + /// Message indicating successful account creation + /// + /// In en, this message translates to: + /// **'Account created successfully!'** + String get accountCreatedSuccessfully; + + /// Message welcoming user to new account + /// + /// In en, this message translates to: + /// **'Welcome to your new account!'** + String get welcomeToYourNewAccount; + + /// Generic location + /// + /// In en, this message translates to: + /// **'Somewhere'** + String get somewhere; + + /// Label to start an application + /// + /// In en, this message translates to: + /// **'Start Application'** + String get startApplication; + + /// Label to explore schools + /// + /// In en, this message translates to: + /// **'Explore Schools'** + String get exploreSchools; + + /// Label to dismiss + /// + /// In en, this message translates to: + /// **'Dismiss'** + String get dismiss; + + /// Label to view + /// + /// In en, this message translates to: + /// **'View >'** + String get view; + + /// Message indicating loading feeds + /// + /// In en, this message translates to: + /// **'Loading your feeds...'** + String get loadingYourFeeds; + + /// Message indicating to cross fingers + /// + /// In en, this message translates to: + /// **'Cross your fingers'** + String get crossYourFingers; + + /// Message indicating to wait + /// + /// In en, this message translates to: + /// **'Please wait...'** + String get pleaseWait; + + /// Error message when feeds fail to load + /// + /// In en, this message translates to: + /// **'Error loading your feeds'** + String get errorLoadingYourFeeds; + + /// Message indicating all content is viewed + /// + /// In en, this message translates to: + /// **'All caught up!'** + String get allCaughtUp; + + /// Error message when classrooms fail to load + /// + /// In en, this message translates to: + /// **'Unable to load classrooms'** + String get unableToLoadClassrooms; + + /// Message indicating no classrooms + /// + /// In en, this message translates to: + /// **'No classrooms'** + String get noClassrooms; + + /// Message indicating user is not a member of any classroom + /// + /// In en, this message translates to: + /// **'You are not a member of any classroom yet'** + String get youAreNotAMemberOfAnyClassroomYet; + + /// Generic loading message + /// + /// In en, this message translates to: + /// **'Loading...'** + String get loading; + + /// Message indicating form retrieval + /// + /// In en, this message translates to: + /// **'Getting form...'** + String get gettingForm; + + /// Label for instructions + /// + /// In en, this message translates to: + /// **'Instructions'** + String get instructions; + + /// Label for next action + /// + /// In en, this message translates to: + /// **'Next'** + String get next; + + /// Label for next step + /// + /// In en, this message translates to: + /// **'Next Step'** + String get nextStep; + + /// Message indicating next step of application + /// + /// In en, this message translates to: + /// **'Next step of the application goes here.'** + String get nextStepOfTheApplicationGoesHere; + + /// Message indicating a required question + /// + /// In en, this message translates to: + /// **'This question is required'** + String get thisQuestionIsRequired; + + /// Message prompting user to enter their answer + /// + /// In en, this message translates to: + /// **'Enter your answer'** + String get enterYourAnswer; + + /// Message indicating a required field + /// + /// In en, this message translates to: + /// **'This field is required'** + String get thisFieldIsRequired; + + /// Message indicating to tap to select a date + /// + /// In en, this message translates to: + /// **'Tap to select date'** + String get tapToSelectDate; + + /// Label to submit application + /// + /// In en, this message translates to: + /// **'Submit Application'** + String get submitApplication; + + /// Shows the current question number and total number of questions + /// + /// In en, this message translates to: + /// **'question {index} of {length}'** + String questionXofX(int index, int length); + + /// Error message for timed out request + /// + /// In en, this message translates to: + /// **'Request timed out. Please check your connection.'** + String get requestTimedOutPleaseCheckYourConnection; + + /// Error message for network error + /// + /// In en, this message translates to: + /// **'Network error. Please check your internet connection.'** + String get networkErrorPleaseCheckYourInternetConnection; + + /// Error message for failed submission + /// + /// In en, this message translates to: + /// **'Submission failed. Please try again.'** + String get submissionFailedPleaseTryAgain; + + /// Message indicating form submission + /// + /// In en, this message translates to: + /// **'Submitting form...'** + String get submittingForm; + + /// Message indicating information processing + /// + /// In en, this message translates to: + /// **'Almost there! Processing your information...'** + String get almostThereProcessingYourInformation; + + /// Message indicating submission finalization + /// + /// In en, this message translates to: + /// **'Finalizing your submission...'** + String get finalizingYourSubmission; + + /// Message after successful submission + /// + /// In en, this message translates to: + /// **'Submission Successful!'** + String get submissionSuccessful; + + /// Message indicating successful form submission + /// + /// In en, this message translates to: + /// **'Your form has been submitted successfully.'** + String get yourFormHasBeenSubmittedSuccessfully; + + /// Message indicating a confirmation email will be sent + /// + /// In en, this message translates to: + /// **'You will receive a confirmation email shortly.'** + String get youWillReceiveAConfirmationEmailShortly; + + /// Label to return to dashboard + /// + /// In en, this message translates to: + /// **'Return to Dashboard'** + String get returnToDashboard; + + /// Message indicating submission failure + /// + /// In en, this message translates to: + /// **'Submission Failed'** + String get submissionFailed; + + /// Message prompting user to check information and try again + /// + /// In en, this message translates to: + /// **'Please check your information and try again.'** + String get pleaseCheckYourInformationAndTryAgain; + + /// Label to try again + /// + /// In en, this message translates to: + /// **'Try Again'** + String get tryAgain; + + /// Label to go back + /// + /// In en, this message translates to: + /// **'Go Back'** + String get goBack; + + /// Error message when the application form fails to load + /// + /// In en, this message translates to: + /// **'Error loading application form'** + String get errorLoadingApplicationForm; + + /// Message to select an application form + /// + /// In en, this message translates to: + /// **'Select application form'** + String get selectApplicationForm; + + /// No description provided for @banana. + /// + /// In en, this message translates to: + /// **'banana'** + String get banana; + + /// No description provided for @schoolApplications. + /// + /// In en, this message translates to: + /// **'School Applications'** + String get schoolApplications; + + /// No description provided for @gettingAllSchoolMembers. + /// + /// In en, this message translates to: + /// **'Getting all school members...'** + String get gettingAllSchoolMembers; + + /// No description provided for @crunchingDatabaseRecords. + /// + /// In en, this message translates to: + /// **'Crunching database records...'** + String get crunchingDatabaseRecords; + + /// No description provided for @schoolMembers. + /// + /// In en, this message translates to: + /// **'School Members'** + String get schoolMembers; + + /// No description provided for @exit. + /// + /// In en, this message translates to: + /// **'Exit'** + String get exit; + + /// No description provided for @gettingAllSchoolApplications. + /// + /// In en, this message translates to: + /// **'Getting all school applications'** + String get gettingAllSchoolApplications; + + /// No description provided for @errorGettingApplicationsAttempts. + /// + /// In en, this message translates to: + /// **'Error getting applications attempts'** + String get errorGettingApplicationsAttempts; + + /// No description provided for @applicationAccepted. + /// + /// In en, this message translates to: + /// **'Application accepted.'** + String get applicationAccepted; + + /// No description provided for @applicationDeclined. + /// + /// In en, this message translates to: + /// **'Application declined.'** + String get applicationDeclined; + + /// No description provided for @reviewApplication. + /// + /// In en, this message translates to: + /// **'Review Application'** + String get reviewApplication; + + /// No description provided for @noAnswer. + /// + /// In en, this message translates to: + /// **'(No answer)'** + String get noAnswer; + + /// No description provided for @accept. + /// + /// In en, this message translates to: + /// **'Accept'** + String get accept; + + /// No description provided for @decline. + /// + /// In en, this message translates to: + /// **'Decline'** + String get decline; + + /// No description provided for @selectTheRoleForTheNewUser. + /// + /// In en, this message translates to: + /// **'Select the role for the new user:'** + String get selectTheRoleForTheNewUser; + + /// No description provided for @teacher. + /// + /// In en, this message translates to: + /// **'Teacher'** + String get teacher; + + /// No description provided for @admin. + /// + /// In en, this message translates to: + /// **'Admin'** + String get admin; +} + +class _AppLocalizationsDelegate extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupAppLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => ['en', 'fr'].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +AppLocalizations lookupAppLocalizations(Locale locale) { + + + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'en': return AppLocalizationsEn(); + case 'fr': return AppLocalizationsFr(); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); +} diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart new file mode 100644 index 0000000..488a87e --- /dev/null +++ b/lib/l10n/app_localizations_en.dart @@ -0,0 +1,427 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for English (`en`). +class AppLocalizationsEn extends AppLocalizations { + AppLocalizationsEn([String locale = 'en']) : super(locale); + + @override + String get helloWorld => 'Hello World!'; + + @override + String get errorLoadingYourSession => 'Error loading your session'; + + @override + String get reload => 'Reload'; + + @override + String get logout => 'logout'; + + @override + String get error => 'Error'; + + @override + String get loadingYourOnlineAccounts => 'Loading your online accounts...'; + + @override + String get welcomeToTheIntranetOfSchools => 'Welcome to the Intranet of Schools'; + + @override + String errorSnapshotError(Object error) { + return 'Error: $error'; + } + + @override + String get yourSchools => 'Your schools'; + + @override + String get dashboard => 'Dashboard'; + + @override + String get schedule => 'Schedule'; + + @override + String get classrooms => 'Classrooms'; + + @override + String get profile => 'Profile'; + + @override + String get settings => 'Settings'; + + @override + String get signOut => 'Sign Out'; + + @override + String get welcomeBack => 'Welcome back'; + + @override + String get dashboardBaseContent => 'Dashboard Base Content'; + + @override + String get welcome => 'Welcome!'; + + @override + String get connect => 'Connect'; + + @override + String get register => 'Register'; + + @override + String get schools => 'Schools'; + + @override + String get home => 'Home'; + + @override + String get intranetOfSchools => 'Intranet of Schools'; + + @override + String get noSchools => 'No schools'; + + @override + String get noSchoolMembership => 'You are a member of no school yet'; + + @override + String get explore => 'Explore'; + + @override + String get youAreAMemberOfNoSchoolYet => 'You are a member of no school yet'; + + @override + String get waitALittleBit => 'Wait a little bit ...'; + + @override + String get manualSignup => 'Manual Signup >'; + + @override + String get successfullySignedUp => 'Successfully signed up'; + + @override + String get yourName => 'Your Name'; + + @override + String get yourPassword => 'Your password'; + + @override + String get signin => 'Signin >'; + + @override + String get whatRoleBestFitsYou => 'What role best fits you?'; + + @override + String get student => 'Student'; + + @override + String get instructor => 'Instructor'; + + @override + String get administrator => 'Administrator'; + + @override + String get parent => 'Parent'; + + @override + String get role => 'Role'; + + @override + String get weak => 'Weak'; + + @override + String get moderate => 'Moderate'; + + @override + String get strong => 'Strong'; + + @override + String get suggestedPassword => 'Suggested Password'; + + @override + String get cancel => 'Cancel'; + + @override + String get copy => 'Copy'; + + @override + String get useThis => 'Use This'; + + @override + String get password => 'Password'; + + @override + String get generatePassword => 'Generate password'; + + @override + String get minimum8Characters => 'Minimum 8 characters'; + + @override + String get number09 => 'Number (0-9)'; + + @override + String get lowercaseLetterAZ => 'Lowercase letter (a-z)'; + + @override + String get specialCharacter => 'Special character (!@#...)'; + + @override + String get uppercaseLetterAZ => 'Uppercase letter (A-Z)'; + + @override + String get continuer => 'Continue'; + + @override + String strengthlabelPassword(Object _strengthLabel) { + return '\$_strengthLabel password'; + } + + @override + String get createYourProfile => 'Create Your Profile'; + + @override + String get fullName => 'Full Name'; + + @override + String get username => 'Username'; + + @override + String get profileSetup => 'Profile Setup'; + + @override + String get checkingUsernameAvailability => 'Checking username availability...'; + + @override + String get usernameMustBeAtLeast3CharactersAndCanOnlyContainNlowercaseLettersNumbersUnderscoresAndPeriods => 'Username must be at least 3 characters and can only contain:\\nlowercase letters, numbers, underscores (_), and periods (.)'; + + @override + String get thisUsernameIsAlreadyTaken => 'This username is already taken'; + + @override + String get pleaseSelectADateOfBirth => 'Please select a date of birth.'; + + @override + String get dateOfBirth => 'Date of Birth'; + + @override + String get chooseYourDateOfBirth => 'Choose your date of birth'; + + @override + String get selectDate => 'Select date'; + + @override + String get settingUpYourNewAccount => 'Setting up your new account...'; + + @override + String get preparingYourWorkspace => 'Preparing your workspace...'; + + @override + String get configuringSettings => 'Configuring settings...'; + + @override + String get almostThere => 'Almost there...'; + + @override + String get justAFewMoreMoments => 'Just a few more moments...'; + + @override + String get creatingYourProfile => 'Creating your profile...'; + + @override + String get settingUpYourPreferences => 'Setting up your preferences...'; + + @override + String get finalizingYourAccount => 'Finalizing your account...'; + + @override + String get loadingYourDashboard => 'Loading your dashboard...'; + + @override + String get creatingYourAccount => 'Creating your account'; + + @override + String get accountCreationFailed => 'Account creation failed'; + + @override + String get accountCreatedSuccessfully => 'Account created successfully!'; + + @override + String get welcomeToYourNewAccount => 'Welcome to your new account!'; + + @override + String get somewhere => 'Somewhere'; + + @override + String get startApplication => 'Start Application'; + + @override + String get exploreSchools => 'Explore Schools'; + + @override + String get dismiss => 'Dismiss'; + + @override + String get view => 'View >'; + + @override + String get loadingYourFeeds => 'Loading your feeds...'; + + @override + String get crossYourFingers => 'Cross your fingers'; + + @override + String get pleaseWait => 'Please wait...'; + + @override + String get errorLoadingYourFeeds => 'Error loading your feeds'; + + @override + String get allCaughtUp => 'All caught up!'; + + @override + String get unableToLoadClassrooms => 'Unable to load classrooms'; + + @override + String get noClassrooms => 'No classrooms'; + + @override + String get youAreNotAMemberOfAnyClassroomYet => 'You are not a member of any classroom yet'; + + @override + String get loading => 'Loading...'; + + @override + String get gettingForm => 'Getting form...'; + + @override + String get instructions => 'Instructions'; + + @override + String get next => 'Next'; + + @override + String get nextStep => 'Next Step'; + + @override + String get nextStepOfTheApplicationGoesHere => 'Next step of the application goes here.'; + + @override + String get thisQuestionIsRequired => 'This question is required'; + + @override + String get enterYourAnswer => 'Enter your answer'; + + @override + String get thisFieldIsRequired => 'This field is required'; + + @override + String get tapToSelectDate => 'Tap to select date'; + + @override + String get submitApplication => 'Submit Application'; + + @override + String questionXofX(int index, int length) { + return 'question $index of $length'; + } + + @override + String get requestTimedOutPleaseCheckYourConnection => 'Request timed out. Please check your connection.'; + + @override + String get networkErrorPleaseCheckYourInternetConnection => 'Network error. Please check your internet connection.'; + + @override + String get submissionFailedPleaseTryAgain => 'Submission failed. Please try again.'; + + @override + String get submittingForm => 'Submitting form...'; + + @override + String get almostThereProcessingYourInformation => 'Almost there! Processing your information...'; + + @override + String get finalizingYourSubmission => 'Finalizing your submission...'; + + @override + String get submissionSuccessful => 'Submission Successful!'; + + @override + String get yourFormHasBeenSubmittedSuccessfully => 'Your form has been submitted successfully.'; + + @override + String get youWillReceiveAConfirmationEmailShortly => 'You will receive a confirmation email shortly.'; + + @override + String get returnToDashboard => 'Return to Dashboard'; + + @override + String get submissionFailed => 'Submission Failed'; + + @override + String get pleaseCheckYourInformationAndTryAgain => 'Please check your information and try again.'; + + @override + String get tryAgain => 'Try Again'; + + @override + String get goBack => 'Go Back'; + + @override + String get errorLoadingApplicationForm => 'Error loading application form'; + + @override + String get selectApplicationForm => 'Select application form'; + + @override + String get banana => 'banana'; + + @override + String get schoolApplications => 'School Applications'; + + @override + String get gettingAllSchoolMembers => 'Getting all school members...'; + + @override + String get crunchingDatabaseRecords => 'Crunching database records...'; + + @override + String get schoolMembers => 'School Members'; + + @override + String get exit => 'Exit'; + + @override + String get gettingAllSchoolApplications => 'Getting all school applications'; + + @override + String get errorGettingApplicationsAttempts => 'Error getting applications attempts'; + + @override + String get applicationAccepted => 'Application accepted.'; + + @override + String get applicationDeclined => 'Application declined.'; + + @override + String get reviewApplication => 'Review Application'; + + @override + String get noAnswer => '(No answer)'; + + @override + String get accept => 'Accept'; + + @override + String get decline => 'Decline'; + + @override + String get selectTheRoleForTheNewUser => 'Select the role for the new user:'; + + @override + String get teacher => 'Teacher'; + + @override + String get admin => 'Admin'; +} diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart new file mode 100644 index 0000000..79be68e --- /dev/null +++ b/lib/l10n/app_localizations_fr.dart @@ -0,0 +1,427 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for French (`fr`). +class AppLocalizationsFr extends AppLocalizations { + AppLocalizationsFr([String locale = 'fr']) : super(locale); + + @override + String get helloWorld => 'Bonjour le monde !'; + + @override + String get errorLoadingYourSession => 'Erreur lors du chargement de votre session'; + + @override + String get reload => 'Recharger'; + + @override + String get logout => 'Se déconnecter'; + + @override + String get error => 'Erreur'; + + @override + String get loadingYourOnlineAccounts => 'Chargement de vos comptes en ligne...'; + + @override + String get welcomeToTheIntranetOfSchools => 'Bienvenue sur l\'Intranet des Écoles'; + + @override + String errorSnapshotError(Object error) { + return 'Erreur : $error'; + } + + @override + String get yourSchools => 'Vos écoles'; + + @override + String get dashboard => 'Tableau de bord'; + + @override + String get schedule => 'Emploi du temps'; + + @override + String get classrooms => 'Salles de classe'; + + @override + String get profile => 'Profil'; + + @override + String get settings => 'Paramètres'; + + @override + String get signOut => 'Se déconnecter'; + + @override + String get welcomeBack => 'Bon retour'; + + @override + String get dashboardBaseContent => 'Contenu de base du tableau de bord'; + + @override + String get welcome => 'Bienvenue !'; + + @override + String get connect => 'Se connecter'; + + @override + String get register => 'S\'inscrire'; + + @override + String get schools => 'Écoles'; + + @override + String get home => 'Home'; + + @override + String get intranetOfSchools => 'Intranet des Écoles'; + + @override + String get noSchools => 'Aucune école'; + + @override + String get noSchoolMembership => 'Vous n\'êtes membre d\'aucune école pour le moment'; + + @override + String get explore => 'Explorer'; + + @override + String get youAreAMemberOfNoSchoolYet => 'Vous n\'êtes membre d\'aucune école pour le moment'; + + @override + String get waitALittleBit => 'Patientez un instant...'; + + @override + String get manualSignup => 'Inscription manuelle >'; + + @override + String get successfullySignedUp => 'Inscription réussie'; + + @override + String get yourName => 'Votre nom'; + + @override + String get yourPassword => 'Votre mot de passe'; + + @override + String get signin => 'Se connecter >'; + + @override + String get whatRoleBestFitsYou => 'Quel rôle vous correspond le mieux ?'; + + @override + String get student => 'Student'; + + @override + String get instructor => 'Professeur'; + + @override + String get administrator => 'Administrateur'; + + @override + String get parent => 'Parent'; + + @override + String get role => 'Rôle'; + + @override + String get weak => 'Faible'; + + @override + String get moderate => 'Moyen'; + + @override + String get strong => 'Fort'; + + @override + String get suggestedPassword => 'Mot de passe suggéré'; + + @override + String get cancel => 'Annuler'; + + @override + String get copy => 'Copier'; + + @override + String get useThis => 'Utiliser'; + + @override + String get password => 'Mot de passe'; + + @override + String get generatePassword => 'Générer un mot de passe'; + + @override + String get minimum8Characters => 'Minimum 8 caractères'; + + @override + String get number09 => 'Chiffre (0-9)'; + + @override + String get lowercaseLetterAZ => 'Lettre minuscule (a-z)'; + + @override + String get specialCharacter => 'Caractère spécial (!@#...)'; + + @override + String get uppercaseLetterAZ => 'Lettre majuscule (A-Z)'; + + @override + String get continuer => 'Continuer'; + + @override + String strengthlabelPassword(Object _strengthLabel) { + return 'Mot de passe \$_strengthLabel'; + } + + @override + String get createYourProfile => 'Créer votre profil'; + + @override + String get fullName => 'Nom complet'; + + @override + String get username => 'Nom d\'utilisateur'; + + @override + String get profileSetup => 'Configuration du profil'; + + @override + String get checkingUsernameAvailability => 'Vérification de la disponibilité du nom d\'utilisateur...'; + + @override + String get usernameMustBeAtLeast3CharactersAndCanOnlyContainNlowercaseLettersNumbersUnderscoresAndPeriods => 'Le nom d\'utilisateur doit comporter au moins 3 caractères et ne peut contenir que :\ndes lettres minuscules, des chiffres, des underscores (_) et des points (.)'; + + @override + String get thisUsernameIsAlreadyTaken => 'Ce nom d\'utilisateur est déjà pris'; + + @override + String get pleaseSelectADateOfBirth => 'Veuillez sélectionner une date de naissance.'; + + @override + String get dateOfBirth => 'Date de naissance'; + + @override + String get chooseYourDateOfBirth => 'Choisissez votre date de naissance'; + + @override + String get selectDate => 'Sélectionner une date'; + + @override + String get settingUpYourNewAccount => 'Configuration de votre nouveau compte...'; + + @override + String get preparingYourWorkspace => 'Préparation de votre espace de travail...'; + + @override + String get configuringSettings => 'Configuration des paramètres...'; + + @override + String get almostThere => 'Presque là...'; + + @override + String get justAFewMoreMoments => 'Encore quelques instants...'; + + @override + String get creatingYourProfile => 'Création de votre profil...'; + + @override + String get settingUpYourPreferences => 'Configuration de vos préférences...'; + + @override + String get finalizingYourAccount => 'Finalisation de votre compte...'; + + @override + String get loadingYourDashboard => 'Chargement de votre tableau de bord...'; + + @override + String get creatingYourAccount => 'Création de votre compte'; + + @override + String get accountCreationFailed => 'La création du compte a échoué'; + + @override + String get accountCreatedSuccessfully => 'Compte créé avec succès !'; + + @override + String get welcomeToYourNewAccount => 'Bienvenue sur votre nouveau compte !'; + + @override + String get somewhere => 'Quelque part'; + + @override + String get startApplication => 'Démarrer l\'application'; + + @override + String get exploreSchools => 'Explorer les écoles'; + + @override + String get dismiss => 'Ignorer'; + + @override + String get view => 'Voir >'; + + @override + String get loadingYourFeeds => 'Chargement de vos flux...'; + + @override + String get crossYourFingers => 'Croisez les doigts'; + + @override + String get pleaseWait => 'Please wait...'; + + @override + String get errorLoadingYourFeeds => 'Erreur lors du chargement de vos flux'; + + @override + String get allCaughtUp => 'Tout est à jour !'; + + @override + String get unableToLoadClassrooms => 'Impossible de charger les salles de classe'; + + @override + String get noClassrooms => 'Aucune salle de classe'; + + @override + String get youAreNotAMemberOfAnyClassroomYet => 'Vous n\'êtes membre d\'aucune salle de classe pour le moment'; + + @override + String get loading => 'Chargement...'; + + @override + String get gettingForm => 'Récupération du formulaire...'; + + @override + String get instructions => 'Instructions'; + + @override + String get next => 'Suivant'; + + @override + String get nextStep => 'Étape suivante'; + + @override + String get nextStepOfTheApplicationGoesHere => 'La prochaine étape de la demande se trouve ici.'; + + @override + String get thisQuestionIsRequired => 'Cette question est obligatoire'; + + @override + String get enterYourAnswer => 'Entrez votre réponse'; + + @override + String get thisFieldIsRequired => 'Ce champ est obligatoire'; + + @override + String get tapToSelectDate => 'Appuyez pour sélectionner la date'; + + @override + String get submitApplication => 'Soumettre la demande'; + + @override + String questionXofX(int index, int length) { + return 'Question $index sur $length'; + } + + @override + String get requestTimedOutPleaseCheckYourConnection => 'La requête a expiré. Veuillez vérifier votre connexion.'; + + @override + String get networkErrorPleaseCheckYourInternetConnection => 'Erreur réseau. Veuillez vérifier votre connexion Internet.'; + + @override + String get submissionFailedPleaseTryAgain => 'La soumission a échoué. Veuillez réessayer.'; + + @override + String get submittingForm => 'Soumission du formulaire...'; + + @override + String get almostThereProcessingYourInformation => 'Presque là ! Traitement de vos informations...'; + + @override + String get finalizingYourSubmission => 'Finalisation de votre soumission...'; + + @override + String get submissionSuccessful => 'Soumission réussie !'; + + @override + String get yourFormHasBeenSubmittedSuccessfully => 'Votre formulaire a été soumis avec succès.'; + + @override + String get youWillReceiveAConfirmationEmailShortly => 'Vous recevrez un e-mail de confirmation sous peu.'; + + @override + String get returnToDashboard => 'Retour au tableau de bord'; + + @override + String get submissionFailed => 'Échec de la soumission'; + + @override + String get pleaseCheckYourInformationAndTryAgain => 'Veuillez vérifier vos informations et réessayer.'; + + @override + String get tryAgain => 'Réessayer'; + + @override + String get goBack => 'Retourner'; + + @override + String get errorLoadingApplicationForm => 'Erreur lors du chargement du formulaire de demande'; + + @override + String get selectApplicationForm => 'Sélectionner le formulaire de demande'; + + @override + String get banana => 'banana'; + + @override + String get schoolApplications => 'School Applications'; + + @override + String get gettingAllSchoolMembers => 'Getting all school members...'; + + @override + String get crunchingDatabaseRecords => 'Crunching database records...'; + + @override + String get schoolMembers => 'School Members'; + + @override + String get exit => 'Exit'; + + @override + String get gettingAllSchoolApplications => 'Getting all school applications'; + + @override + String get errorGettingApplicationsAttempts => 'Error getting applications attempts'; + + @override + String get applicationAccepted => 'Application accepted.'; + + @override + String get applicationDeclined => 'Application declined.'; + + @override + String get reviewApplication => 'Review Application'; + + @override + String get noAnswer => '(No answer)'; + + @override + String get accept => 'Accept'; + + @override + String get decline => 'Decline'; + + @override + String get selectTheRoleForTheNewUser => 'Select the role for the new user:'; + + @override + String get teacher => 'Teacher'; + + @override + String get admin => 'Admin'; +} diff --git a/lib/loadingpage.dart b/lib/loadingpage.dart index c7d9168..b2399ce 100644 --- a/lib/loadingpage.dart +++ b/lib/loadingpage.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class LoadingPage extends StatefulWidget { final List messages; @@ -51,7 +50,7 @@ class _LoadingPageState extends State { const CircularProgressIndicator(), const SizedBox(height: 24), Text( - AppLocalizations.of(context)!.waitALittleBit, + "Wait a little bit ...", style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center, ), diff --git a/lib/pages/dashboard/base.dart b/lib/pages/dashboard/base.dart index a56d8e7..e3bcb24 100644 --- a/lib/pages/dashboard/base.dart +++ b/lib/pages/dashboard/base.dart @@ -5,8 +5,6 @@ import './nav.dart'; import './dashboardnav.dart'; import '../../analytics.dart' as analytics; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - class DashboardBase extends StatelessWidget { final Session session; final User user; @@ -20,9 +18,7 @@ class DashboardBase extends StatelessWidget { required this.title, }); Widget buildContent(BuildContext context) { - return Center( - child: Text(AppLocalizations.of(context)!.dashboardBaseContent), - ); + return Center(child: Text("Dashboard Base Content")); } @override diff --git a/lib/pages/dashboard/classrooms.dart b/lib/pages/dashboard/classrooms.dart index 9535e3c..9ae82bd 100644 --- a/lib/pages/dashboard/classrooms.dart +++ b/lib/pages/dashboard/classrooms.dart @@ -1,6 +1,8 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; +import 'dart:ui'; import 'package:google_fonts/google_fonts.dart'; +import 'package:transparent_image/transparent_image.dart'; // For fade-in + import './base.dart'; import '../../errorpage.dart'; import '../../backend/models.dart' as models; @@ -21,10 +23,8 @@ class DashboardClassroomsPage extends DashboardBase { builder: (context, snapshot) { if (snapshot.hasError) { return ErrorPage( - title: AppLocalizations.of(context)!.error, - description: - AppLocalizations.of(context)!.unableToLoadClassrooms + - snapshot.error.toString(), + title: "Error", + description: "Unable to load classrooms ${snapshot.error}", ); } else if (!snapshot.hasData) { return CircularProgressIndicator( @@ -37,14 +37,12 @@ class DashboardClassroomsPage extends DashboardBase { child: Column( children: [ Text( - AppLocalizations.of(context)!.noClassrooms, + "No classrooms", style: Theme.of(context).textTheme.titleLarge, ), Container(height: 10), Text( - AppLocalizations.of( - context, - )!.youAreNotAMemberOfAnyClassroomYet, + "You are not a member of any classroom yet", style: Theme.of(context).textTheme.bodyMedium, ), ], @@ -71,9 +69,7 @@ class DashboardClassroomsPage extends DashboardBase { child: Column( children: [ Text( - AppLocalizations.of( - context, - )!.noClassrooms, + "No classrooms", style: Theme.of( context, @@ -81,9 +77,7 @@ class DashboardClassroomsPage extends DashboardBase { ), Container(height: 10), Text( - AppLocalizations.of( - context, - )!.youAreNotAMemberOfAnyClassroomYet, + "You are not a member of any classroom yet", style: Theme.of( context, @@ -128,60 +122,91 @@ class StudentClassroomCard extends StatelessWidget { }); @override Widget build(BuildContext context) { - return GestureDetector( + return InkWell( onTap: () {}, child: Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), - clipBehavior: Clip.antiAliasWithSaveLayer, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(15), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(45), - child: Image.network( - classroom.profile.getPath(), - height: 100, - width: 100, - fit: BoxFit.cover, - ), + elevation: 2, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + margin: const EdgeInsets.symmetric(vertical: 8), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + children: [ + Container( + width: 120, // Increased width + height: 120, // Increased height + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + image: DecorationImage( + image: NetworkImage(classroom.profile.getPath()), + fit: + BoxFit + .cover, // Ensure image covers the entire container ), - Container(width: 10), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container(height: 20), - Text( - classroom.name, - style: GoogleFonts.lato( - fontSize: 20, - fontWeight: FontWeight.w700, - ).copyWith( - color: const Color.fromRGBO(55, 71, 79, 1), - ), - ), - Container(height: 5), - Text( - classroom.role, - style: GoogleFonts.lato( - fontSize: 16, - fontWeight: FontWeight.w400, - ).copyWith( - color: const Color.fromRGBO(158, 158, 158, 1), - ), + color: Colors.transparent, + backgroundBlendMode: BlendMode.srcOver, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: Container( + color: Colors.transparent, + child: Center( + child: FadeInImage.memoryNetwork( + placeholder: kTransparentImage, + image: classroom.profile.getPath(), + width: 70, // Increased width + height: 70, // increased height + fit: BoxFit.cover, + imageErrorBuilder: (context, error, stackTrace) { + return Container( + color: Colors.grey.shade300, + child: const Center( + child: Icon( + Icons.image_not_supported_outlined, + color: Colors.grey, + ), + ), + ); + }, ), - ], + ), ), ), - ], + ), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + classroom.info.name, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 8), + // Display school.school_name as preformatted text + Text( + "@${classroom.classroomName}", + style: GoogleFonts.sourceCodePro( + // Use a monospace font + fontSize: 12, // Smaller font size + color: + Colors + .grey[700], // Darker grey for preformatted text + ), + ), + ], + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/pages/dashboard/dashboard.dart b/lib/pages/dashboard/dashboard.dart index 2d8941e..72d3aeb 100644 --- a/lib/pages/dashboard/dashboard.dart +++ b/lib/pages/dashboard/dashboard.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import './feeds.dart'; import './base.dart'; @@ -22,14 +21,14 @@ class DashboardPage extends DashboardBase { if (snapshot.connectionState == ConnectionState.waiting) { return LoadingPage( messages: [ - AppLocalizations.of(context)!.loadingYourFeeds, - AppLocalizations.of(context)!.pleaseWait, - AppLocalizations.of(context)!.crossYourFingers, + "Loading your feeds...", + "Please wait...", + "Cross your fingers", ], ); } else if (snapshot.hasError) { return ErrorPage( - title: AppLocalizations.of(context)!.errorLoadingYourFeeds, + title: "Error loading your feeds", description: snapshot.error.toString(), icon: Icon( Icons.signal_wifi_off, @@ -80,7 +79,7 @@ class _FeedsViewState extends State { const SizedBox(height: 24), Text( - AppLocalizations.of(context)!.allCaughtUp, + "All caught up!", style: Theme.of(context).textTheme.headlineLarge, ), ], diff --git a/lib/pages/dashboard/dashboardnav.dart b/lib/pages/dashboard/dashboardnav.dart index b659b11..8fb4d4c 100644 --- a/lib/pages/dashboard/dashboardnav.dart +++ b/lib/pages/dashboard/dashboardnav.dart @@ -3,7 +3,6 @@ import '../../backend/models.dart'; import './dashboard.dart'; import './classrooms.dart'; import './schools.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; Widget dashboardBottomNav( BuildContext context, @@ -19,12 +18,9 @@ Widget dashboardBottomNav( selectedItemColor: Theme.of(context).colorScheme.primary, unselectedItemColor: Colors.grey.shade600, items: [ - BottomNavigationBarItem(icon: Icon(Icons.dashboard), label: AppLocalizations.of(context)!.home), - BottomNavigationBarItem(icon: Icon(Icons.class_), label: AppLocalizations.of(context)!.classrooms), - BottomNavigationBarItem( - icon: Icon(Icons.school), - label: AppLocalizations.of(context)!.schools, - ), + BottomNavigationBarItem(icon: Icon(Icons.dashboard), label: "Home"), + BottomNavigationBarItem(icon: Icon(Icons.class_), label: "Classrooms"), + BottomNavigationBarItem(icon: Icon(Icons.school), label: "Schools"), ], onTap: (index) { switch (index) { diff --git a/lib/pages/dashboard/feeds.dart b/lib/pages/dashboard/feeds.dart index 11fc949..45186d7 100644 --- a/lib/pages/dashboard/feeds.dart +++ b/lib/pages/dashboard/feeds.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; @@ -101,7 +100,7 @@ class NotificationFeedView extends StatelessWidget { ), foregroundColor: WidgetStateProperty.all(colorScheme.error), ), - child: Text(AppLocalizations.of(context)!.dismiss), + child: Text("Dismiss"), ), ), ], @@ -123,7 +122,7 @@ class NotificationFeedView extends StatelessWidget { ), foregroundColor: WidgetStateProperty.all(colorScheme.error), ), - child: Text(AppLocalizations.of(context)!.dismiss), + child: Text("Dismiss"), ), ), ElevatedButton( @@ -132,7 +131,7 @@ class NotificationFeedView extends StatelessWidget { backgroundColor: colorScheme.primary, foregroundColor: colorScheme.onPrimary, ), - child: Text(AppLocalizations.of(context)!.view), + child: Text("View >"), ), ], ), diff --git a/lib/pages/dashboard/nav.dart b/lib/pages/dashboard/nav.dart index 6ca7e1e..1025a32 100644 --- a/lib/pages/dashboard/nav.dart +++ b/lib/pages/dashboard/nav.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:ins/pages/dashboard/classrooms.dart'; +import 'package:ins/pages/dashboard/schools.dart'; import 'package:ins/profile.dart'; import '../../backend/sessions.dart'; import './dashboard.dart'; import '../../backend/models.dart' as models; import '../welcome.dart'; import 'package:ins/theme.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; Widget dashboardNav( BuildContext context, @@ -20,7 +21,7 @@ Widget dashboardNav( DrawerHeader(child: Container()), ListTile( leading: Icon(Icons.dashboard), - title: Text(AppLocalizations.of(context)!.dashboard), + title: Text("Dashboard"), onTap: () => Navigator.pushReplacement( context, @@ -32,13 +33,31 @@ Widget dashboardNav( ), ListTile( leading: Icon(Icons.book), - title: Text(AppLocalizations.of(context)!.classrooms), - onTap: () {}, + title: Text("Classrooms"), + onTap: () { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: + (context) => + DashboardClassroomsPage(session: session, user: user), + ), + ); + }, ), ListTile( leading: Icon(Icons.calendar_today), - title: Text(AppLocalizations.of(context)!.schedule), - onTap: () {}, + title: Text("Schools"), + onTap: () { + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: + (context) => + DashboardSchoolsPage(session: session, user: user), + ), + ); + }, ), ], ), @@ -85,23 +104,23 @@ Widget dashboardAccountNav( ), ListTile( leading: Icon(Icons.person), - title: Text(AppLocalizations.of(context)!.profile), + title: Text("Profile"), onTap: () => Navigator.pop(context), ), ListTile( leading: Icon(Icons.settings), - title: Text(AppLocalizations.of(context)!.settings), + title: Text("Settings"), onTap: () {}, ), ListTile( leading: Icon(Icons.logout), - title: Text(AppLocalizations.of(context)!.signOut), + title: Text("Sign Out"), onTap: () { sessionManager.clearSession(); Navigator.pushAndRemoveUntil( context, MaterialPageRoute( - builder: (context) => WelcomePage(title: AppLocalizations.of(context)!.welcomeBack), + builder: (context) => WelcomePage(title: "Welcome back"), ), (route) => false, ); diff --git a/lib/pages/dashboard/school/admin/application_form_review.dart b/lib/pages/dashboard/school/admin/application_form_review.dart index 42878ad..907222f 100644 --- a/lib/pages/dashboard/school/admin/application_form_review.dart +++ b/lib/pages/dashboard/school/admin/application_form_review.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:ins/backend/models.dart' as models; @@ -8,6 +7,7 @@ class ApplicationFormReviewPage extends StatefulWidget { final models.Session session; final models.SchoolMember member; final models.User user; + final models.School school; const ApplicationFormReviewPage({ super.key, required this.attempt, @@ -15,6 +15,7 @@ class ApplicationFormReviewPage extends StatefulWidget { required this.session, required this.member, required this.user, + required this.school, }); @override @@ -32,58 +33,193 @@ class _ApplicationFormReviewPageState extends State { _resultMessage = null; }); if (accepted) { - final role = await showModalBottomSheet( - context: context, - builder: (context) { - return SafeArea( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(height: 10), - Text( - AppLocalizations.of(context)!.selectTheRoleForTheNewUser, - style: Theme.of(context).textTheme.headlineMedium, - ), - SizedBox(height: 16), - ListTile( - title: Text(AppLocalizations.of(context)!.student), - onTap: () => Navigator.pop(context, 'student'), - ), - ListTile( - title: Text(AppLocalizations.of(context)!.teacher), - onTap: () => Navigator.pop(context, 'teacher'), - ), - ListTile( - title: Text(AppLocalizations.of(context)!.parent), - onTap: () => Navigator.pop(context, 'parent'), - ), - ListTile( - title: Text(AppLocalizations.of(context)!.admin), - onTap: () => Navigator.pop(context, 'admin'), - ), - ], - ), - ); - }, - ); - if (role != null) { - await widget.attempt.accept(widget.session, role); - Navigator.of(context).pop(); + try { + final role = await showModalBottomSheet( + context: context, + builder: (context) { + return SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 10), + Text( + "Select the role for the new user:", + style: Theme.of(context).textTheme.headlineMedium, + ), + SizedBox(height: 16), + ListTile( + title: Text("Student"), + onTap: () => Navigator.pop(context, 'student'), + ), + ListTile( + title: Text("Teacher"), + onTap: () => Navigator.pop(context, 'teacher'), + ), + ListTile( + title: Text("Parent"), + onTap: () => Navigator.pop(context, 'parent'), + ), + ListTile( + title: Text("Admin"), + onTap: () => Navigator.pop(context, 'admin'), + ), + ], + ), + ); + }, + ); + if (role == null) { + setState(() { + _isProcessing = false; + }); + return; + } + // Step 2: Select classrooms + final classrooms = await widget.school.getClassrooms(widget.session); + final selectedClassrooms = await showModalBottomSheet>( + context: context, + isScrollControlled: true, + builder: (context) { + final List selected = []; + return StatefulBuilder( + builder: (context, setModalState) { + return SafeArea( + child: Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 10), + Text( + "Select classroom(s):", + style: Theme.of(context).textTheme.headlineMedium, + ), + SizedBox(height: 16), + ...classrooms.map( + (c) => CheckboxListTile( + title: Text(c.info.name), + value: selected.contains(c.id), + onChanged: (v) { + setModalState(() { + if (v == true) { + selected.add(c.id); + } else { + selected.remove(c.id); + } + }); + }, + ), + ), + + Padding( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 20, + ), + child: ElevatedButton( + child: Text("Continue"), + onPressed: + () => Navigator.pop(context, selected.toList()), + ), + ), + ], + ), + ), + ); + }, + ); + }, + ); + if (selectedClassrooms == null || selectedClassrooms.isEmpty) { + setState(() { + _isProcessing = false; + }); + return; + } + // Step 3: Select tags + final possibleTags = [ + 'prefect', + 'monitor', + 'sports', + 'music', + 'science', + ]; + final selectedTags = await showModalBottomSheet>( + context: context, + isScrollControlled: true, + builder: (context) { + final selected = {}; + return StatefulBuilder( + builder: (context, setModalState) { + return SafeArea( + child: Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 10), + Text( + "Select tags (optional):", + style: Theme.of(context).textTheme.headlineMedium, + ), + SizedBox(height: 16), + ...possibleTags.map( + (tag) => CheckboxListTile( + title: Text(tag), + value: selected.contains(tag), + onChanged: (v) { + setModalState(() { + if (v == true) { + selected.add(tag); + } else { + selected.remove(tag); + } + }); + }, + ), + ), + ElevatedButton( + child: Text("Finish"), + onPressed: + () => Navigator.pop(context, selected.toList()), + ), + ], + ), + ), + ); + }, + ); + }, + ); + // Call accept with all info + await widget.attempt.accept( + widget.session, + role, + selectedClassrooms, + selectedTags ?? [], + ); Navigator.of(context).pop(); + } catch (e) { + setState(() { + _isProcessing = false; + _resultMessage = "Error: ${e.toString()}"; + }); + return; } } else { await widget.attempt.decline(widget.session); Navigator.of(context).pop(); - Navigator.of(context).pop(); return; } await Future.delayed(const Duration(seconds: 1)); setState(() { _isProcessing = false; _resultMessage = - accepted - ? AppLocalizations.of(context)!.applicationAccepted - : AppLocalizations.of(context)!.applicationDeclined; + accepted ? "Application accepted." : "Application declined."; }); } @@ -92,9 +228,7 @@ class _ApplicationFormReviewPageState extends State { final answers = widget.attempt.answers; final questions = widget.form.questions; return Scaffold( - appBar: AppBar( - title: Text(AppLocalizations.of(context)!.reviewApplication), - ), + appBar: AppBar(title: Text("Review Application")), body: _isProcessing ? const Center(child: CircularProgressIndicator()) @@ -125,9 +259,7 @@ class _ApplicationFormReviewPageState extends State { ), ), subtitle: Text( - a.content.isNotEmpty - ? a.content - : AppLocalizations.of(context)!.noAnswer, + a.content.isNotEmpty ? a.content : "(No answer)", ), ); }, @@ -138,7 +270,12 @@ class _ApplicationFormReviewPageState extends State { padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text( _resultMessage!, - style: const TextStyle(color: Colors.green), + style: TextStyle( + color: + _resultMessage!.startsWith("Error") + ? Colors.red + : Colors.green, + ), ), ), ], @@ -147,7 +284,7 @@ class _ApplicationFormReviewPageState extends State { children: [ ElevatedButton.icon( icon: const Icon(Icons.check), - label: Text(AppLocalizations.of(context)!.accept), + label: Text("Accept"), style: ElevatedButton.styleFrom( backgroundColor: Colors.green, ), @@ -158,7 +295,7 @@ class _ApplicationFormReviewPageState extends State { ), ElevatedButton.icon( icon: const Icon(Icons.close), - label: Text(AppLocalizations.of(context)!.decline), + label: Text("Decline"), style: ElevatedButton.styleFrom( backgroundColor: Colors.red, ), diff --git a/lib/pages/dashboard/school/admin/base.dart b/lib/pages/dashboard/school/admin/base.dart index 1b2f7ec..120b727 100644 --- a/lib/pages/dashboard/school/admin/base.dart +++ b/lib/pages/dashboard/school/admin/base.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:ins/offline.dart'; import 'package:ins/backend/models.dart' as models; @@ -10,13 +9,13 @@ import 'package:ins/theme.dart'; import './dashboard.dart'; import './users.dart'; -class StudentSchoolViewBase extends StatelessWidget { +class AdminSchoolViewBase extends StatelessWidget { final models.Session session; final models.User user; final models.School school; final models.SchoolMember member; final int index; - const StudentSchoolViewBase({ + const AdminSchoolViewBase({ super.key, required this.session, required this.user, @@ -30,7 +29,7 @@ class StudentSchoolViewBase extends StatelessWidget { } String getTitle(BuildContext context) { - return AppLocalizations.of(context)!.dashboard; + return "Dashboard"; } @override @@ -93,24 +92,26 @@ class StudentSchoolViewBase extends StatelessWidget { ), ListTile( leading: Icon(Icons.person), - title: Text(AppLocalizations.of(context)!.profile), + title: Text("Profile"), onTap: () => Navigator.pop(context), ), ListTile( leading: Icon(Icons.settings), - title: Text(AppLocalizations.of(context)!.settings), - onTap: () {}, + title: Text("Settings"), + onTap: () { + Navigator.pop(context); + }, ), ListTile( leading: Icon(Icons.logout), - title: Text(AppLocalizations.of(context)!.exit), + title: Text("Exit"), onTap: () { Navigator.pushAndRemoveUntil( context, MaterialPageRoute( builder: (context) => dashboard.DashboardPage( - title: AppLocalizations.of(context)!.welcomeBack, + title: "Welcome back", session: session, user: user, ), @@ -127,21 +128,15 @@ class StudentSchoolViewBase extends StatelessWidget { selectedItemColor: Theme.of(context).colorScheme.primary, unselectedItemColor: Colors.grey.shade600, items: [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: AppLocalizations.of(context)!.home, - ), - BottomNavigationBarItem( - icon: Icon(Icons.person), - label: AppLocalizations.of(context)!.profile, - ), + BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"), + BottomNavigationBarItem(icon: Icon(Icons.person), label: "Users"), BottomNavigationBarItem( icon: Icon(Icons.class_), - label: AppLocalizations.of(context)!.classrooms, + label: "Classrooms", ), BottomNavigationBarItem( icon: Icon(Icons.apps), - label: AppLocalizations.of(context)!.schoolApplications, + label: "School Applications", ), ], currentIndex: index, diff --git a/lib/pages/dashboard/school/admin/dashboard.dart b/lib/pages/dashboard/school/admin/dashboard.dart index ccbbce1..7278b6f 100644 --- a/lib/pages/dashboard/school/admin/dashboard.dart +++ b/lib/pages/dashboard/school/admin/dashboard.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:ins/pages/dashboard/school/admin/users.dart'; import './base.dart'; -class AdminSchoolDashboardPage extends StudentSchoolViewBase { +class AdminSchoolDashboardPage extends AdminSchoolViewBase { const AdminSchoolDashboardPage({ super.key, super.index = 0, @@ -13,7 +13,7 @@ class AdminSchoolDashboardPage extends StudentSchoolViewBase { }); @override String getTitle(BuildContext context) { - return AppLocalizations.of(context)!.dashboard; + return "Dashboard"; } @override @@ -38,6 +38,18 @@ class AdminSchoolDashboardPage extends StudentSchoolViewBase { width: double.infinity, child: ElevatedButton( onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: + (context) => AdminSchoolUsersPage( + school: school, + member: member, + session: session, + user: user, + ), + ), + ); // Handle button press }, child: Text("Manage Users"), diff --git a/lib/pages/dashboard/school/admin/users.dart b/lib/pages/dashboard/school/admin/users.dart index 2ba59c0..5b106b9 100644 --- a/lib/pages/dashboard/school/admin/users.dart +++ b/lib/pages/dashboard/school/admin/users.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:ins/profile.dart'; import './base.dart'; @@ -7,7 +6,7 @@ import 'package:ins/errorpage.dart'; import 'package:ins/backend/models.dart' as models; import './application_form_review.dart'; -class AdminSchoolUsersPage extends StudentSchoolViewBase { +class AdminSchoolUsersPage extends AdminSchoolViewBase { const AdminSchoolUsersPage({ super.key, super.index = 1, @@ -19,7 +18,7 @@ class AdminSchoolUsersPage extends StudentSchoolViewBase { @override String getTitle(BuildContext context) { - return AppLocalizations.of(context)!.schoolMembers; + return "School Members"; } @override @@ -49,13 +48,9 @@ class AdminSchoolUsersPage extends StudentSchoolViewBase { ConnectionState.waiting) { return LoadingPage( messages: [ - AppLocalizations.of( - context, - )!.gettingAllSchoolMembers, - AppLocalizations.of( - context, - )!.crunchingDatabaseRecords, - AppLocalizations.of(context)!.pleaseWait, + "Getting all school members...", + "Crunching database records...", + "Please wait...", ], ); } else if (snapshot.hasError) { @@ -128,18 +123,13 @@ class AdminSchoolUsersPage extends StudentSchoolViewBase { ConnectionState.waiting) { return LoadingPage( messages: [ - AppLocalizations.of( - context, - )!.gettingAllSchoolApplications, - AppLocalizations.of(context)!.pleaseWait, + "Getting all school applications...", + "Please wait...", ], ); } else if (snapshot.hasError) { return ErrorPage( - title: - AppLocalizations.of( - context, - )!.errorGettingApplicationsAttempts, + title: "Error getting applications attempts", description: snapshot.error.toString(), ); } else if (snapshot.hasData) { @@ -201,6 +191,7 @@ class AdminSchoolUsersPage extends StudentSchoolViewBase { session: session, member: member, user: user, + school: school, ), ), ); diff --git a/lib/pages/dashboard/school/student/base.dart b/lib/pages/dashboard/school/student/base.dart index 4d8c36c..1fb41bb 100644 --- a/lib/pages/dashboard/school/student/base.dart +++ b/lib/pages/dashboard/school/student/base.dart @@ -1,30 +1,182 @@ import 'package:flutter/material.dart'; -import '../../../../backend/models.dart' as models; -import '../../../../analytics.dart' as analytics; +import 'package:ins/offline.dart'; +import 'package:ins/backend/models.dart' as models; +import 'package:ins/pages/dashboard/dashboard.dart' as dashboard; +import 'package:ins/analytics.dart' as analytics; +import 'package:ins/profile.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:ins/theme.dart'; +import './dashboard.dart'; +import './chatrooms.dart'; class StudentSchoolViewBase extends StatelessWidget { final models.Session session; final models.User user; final models.School school; final models.SchoolMember member; + final int index; const StudentSchoolViewBase({ super.key, required this.session, required this.user, required this.member, required this.school, + required this.index, }); Widget buildContent(BuildContext context) { return Text("Content"); } + String getTitle(BuildContext context) { + return "Dashboard"; + } + @override Widget build(BuildContext context) { - analytics.screen("student_school_view"); + analytics.screen("admin_school_view"); return Scaffold( - appBar: AppBar(leading: BackButton()), + appBar: AppBar( + leading: null, + title: appBarTitle(getTitle(context)), + actions: [ + Builder( + builder: + (context) => GestureDetector( + onTap: () => Scaffold.of(context).openEndDrawer(), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: profileAvatar( + profile: user.profile, + radius: 20, + name: user.info.name, + ), + ), + ), + ), + ], + ), + + endDrawer: Drawer( + child: ListView( + padding: EdgeInsets.zero, + children: [ + DrawerHeader( + decoration: BoxDecoration(color: Theme.of(context).primaryColor), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + profileAvatar( + profile: user.profile, + radius: 50, + name: user.info.name, + ), + SizedBox(width: 10), + Column( + children: [ + SizedBox(height: 30), + Text( + user.username, + style: GoogleFonts.lato( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 30), + ThemeSwitcherWidget(), + ], + ), + ], + ), + ), + ListTile( + leading: Icon(Icons.person), + title: Text("Profile"), + onTap: () => Navigator.pop(context), + ), + ListTile( + leading: Icon(Icons.settings), + title: Text("Settings"), + onTap: () { + Navigator.pop(context); + }, + ), + ListTile( + leading: Icon(Icons.logout), + title: Text("Exit"), + onTap: () { + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute( + builder: + (context) => dashboard.DashboardPage( + title: "Welcome back", + session: session, + user: user, + ), + ), + (route) => false, + ); + }, + ), + ], + ), + ), body: buildContent(context), + bottomNavigationBar: BottomNavigationBar( + selectedItemColor: Theme.of(context).colorScheme.primary, + unselectedItemColor: Colors.grey.shade600, + items: [ + BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"), + BottomNavigationBarItem( + icon: Icon(Icons.message), + label: "Chatrooms", + ), + BottomNavigationBarItem( + icon: Icon(Icons.notifications), + label: "Notifications", + ), + BottomNavigationBarItem( + icon: Icon(Icons.account_circle), + label: "Profile", + ), + ], + currentIndex: index, + type: BottomNavigationBarType.fixed, + onTap: (index) { + switch (index) { + case 0: + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: + (context) => StudentSchoolDashboardPage( + session: session, + user: user, + school: school, + member: member, + ), + ), + ); + break; + case 1: + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: + (context) => StudentChatroomsPage( + session: session, + user: user, + school: school, + member: member, + ), + ), + ); + break; + } + }, + ), ); } } diff --git a/lib/pages/dashboard/school/student/chatrooms.dart b/lib/pages/dashboard/school/student/chatrooms.dart new file mode 100644 index 0000000..563b98a --- /dev/null +++ b/lib/pages/dashboard/school/student/chatrooms.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import './base.dart'; + +class StudentChatroomsPage extends StudentSchoolViewBase { + const StudentChatroomsPage({ + super.key, + required super.school, + required super.member, + required super.session, + required super.user, + super.index = 1, + }); + + @override + Widget buildContent(BuildContext context) { + return Center( + child: Column( + children: [ + Padding( + padding: EdgeInsets.all(20), + child: Column( + children: [ + Hero( + tag: school.profile.getPath(), + child: Image.network( + school.profile.getPath(), + width: 200, + height: 200, + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/dashboard/school/student/dashboard.dart b/lib/pages/dashboard/school/student/dashboard.dart index c1bced5..85490a9 100644 --- a/lib/pages/dashboard/school/student/dashboard.dart +++ b/lib/pages/dashboard/school/student/dashboard.dart @@ -8,9 +8,70 @@ class StudentSchoolDashboardPage extends StudentSchoolViewBase { required super.member, required super.session, required super.user, + super.index = 0, }); @override Widget buildContent(BuildContext context) { - return Text("Student school dashboard"); + return Center( + child: Column( + children: [ + Padding( + padding: EdgeInsets.all(20), + child: Column( + children: [ + Card( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Hero( + tag: school.profile.getPath(), + child: Image.network( + school.profile.getPath(), + width: 200, + height: 200, + ), + ), + SizedBox(width: 20), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + school.info.name, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 10), + Text( + "@${school.school_name}", + style: TextStyle( + fontSize: 16, + color: Colors.grey, + backgroundColor: Theme.of( + context, + ).primaryColor.withOpacity(0.3), + ), + ), + ], + ), + ], + ), + ), + ), + SizedBox(height: 20), + Text( + "Hy ${user.info.name}, what would you like to do?", + style: Theme.of(context).textTheme.displayLarge, + ), + ], + ), + ), + ], + ), + ); } } diff --git a/lib/pages/dashboard/school/student/home.dart b/lib/pages/dashboard/school/student/home.dart index f40437f..ab69cd9 100644 --- a/lib/pages/dashboard/school/student/home.dart +++ b/lib/pages/dashboard/school/student/home.dart @@ -9,15 +9,33 @@ Future launchStudentSchoolView({ required models.SchoolMember member, required models.Session session, }) async { - Navigator.of(context).push( - MaterialPageRoute( - builder: - (context) => StudentSchoolDashboardPage( - school: school, - member: member, - session: session, - user: user, + Navigator.push( + context, + PageRouteBuilder( + pageBuilder: + (context, animation, secondaryAnimation) => + StudentSchoolDashboardPage( + school: school, + member: member, + session: session, + user: user, + ), + transitionsBuilder: (context, animation, secondaryAnimation, child) { + return SlideTransition( + position: Tween( + begin: const Offset(1.0, 0.0), + end: Offset.zero, + ).animate( + CurvedAnimation( + parent: animation, + curve: Curves.easeInOut, + reverseCurve: Curves.easeInOut.flipped, + ), ), + child: child, + ); + }, + transitionDuration: const Duration(milliseconds: 400), ), ); } diff --git a/lib/pages/dashboard/school_apply/home.dart b/lib/pages/dashboard/school_apply/home.dart index 542448c..8ae20af 100644 --- a/lib/pages/dashboard/school_apply/home.dart +++ b/lib/pages/dashboard/school_apply/home.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:ins/pages/dashboard/school_apply/manager.dart'; import '../../../backend/models.dart' as models; @@ -20,11 +19,7 @@ void launchApplicationForm( builder: (context) => Scaffold( body: LoadingPage( - messages: [ - AppLocalizations.of(context)!.loading, - AppLocalizations.of(context)!.gettingForm, - AppLocalizations.of(context)!.pleaseWait, - ], + messages: ["Loading...", "Getting form...", "Please wait..."], ), ), ), diff --git a/lib/pages/dashboard/school_apply/instructions.dart b/lib/pages/dashboard/school_apply/instructions.dart index 348059d..4dce78f 100644 --- a/lib/pages/dashboard/school_apply/instructions.dart +++ b/lib/pages/dashboard/school_apply/instructions.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -24,7 +23,7 @@ class ApplicationFormInstructionsPage extends AssistantBasePage { children: [ SizedBox(height: 10), Text( - AppLocalizations.of(context)!.instructions, + "Instructions", style: Theme.of(context).textTheme.headlineLarge, ), Padding( @@ -52,7 +51,7 @@ class ApplicationFormInstructionsPage extends AssistantBasePage { ), ); }, - child: Text(AppLocalizations.of(context)!.next), + child: Text("Next"), ), ), ], diff --git a/lib/pages/dashboard/school_apply/questions.dart b/lib/pages/dashboard/school_apply/questions.dart index 5fe36d5..d85265c 100644 --- a/lib/pages/dashboard/school_apply/questions.dart +++ b/lib/pages/dashboard/school_apply/questions.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:intl/intl.dart'; @@ -91,11 +90,7 @@ class _QuestionsViewState extends State<_QuestionsView> final answer = widget.assistantState.answers[question.number]; if (question.required && (answer == null || answer.isEmpty)) { - setState( - () => - _currentError = - AppLocalizations.of(context)!.thisQuestionIsRequired, - ); + setState(() => _currentError = "This question is required"); return false; } return true; @@ -189,10 +184,10 @@ class _QuestionsViewState extends State<_QuestionsView> Row( children: [ Text( - AppLocalizations.of(context)!.questionXofX( - _currentQuestionIndex + 1, - widget.form.questions.length, - ), + "question " + + (_currentQuestionIndex + 1).toString() + + " of " + + widget.form.questions.length.toString(), style: Theme.of( context, ).textTheme.bodySmall?.copyWith(color: Colors.grey.shade600), @@ -243,7 +238,7 @@ class _QuestionsViewState extends State<_QuestionsView> text: currentValue?.toString() ?? '', ), decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.enterYourAnswer, + labelText: "Enter your answer", border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), filled: true, floatingLabelBehavior: FloatingLabelBehavior.auto, @@ -251,7 +246,7 @@ class _QuestionsViewState extends State<_QuestionsView> validator: (value) => question.required && (value == null || value.isEmpty) - ? AppLocalizations.of(context)!.thisFieldIsRequired + ? "This field is required" : null, ); case 'date': @@ -270,7 +265,7 @@ class _QuestionsViewState extends State<_QuestionsView> }, child: InputDecorator( decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.selectDate, + labelText: "Select date", border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), @@ -280,7 +275,7 @@ class _QuestionsViewState extends State<_QuestionsView> child: Text( date != null ? DateFormat('MMM dd, yyyy').format(date) - : AppLocalizations.of(context)!.tapToSelectDate, + : "Tap to select date", style: Theme.of(context).textTheme.bodyLarge, ), ), @@ -291,7 +286,7 @@ class _QuestionsViewState extends State<_QuestionsView> onChanged: (value) => _onAnswerChanged(question, value), controller: TextEditingController(text: currentValue ?? ''), decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.enterYourAnswer, + labelText: "Enter your answer", border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), filled: true, floatingLabelBehavior: FloatingLabelBehavior.auto, @@ -299,7 +294,7 @@ class _QuestionsViewState extends State<_QuestionsView> validator: (value) => question.required && (value == null || value.isEmpty) - ? AppLocalizations.of(context)!.thisFieldIsRequired + ? "This field is required" : null, ); } @@ -353,8 +348,8 @@ class _QuestionsViewState extends State<_QuestionsView> children: [ Text( _currentQuestionIndex < widget.form.questions.length - 1 - ? AppLocalizations.of(context)!.continuer - : AppLocalizations.of(context)!.submitApplication, + ? "Continue" + : "Submit application", ), if (_currentQuestionIndex < widget.form.questions.length - 1) diff --git a/lib/pages/dashboard/school_apply/submiting.dart b/lib/pages/dashboard/school_apply/submiting.dart index 7a6bd12..e6bbfaa 100644 --- a/lib/pages/dashboard/school_apply/submiting.dart +++ b/lib/pages/dashboard/school_apply/submiting.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:ins/analytics.dart' as analytics; import '../../../backend/models.dart' as models; @@ -69,16 +68,12 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { String _parseErrorMessage(String error, BuildContext context) { // Custom error message parsing can be added here if (error.contains('timeout')) { - return AppLocalizations.of( - context, - )!.requestTimedOutPleaseCheckYourConnection; + return "Request timed out. Please check your connection."; } if (error.contains('network')) { - return AppLocalizations.of( - context, - )!.networkErrorPleaseCheckYourInternetConnection; + return "Network error. Please check your internet connection."; } - return AppLocalizations.of(context)!.submissionFailedPleaseTryAgain; + return "Submission failed. Please try again."; } @override @@ -105,9 +100,9 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { Widget _buildLoadingState(BuildContext context) { return LoadingPage( messages: [ - AppLocalizations.of(context)!.submittingForm, - AppLocalizations.of(context)!.almostThereProcessingYourInformation, - AppLocalizations.of(context)!.finalizingYourSubmission, + "Submitting form...", + "Almost there! Processing your information...", + "Finalizing your submission...", ], ); } @@ -126,7 +121,7 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { ), const SizedBox(height: 24), Text( - AppLocalizations.of(context)!.submissionSuccessful, + "Submission Successful!", style: Theme.of(context).textTheme.headlineSmall?.copyWith( fontWeight: FontWeight.bold, color: colorScheme.onSurface, @@ -134,17 +129,13 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { ), const SizedBox(height: 16), Text( - AppLocalizations.of( - context, - )!.yourFormHasBeenSubmittedSuccessfully, + "Your form has been submitted successfully.", textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyLarge, ), const SizedBox(height: 8), Text( - AppLocalizations.of( - context, - )!.youWillReceiveAConfirmationEmailShortly, + "You will receive a confirmation email shortly.", textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: colorScheme.onSurface.withOpacity(0.6), @@ -155,7 +146,7 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { onPressed: () { Navigator.of(context).popUntil((route) => route.isFirst); }, - child: Text(AppLocalizations.of(context)!.returnToDashboard), + child: Text("Return to Dashboard"), ), ], ), @@ -173,7 +164,7 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { Icon(Icons.error_outline, color: colorScheme.error, size: 80), const SizedBox(height: 24), Text( - AppLocalizations.of(context)!.submissionFailed, + "Submission Failed", style: Theme.of(context).textTheme.headlineSmall?.copyWith( fontWeight: FontWeight.bold, color: colorScheme.onSurface, @@ -189,9 +180,7 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { ), const SizedBox(height: 8), Text( - AppLocalizations.of( - context, - )!.pleaseCheckYourInformationAndTryAgain, + "Please check your information and try again.", textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium, ), @@ -206,14 +195,14 @@ class _SubmitingFormViewState extends State<_SubmitingFormView> { _submitFuture = _submit(); }); }, - child: Text(AppLocalizations.of(context)!.tryAgain), + child: Text("Try Again"), ), const SizedBox(width: 16), TextButton( onPressed: () { Navigator.of(context).pop(); }, - child: Text(AppLocalizations.of(context)!.goBack), + child: Text("Go Back"), ), ], ), diff --git a/lib/pages/dashboard/school_explore.dart b/lib/pages/dashboard/school_explore.dart index 8c63ff8..82580af 100644 --- a/lib/pages/dashboard/school_explore.dart +++ b/lib/pages/dashboard/school_explore.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:ins/offline.dart'; import '../../backend/models.dart' as models; @@ -20,7 +19,7 @@ class SchoolExplorePage extends StatelessWidget { Widget build(BuildContext context) { analytics.screen("Explore Schools"); return Scaffold( - appBar: AppBar(title: appBarTitle(AppLocalizations.of(context)!.exploreSchools), elevation: 0), + appBar: AppBar(title: appBarTitle("Explore Schools"), elevation: 0), body: FutureBuilder>( future: models.School.getSchools(), builder: (context, snapshot) { diff --git a/lib/pages/dashboard/school_profile.dart b/lib/pages/dashboard/school_profile.dart index 5c7c87a..f86f1f3 100644 --- a/lib/pages/dashboard/school_profile.dart +++ b/lib/pages/dashboard/school_profile.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'dart:ui'; import 'package:flutter/material.dart'; @@ -151,10 +150,7 @@ class SchoolProfilePage extends StatelessWidget { children: [ _buildStatItem(Icons.star, "4.4"), _buildStatItem(Icons.people, "0"), - _buildStatItem( - Icons.location_city, - AppLocalizations.of(context)!.somewhere, - ), + _buildStatItem(Icons.location_city, "Somewhere"), ], ), ); @@ -210,9 +206,7 @@ class SchoolProfilePage extends StatelessWidget { ? Center( child: ElevatedButton.icon( icon: const Icon(Icons.edit_document), - label: Text( - AppLocalizations.of(context)!.startApplication, - ), + label: Text("Start Application"), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric( horizontal: 32, @@ -314,7 +308,7 @@ Future _selectApplicationForm( ), const SizedBox(height: 16), Text( - AppLocalizations.of(context)!.selectApplicationForm, + "Select application form", style: GoogleFonts.poppins( fontSize: 22, fontWeight: FontWeight.w600, diff --git a/lib/pages/dashboard/schools.dart b/lib/pages/dashboard/schools.dart index e98dc05..751adbb 100644 --- a/lib/pages/dashboard/schools.dart +++ b/lib/pages/dashboard/schools.dart @@ -2,7 +2,6 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:transparent_image/transparent_image.dart'; // For fade-in -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:ins/backend/models.dart' as models; import './school_explore.dart'; @@ -33,8 +32,9 @@ class DashboardSchoolsPage extends DashboardBase { builder: (context, snapshot) { if (snapshot.hasError) { return ErrorPage( - title: AppLocalizations.of(context)!.error, - description: "Unable to load schools ${snapshot.error}", + title: "Error", + description: + "Unable to load schools " + snapshot.error.toString(), ); } else if (!snapshot.hasData) { return CircularProgressIndicator( @@ -50,12 +50,12 @@ class DashboardSchoolsPage extends DashboardBase { child: Column( children: [ Text( - AppLocalizations.of(context)!.noSchools, + "No schools", style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 10), Text( - AppLocalizations.of(context)!.youAreAMemberOfNoSchoolYet, + "You are a member of no school yet", style: Theme.of(context).textTheme.bodyMedium, ), ], @@ -68,7 +68,6 @@ class DashboardSchoolsPage extends DashboardBase { child: Padding( padding: const EdgeInsets.all(10), child: Column( - // Changed to Column for list layout children: schools.map((school) { return SchoolListCard( @@ -81,7 +80,7 @@ class DashboardSchoolsPage extends DashboardBase { session, ); }, - ); // Using the new SchoolListCard + ); }).toList(), ), ), @@ -159,44 +158,48 @@ class SchoolListCard extends StatelessWidget { padding: const EdgeInsets.all(12.0), child: Row( children: [ - Container( - width: 120, // Increased width - height: 120, // Increased height - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - image: DecorationImage( - image: NetworkImage(school.profile.getPath()), - fit: - BoxFit - .cover, // Ensure image covers the entire container + Hero( + tag: school.profile.getPath(), + transitionOnUserGestures: true, + child: Container( + width: 150, // Increased width + height: 150, // Increased height + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + image: DecorationImage( + image: NetworkImage(school.profile.getPath()), + fit: + BoxFit + .cover, // Ensure image covers the entire container + ), + color: Colors.transparent, + backgroundBlendMode: BlendMode.srcOver, ), - color: Colors.transparent, - backgroundBlendMode: BlendMode.srcOver, - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: Container( - color: Colors.transparent, - child: Center( - child: FadeInImage.memoryNetwork( - placeholder: kTransparentImage, - image: school.profile.getPath(), - width: 70, // Increased width - height: 70, // increased height - fit: BoxFit.cover, - imageErrorBuilder: (context, error, stackTrace) { - return Container( - color: Colors.grey.shade300, - child: const Center( - child: Icon( - Icons.image_not_supported_outlined, - color: Colors.grey, + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: Container( + color: Colors.transparent, + child: Center( + child: FadeInImage.memoryNetwork( + placeholder: kTransparentImage, + image: school.profile.getPath(), + width: 70, // Increased width + height: 70, // increased height + fit: BoxFit.cover, + imageErrorBuilder: (context, error, stackTrace) { + return Container( + color: Colors.grey.shade300, + child: const Center( + child: Icon( + Icons.image_not_supported_outlined, + color: Colors.grey, + ), ), - ), - ); - }, + ); + }, + ), ), ), ), diff --git a/lib/pages/sign/assistant/creatingaccount.dart b/lib/pages/sign/assistant/creatingaccount.dart index 8a7be4a..4032917 100644 --- a/lib/pages/sign/assistant/creatingaccount.dart +++ b/lib/pages/sign/assistant/creatingaccount.dart @@ -1,4 +1,3 @@ -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'dart:async'; import 'package:flutter/material.dart'; import './base.dart'; @@ -53,17 +52,17 @@ class _CreatingAccountPageState extends State { @override Widget build(BuildContext context) { _messages.addAll([ - AppLocalizations.of(context)!.preparingYourWorkspace, - AppLocalizations.of(context)!.configuringSettings, - AppLocalizations.of(context)!.almostThere, - AppLocalizations.of(context)!.justAFewMoreMoments, - AppLocalizations.of(context)!.creatingYourProfile, - AppLocalizations.of(context)!.finalizingYourAccount, - AppLocalizations.of(context)!.settingUpYourPreferences, - AppLocalizations.of(context)!.loadingYourDashboard, + "Preparing your workspace...", + "Configuring settings...", + "Almost there...", + "Just a few more moments...", + "Creating your profile...", + "Finalizing your account...", + "Setting up your preferences...", + "Loading your dashboard...", ]); return AssistantBasePage( - title: Text(AppLocalizations.of(context)!.creatingYourAccount), + title: Text("Creating your account"), body: FutureBuilder( future: _createAccountFuture, builder: (context, snapshot) { @@ -103,7 +102,7 @@ class _CreatingAccountPageState extends State { const CircularProgressIndicator(), const SizedBox(height: 24), Text( - AppLocalizations.of(context)!.creatingYourAccount, + "Creating your account", style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center, ), @@ -129,7 +128,7 @@ class _CreatingAccountPageState extends State { const Icon(Icons.error_outline, size: 200, color: Colors.red), const SizedBox(height: 24), Text( - AppLocalizations.of(context)!.accountCreationFailed, + "Account creation failed", style: Theme.of( context, ).textTheme.headlineLarge?.copyWith(color: Colors.red), @@ -156,13 +155,13 @@ class _CreatingAccountPageState extends State { const Icon(Icons.check_circle, size: 200, color: Colors.green), const SizedBox(height: 24), Text( - AppLocalizations.of(context)!.accountCreatedSuccessfully, + "Account created successfully!", style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center, ), const SizedBox(height: 16), Text( - AppLocalizations.of(context)!.welcomeToYourNewAccount, + "Welcome to your new account!", style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.center, ), diff --git a/lib/pages/sign/assistant/dobchooser.dart b/lib/pages/sign/assistant/dobchooser.dart index 2372d47..3d70021 100644 --- a/lib/pages/sign/assistant/dobchooser.dart +++ b/lib/pages/sign/assistant/dobchooser.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import './creatingaccount.dart'; import './base.dart'; import './manager.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class DobChooser extends StatelessWidget { final SignupAssistantState assistantState; @@ -11,11 +10,9 @@ class DobChooser extends StatelessWidget { void _next(BuildContext context) { if (assistantState.dob == null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(AppLocalizations.of(context)!.pleaseSelectADateOfBirth), - ), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text("Please select a date of birth."))); return; } Navigator.push( @@ -45,7 +42,7 @@ class DobChooser extends StatelessWidget { @override Widget build(BuildContext context) { return AssistantBasePage( - title: Text(AppLocalizations.of(context)!.dateOfBirth), + title: Text("Date of Birth"), body: Padding( padding: EdgeInsets.symmetric(horizontal: 20, vertical: 50), child: Center( @@ -53,7 +50,7 @@ class DobChooser extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Text( - AppLocalizations.of(context)!.chooseYourDateOfBirth, + "Choose your date of birth", style: Theme.of(context).textTheme.headlineSmall, ), const SizedBox(height: 20), @@ -62,13 +59,13 @@ class DobChooser extends StatelessWidget { child: Text( assistantState.dob != null ? assistantState.dob!.toString().split(' ')[0] - : AppLocalizations.of(context)!.selectDate, + : "Select date", ), ), Spacer(), FilledButton( onPressed: () => _next(context), - child: Text(AppLocalizations.of(context)!.continuer), + child: Text("Continue"), ), ], ), diff --git a/lib/pages/sign/assistant/namechooser.dart b/lib/pages/sign/assistant/namechooser.dart index 8d4c7d1..df65bea 100644 --- a/lib/pages/sign/assistant/namechooser.dart +++ b/lib/pages/sign/assistant/namechooser.dart @@ -4,7 +4,6 @@ import 'dart:async'; import 'package:ins/pages/sign/assistant/base.dart'; import './manager.dart'; import './passwordchooser.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../../backend/models.dart'; class LowerCaseTextFormatter extends TextInputFormatter { @@ -168,14 +167,14 @@ class _NameChooserPageState extends State { children: [ const SizedBox(height: 20), Text( - AppLocalizations.of(context)!.createYourProfile, + "Create Your Profile", style: Theme.of(context).textTheme.headlineLarge, ), const SizedBox(height: 30), TextField( controller: _nameController, - decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.fullName, + decoration: const InputDecoration( + labelText: "Full Name", hintText: 'John Doe', border: OutlineInputBorder(), ), @@ -188,7 +187,7 @@ class _NameChooserPageState extends State { TextField( controller: _usernameController, decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.username, + labelText: "Username", hintText: 'john_doe123', border: const OutlineInputBorder(), suffixIcon: @@ -229,20 +228,20 @@ class _NameChooserPageState extends State { _usernameController.text.trim(), ) : null, - child: Text(AppLocalizations.of(context)!.continuer), + child: const Text("Continue"), ), ), ], ), ), - title: Text(AppLocalizations.of(context)!.profileSetup), + title: const Text("Profile Setup"), ); } Widget _buildUsernameStatus() { if (_isCheckingUsername) { return Text( - AppLocalizations.of(context)!.checkingUsernameAvailability, + "Checking username availability...", style: Theme.of( context, ).textTheme.bodySmall?.copyWith(color: Colors.blue), @@ -251,9 +250,7 @@ class _NameChooserPageState extends State { if (!_isUsernameValid) { return Text( - AppLocalizations.of( - context, - )!.usernameMustBeAtLeast3CharactersAndCanOnlyContainNlowercaseLettersNumbersUnderscoresAndPeriods, + "Username must be at least 3 characters and can only contain lowercase letters, numbers, underscores, and periods.", style: Theme.of( context, ).textTheme.bodySmall?.copyWith(color: Colors.red), @@ -262,7 +259,7 @@ class _NameChooserPageState extends State { if (!_isUsernameAvailable) { return Text( - AppLocalizations.of(context)!.thisUsernameIsAlreadyTaken, + "This username is already taken", style: Theme.of( context, ).textTheme.bodySmall?.copyWith(color: Colors.red), diff --git a/lib/pages/sign/assistant/passwordchooser.dart b/lib/pages/sign/assistant/passwordchooser.dart index 0ac1190..5f868be 100644 --- a/lib/pages/sign/assistant/passwordchooser.dart +++ b/lib/pages/sign/assistant/passwordchooser.dart @@ -5,7 +5,6 @@ import 'package:flutter/services.dart'; import './manager.dart'; import './base.dart'; import './dobchooser.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class PasswordChooserPage extends StatefulWidget { final SignupAssistantState assistantState; @@ -90,13 +89,13 @@ class _PasswordChooserPageState extends State { // Determine strength label and color if (_passwordStrength < 0.4) { - _strengthLabel = AppLocalizations.of(context)!.weak; + _strengthLabel = "Weak"; _strengthColor = Colors.red; } else if (_passwordStrength < 0.75) { - _strengthLabel = AppLocalizations.of(context)!.moderate; + _strengthLabel = "Moderate"; _strengthColor = Colors.orange; } else { - _strengthLabel = AppLocalizations.of(context)!.strong; + _strengthLabel = "Strong"; _strengthColor = Colors.green; } @@ -152,26 +151,26 @@ class _PasswordChooserPageState extends State { context: context, builder: (context) => AlertDialog( - title: Text(AppLocalizations.of(context)!.suggestedPassword), + title: Text("Suggested Password"), content: SelectableText(generatedPassword), actions: [ TextButton( onPressed: () => Navigator.pop(context), - child: Text(AppLocalizations.of(context)!.cancel), + child: Text("Cancel"), ), TextButton( onPressed: () { Clipboard.setData(ClipboardData(text: generatedPassword)); Navigator.pop(context); }, - child: Text(AppLocalizations.of(context)!.copy), + child: Text("Copy"), ), FilledButton( onPressed: () { _passwordController.text = generatedPassword; Navigator.pop(context); }, - child: Text(AppLocalizations.of(context)!.useThis), + child: Text("Use This"), ), ], ), @@ -182,7 +181,7 @@ class _PasswordChooserPageState extends State { Widget build(BuildContext context) { _validatePassword(); return AssistantBasePage( - title: Text(AppLocalizations.of(context)!.password), + title: Text("Password"), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( @@ -191,7 +190,7 @@ class _PasswordChooserPageState extends State { TextField( controller: _passwordController, decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.password, + labelText: "Password", border: const OutlineInputBorder(), suffixIcon: Row( mainAxisSize: MainAxisSize.min, @@ -199,7 +198,7 @@ class _PasswordChooserPageState extends State { IconButton( icon: const Icon(Icons.autorenew), onPressed: () => _showPasswordSuggestions(context), - tooltip: AppLocalizations.of(context)!.generatePassword, + tooltip: "Generate password", ), IconButton( icon: Icon( @@ -222,31 +221,12 @@ class _PasswordChooserPageState extends State { const SizedBox(height: 20), _buildStrengthIndicator(), const SizedBox(height: 15), - _buildValidationItem( - AppLocalizations.of(context)!.minimum8Characters, - _hasMinLength, - ), - _buildValidationItem( - AppLocalizations.of(context)!.uppercaseLetterAZ, - _hasUpper, - ), - _buildValidationItem( - AppLocalizations.of(context)!.lowercaseLetterAZ, - _hasLower, - ), - _buildValidationItem( - AppLocalizations.of(context)!.number09, - _hasNumber, - ), - _buildValidationItem( - AppLocalizations.of(context)!.specialCharacter, - _hasSpecial, - ), + _buildValidationItem("Minimum 8 characters", _hasMinLength), + _buildValidationItem("Uppercase letter (A-Z)", _hasUpper), + _buildValidationItem("Lowercase letter (a-z)", _hasLower), + _buildValidationItem("Number (0-9)", _hasNumber), + _buildValidationItem("Special character", _hasSpecial), const SizedBox(height: 10), - //TextButton( - // onPressed: _showPasswordSuggestions, - // child: const Text('Suggest a secure password'), - //), const Spacer(), SizedBox( width: double.infinity, @@ -258,7 +238,7 @@ class _PasswordChooserPageState extends State { _passwordController.text, ) : null, - child: Text(AppLocalizations.of(context)!.continuer), + child: Text("Continue"), ), ), ], @@ -272,7 +252,7 @@ class _PasswordChooserPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "$_strengthLabel${AppLocalizations.of(context)!.password}", + "$_strengthLabel Password", style: TextStyle(color: _strengthColor, fontWeight: FontWeight.bold), ), const SizedBox(height: 5), diff --git a/lib/pages/sign/assistant/roleshooser.dart b/lib/pages/sign/assistant/roleshooser.dart index e938d38..6b05cca 100644 --- a/lib/pages/sign/assistant/roleshooser.dart +++ b/lib/pages/sign/assistant/roleshooser.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:ins/pages/sign/assistant/base.dart'; import 'package:ins/pages/sign/assistant/manager.dart'; import './namechooser.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class RoleChooser extends StatelessWidget { final SignupAssistantState assistantState; @@ -28,7 +27,7 @@ class RoleChooser extends StatelessWidget { child: Column( children: [ Text( - AppLocalizations.of(context)!.whatRoleBestFitsYou, + "What role best fits you?", style: Theme.of(context).textTheme.titleLarge, ), Spacer(), @@ -39,10 +38,7 @@ class RoleChooser extends StatelessWidget { child: FloatingActionButton.extended( onPressed: () => _next(context, 'student'), icon: Icon(Icons.school, size: 32), - label: Text( - AppLocalizations.of(context)!.student, - style: TextStyle(fontSize: 18), - ), + label: Text("Student", style: TextStyle(fontSize: 18)), extendedPadding: EdgeInsets.symmetric( horizontal: 42, vertical: 16, @@ -55,10 +51,7 @@ class RoleChooser extends StatelessWidget { child: FloatingActionButton.extended( onPressed: () => _next(context, 'instructor'), icon: Icon(Icons.person, size: 32), - label: Text( - AppLocalizations.of(context)!.instructor, - style: TextStyle(fontSize: 18), - ), + label: Text("Instructor", style: TextStyle(fontSize: 18)), extendedPadding: EdgeInsets.symmetric( horizontal: 32, vertical: 16, @@ -72,7 +65,7 @@ class RoleChooser extends StatelessWidget { onPressed: () => _next(context, 'administrator'), icon: Icon(Icons.admin_panel_settings, size: 32), label: Text( - AppLocalizations.of(context)!.administrator, + "Administrator", style: TextStyle(fontSize: 18), ), extendedPadding: EdgeInsets.symmetric( @@ -87,10 +80,7 @@ class RoleChooser extends StatelessWidget { child: FloatingActionButton.extended( onPressed: () => _next(context, 'parent'), icon: Icon(Icons.family_restroom, size: 32), - label: Text( - AppLocalizations.of(context)!.parent, - style: TextStyle(fontSize: 18), - ), + label: Text("Parent", style: TextStyle(fontSize: 18)), extendedPadding: EdgeInsets.symmetric( horizontal: 32, vertical: 16, @@ -103,7 +93,7 @@ class RoleChooser extends StatelessWidget { ), ), ), - title: Text(AppLocalizations.of(context)!.role), + title: Text("Role"), ); } } diff --git a/lib/pages/sign/in.dart b/lib/pages/sign/in.dart index 51f67dd..b2854d2 100644 --- a/lib/pages/sign/in.dart +++ b/lib/pages/sign/in.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import '../../backend/sessions.dart'; import '../dashboard/dashboard.dart'; import '../../analytics.dart' as analytics; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class SigninPage extends StatefulWidget { const SigninPage({super.key}); @@ -46,7 +45,7 @@ class _SigninPageState extends State { TextField( controller: _nameController, decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.yourName, + labelText: "Your Name", prefixIcon: Icon(Icons.person), fillColor: Theme.of(context).colorScheme.inversePrimary, ), @@ -55,7 +54,7 @@ class _SigninPageState extends State { TextField( controller: _codeController, decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.yourPassword, + labelText: "Your password", prefixIcon: Icon(Icons.lock), fillColor: Theme.of(context).colorScheme.inversePrimary, ), @@ -71,13 +70,7 @@ class _SigninPageState extends State { ); if (session != null) { ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of( - context, - )!.successfullySignedUp, - ), - ), + SnackBar(content: Text("Successfully signed up")), ); final user = await session.getUser(); @@ -99,7 +92,7 @@ class _SigninPageState extends State { ).showSnackBar(SnackBar(content: Text(e.toString()))); } }, - child: Text(AppLocalizations.of(context)!.signin), + child: Text("Signin >"), ), ], ), diff --git a/lib/pages/sign/up.dart b/lib/pages/sign/up.dart index 40ecdbe..321f5cf 100644 --- a/lib/pages/sign/up.dart +++ b/lib/pages/sign/up.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import './assistant/home.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class SignupPage extends StatelessWidget { const SignupPage({super.key}); @@ -28,7 +27,7 @@ class SignupPage extends StatelessWidget { onPressed: () { launchAssistant(context); }, - child: Text(AppLocalizations.of(context)!.manualSignup), + child: Text("Manual Signup >"), ), ], ), diff --git a/lib/pages/welcome.dart b/lib/pages/welcome.dart index 863c3cf..e52520e 100644 --- a/lib/pages/welcome.dart +++ b/lib/pages/welcome.dart @@ -3,7 +3,6 @@ import './sign/in.dart'; import './sign/up.dart'; import 'package:google_fonts/google_fonts.dart'; import '../analytics.dart' as analytics; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class WelcomePage extends StatelessWidget { final String title; @@ -32,10 +31,7 @@ class WelcomePage extends StatelessWidget { height: 200, ), ), - Text( - AppLocalizations.of(context)!.welcome, - style: GoogleFonts.lato(fontSize: 30), - ), + Text("Welcome!", style: GoogleFonts.lato(fontSize: 30)), const SizedBox(height: 50), Row( mainAxisAlignment: MainAxisAlignment.center, @@ -47,7 +43,7 @@ class WelcomePage extends StatelessWidget { MaterialPageRoute(builder: (context) => SigninPage()), ); }, - child: Text(AppLocalizations.of(context)!.connect), + child: Text("Connect"), ), const SizedBox(width: 20), FilledButton( @@ -57,7 +53,7 @@ class WelcomePage extends StatelessWidget { MaterialPageRoute(builder: (context) => SignupPage()), ); }, - child: Text(AppLocalizations.of(context)!.register), + child: Text("Register"), ), ], ), diff --git a/lib/theme.dart b/lib/theme.dart index 6d1f9de..bcafe6d 100644 --- a/lib/theme.dart +++ b/lib/theme.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:shared_preferences/shared_preferences.dart'; -const Color primaryColor = Color(0xFFE65100); // #E65100 +const Color primaryColor = Color(0xFFF57C00); // Improved primary class ThemeManager with ChangeNotifier { static final ThemeManager _instance = ThemeManager._internal(); @@ -35,39 +35,32 @@ class ThemeManager with ChangeNotifier { notifyListeners(); } - // Light Theme Configuration + // Light Theme (Improved contrast) static final ThemeData _lightTheme = ThemeData( useMaterial3: true, brightness: Brightness.light, colorScheme: ColorScheme( brightness: Brightness.light, - // Primary colors - primary: Color(0xFFC66900), // Deep orange + primary: Color(0xFFF57C00), onPrimary: Colors.white, - primaryContainer: Color(0xFFFFD9B3), - onPrimaryContainer: Color(0xFF3A2600), - - // Secondary colors - secondary: Color(0xFF4F9A94), // Muted teal + primaryContainer: Color(0xFFFFE0B2), + onPrimaryContainer: Color(0xFF311B00), + secondary: Color(0xFF4F9A94), onSecondary: Colors.white, secondaryContainer: Color(0xFFB2DFDB), - onSecondaryContainer: Color(0xFF0A1F1D), // 90% black - surface: Color(0xFFFFF8F2), // Elevated surfaces + onSecondaryContainer: Color(0xFF0A1F1D), + surface: Color(0xFFFFF8F2), onSurface: Color(0xFF1F1B16), - - // Error colors error: Color(0xFFBA1A1A), onError: Colors.white, - - // Neutral colors - surfaceContainerHighest: Color(0xFFF3E9E1), // For cards/dialogs - outline: Color(0xFF857369), // Borders/dividers + surfaceContainerHighest: Color(0xFFF3E9E1), + outline: Color(0xFF857369), ), textTheme: TextTheme( displayLarge: GoogleFonts.robotoFlex( fontSize: 32, fontWeight: FontWeight.w800, - color: Color(0xFF7A4A00), // Warm accent + color: Color(0xFF7A4A00), ), headlineMedium: GoogleFonts.robotoFlex( fontSize: 24, @@ -83,7 +76,7 @@ class ThemeManager with ChangeNotifier { bodyMedium: GoogleFonts.merriweather( fontSize: 16, height: 1.6, - color: Color(0xFF5C4D42), // Warm gray + color: Color(0xFF5C4D42), ), labelLarge: GoogleFonts.robotoFlex( fontSize: 14, @@ -105,7 +98,7 @@ class ThemeManager with ChangeNotifier { ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFFC66900), + backgroundColor: Color(0xFFF57C00), foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), @@ -126,58 +119,55 @@ class ThemeManager with ChangeNotifier { }, ), ); - // Dark Theme Configuration + + // Dark Theme (Improved visibility) static final ThemeData _darkTheme = ThemeData( useMaterial3: true, brightness: Brightness.dark, colorScheme: ColorScheme( brightness: Brightness.dark, - // Primary colors - primary: Color(0xFFFF9E40), // Softer orange + primary: Color(0xFFFFA726), onPrimary: Colors.black, - primaryContainer: Color(0xFFB26F20), // Darker orange container - onPrimaryContainer: Color(0xFFFFD9B3), - - // Secondary colors - secondary: Color(0xFF80CBC4), // Soothing teal + primaryContainer: Color(0xFFB26F20), + onPrimaryContainer: Color(0xFFFFECB3), + secondary: Color(0xFF80CBC4), onSecondary: Colors.black, secondaryContainer: Color(0xFF4A635F), - onSecondaryContainer: Color(0xFFB2DFDB), // 87% white - surface: Color(0xFF1E1E1E), // Elevated surfaces - onSurface: Color(0xFFE0E0E0), - - // Error colors + onSecondaryContainer: Color(0xFFB2DFDB), + surface: Color(0xFF121212), + onSurface: Color(0xFFEDEDED), error: Color(0xFFCF6679), onError: Colors.black, - - // Neutral colors - surfaceContainerHighest: Color(0xFF2D2D2D), // For cards/dialogs - outline: Color(0xFF404040), // Borders/dividers + surfaceContainerHighest: Color(0xFF2D2D2D), + outline: Color(0xFF595959), ), textTheme: TextTheme( displayLarge: GoogleFonts.robotoFlex( fontSize: 32, fontWeight: FontWeight.w800, - color: Color(0xFFFFB77A), // Warm highlight + color: Color(0xFFFFB74D), ), headlineMedium: GoogleFonts.robotoFlex( fontSize: 24, fontWeight: FontWeight.w700, letterSpacing: 0.25, + color: Color(0xFFE0E0E0), ), titleLarge: GoogleFonts.robotoFlex( fontSize: 20, fontWeight: FontWeight.w600, + color: Color(0xFFE0E0E0), ), bodyMedium: GoogleFonts.merriweather( fontSize: 16, height: 1.6, - color: Color(0xFFCCCCCC), // Soft gray for body + color: Color(0xFFDEDEDE), ), labelLarge: GoogleFonts.robotoFlex( fontSize: 14, fontWeight: FontWeight.w500, letterSpacing: 0.1, + color: Color(0xFFB0B0B0), ), ), appBarTheme: AppBarTheme( @@ -187,14 +177,14 @@ class ThemeManager with ChangeNotifier { titleTextStyle: GoogleFonts.robotoFlex( fontSize: 20, fontWeight: FontWeight.w600, - color: Color(0xFFFFB77A), + color: Color(0xFFFFB74D), ), - iconTheme: IconThemeData(color: Color(0xFFFFB77A)), + iconTheme: IconThemeData(color: Color(0xFFFFB74D)), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( - backgroundColor: Color(0xFFB26F20), - foregroundColor: Color(0xFFFFD9B3), + backgroundColor: Color(0xFFFFA726), + foregroundColor: Colors.black, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), ), ), @@ -275,7 +265,7 @@ class _ThemeSwitcherWidgetState extends State height: 40, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), - color: isDark ? Colors.grey[800] : Colors.blueGrey[200], + color: isDark ? Color(0xFF2D2D2D) : Color(0xFFF3E9E1), ), child: Stack( children: [ @@ -290,7 +280,7 @@ class _ThemeSwitcherWidgetState extends State height: 32, decoration: BoxDecoration( shape: BoxShape.circle, - color: isDark ? Colors.grey[200] : Colors.amber, + color: isDark ? Color(0xFFFFA726) : Color(0xFFF57C00), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), @@ -303,8 +293,16 @@ class _ThemeSwitcherWidgetState extends State duration: const Duration(milliseconds: 300), child: isDark - ? const Icon(Icons.nightlight_round, size: 20) - : const Icon(Icons.wb_sunny, size: 20), + ? Icon( + Icons.nightlight_round, + size: 20, + color: Colors.black, + ) // Visible in dark mode + : Icon( + Icons.wb_sunny, + size: 20, + color: Colors.white, + ), ), ), ), diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 1c65bab..e71a16d 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,10 +6,6 @@ #include "generated_plugin_registrant.h" -#include void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) desktop_webview_auth_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopWebviewAuthPlugin"); - desktop_webview_auth_plugin_register_with_registrar(desktop_webview_auth_registrar); } diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index e5bf8b2..2e1de87 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - desktop_webview_auth ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 42a7167..908fb0d 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,19 +6,15 @@ import FlutterMacOS import Foundation import connectivity_plus -import desktop_webview_auth -import firebase_auth +import firebase_analytics import firebase_core -import google_sign_in_ios import path_provider_foundation import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) - DesktopWebviewAuthPlugin.register(with: registry.registrar(forPlugin: "DesktopWebviewAuthPlugin")) - FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) + FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) - FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 2296906..3ba7418 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: e55636ed79578b9abca5fecf9437947798f5ef7456308b5cb85720b793eac92f + url: "https://pub.dev" + source: hosted + version: "82.0.0" _flutterfire_internals: dependency: transitive description: @@ -9,6 +17,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.54" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "13c1e6c6fd460522ea840abec3f677cc226f5fec7872c04ad7b425517ccf54f7" + url: "https://pub.dev" + source: hosted + version: "7.4.4" archive: dependency: transitive description: @@ -81,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" connectivity_plus: dependency: "direct main" description: @@ -97,6 +121,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" crypto: dependency: transitive description: @@ -113,30 +145,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" - dbus: + dart_style: dependency: transitive description: - name: dbus - sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + name: dart_style + sha256: "27eb0ae77836989a3bc541ce55595e8ceee0992807f14511552a898ddd0d88ac" url: "https://pub.dev" source: hosted - version: "0.7.11" - desktop_webview_auth: + version: "3.0.1" + dartx: dependency: transitive description: - name: desktop_webview_auth - sha256: c4dce73346a7be7243c90ac3b1a68586d9f0e2c2710e81e07d758e80a6ebd920 + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" url: "https://pub.dev" source: hosted - version: "0.0.15" - email_validator: + version: "1.2.0" + dbus: dependency: transitive description: - name: email_validator - sha256: e9a90f27ab2b915a27d7f9c2a7ddda5dd752d6942616ee83529b686fc086221b + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" url: "https://pub.dev" source: hosted - version: "2.1.17" + version: "0.7.11" fake_async: dependency: transitive description: @@ -161,30 +193,30 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.1" - firebase_auth: + firebase_analytics: dependency: "direct main" description: - name: firebase_auth - sha256: "54c62b2d187709114dd09ce658a8803ee91f9119b0e0d3fc2245130ad9bff9ad" + name: firebase_analytics + sha256: "2416b9d864412ab7b571dafded801bbcc7e29b5824623c055002d4d0819bea2b" url: "https://pub.dev" source: hosted - version: "5.5.2" - firebase_auth_platform_interface: + version: "11.4.5" + firebase_analytics_platform_interface: dependency: transitive description: - name: firebase_auth_platform_interface - sha256: "5402d13f4bb7f29f2fb819f3b6b5a5a56c9f714aef2276546d397e25ac1b6b8e" + name: firebase_analytics_platform_interface + sha256: "3ccf5c876a8bea186016de4bcf53fc1bc6fa01236d740fb501d7ef9be356c58e" url: "https://pub.dev" source: hosted - version: "7.6.2" - firebase_auth_web: - dependency: transitive + version: "4.3.5" + firebase_analytics_web: + dependency: "direct main" description: - name: firebase_auth_web - sha256: "2be496911f0807895d5fe8067b70b7d758142dd7fb26485cbe23e525e2547764" + name: firebase_analytics_web + sha256: "5e4e3f001b67c2034b76cb2a42a0eed330fb3a8fb41ad13eceb04e8d9a74f662" url: "https://pub.dev" source: hosted - version: "5.14.2" + version: "0.5.10+11" firebase_core: dependency: "direct main" description: @@ -209,67 +241,27 @@ packages: url: "https://pub.dev" source: hosted version: "2.22.0" - firebase_dynamic_links: - dependency: transitive - description: - name: firebase_dynamic_links - sha256: ae8844d78a14a335e1d69d9a198dd5bcc4571ba4b028e45c0972e093b48530f8 - url: "https://pub.dev" - source: hosted - version: "6.1.5" - firebase_dynamic_links_platform_interface: - dependency: transitive - description: - name: firebase_dynamic_links_platform_interface - sha256: "7cb3b86956268a18c49badd66eb9a9279b71bf7188a7a2a48204f41db2642e78" - url: "https://pub.dev" - source: hosted - version: "0.2.7+5" - firebase_ui_auth: + flutter: dependency: "direct main" - description: - name: firebase_ui_auth - sha256: cf2cd23625f3df3c6b27e37d04132980f17d707b1adc160bddf425afe1782eed - url: "https://pub.dev" - source: hosted - version: "1.16.1" - firebase_ui_localizations: - dependency: transitive - description: - name: firebase_ui_localizations - sha256: "01c0c872ce08d16d217490af3438c97c4fcf1187e856dd2525f892178782fc46" - url: "https://pub.dev" - source: hosted - version: "1.13.1" - firebase_ui_oauth: - dependency: transitive - description: - name: firebase_ui_oauth - sha256: f7a0a12e7d4f0518848709f093400796a5c7e3ef13f3498ac83793d291341d9e - url: "https://pub.dev" - source: hosted - version: "1.6.1" - firebase_ui_oauth_google: + description: flutter + source: sdk + version: "0.0.0" + flutter_gen: dependency: "direct main" description: - name: firebase_ui_oauth_google - sha256: "92ffcac3f9fe2509ec962fd50041cae2743b7e739017edad4bbe61c829c0a610" + name: flutter_gen + sha256: "4117a3ea6b26a910c715bd58abcc5a90447e70930a5b98249e94c41da9e849bb" url: "https://pub.dev" source: hosted - version: "1.4.1" - firebase_ui_shared: + version: "5.10.0" + flutter_gen_core: dependency: transitive description: - name: firebase_ui_shared - sha256: f1d07c130a39104d32fba1dab274b7bcb13be2bf4e652624a4ccabb58f9781f1 + name: flutter_gen_core + sha256: "3eaa2d3d8be58267ac4cd5e215ac965dd23cae0410dc073de2e82e227be32bfc" url: "https://pub.dev" source: hosted - version: "1.4.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" + version: "5.10.0" flutter_image: dependency: "direct main" description: @@ -295,7 +287,7 @@ packages: source: hosted version: "5.0.0" flutter_localizations: - dependency: transitive + dependency: "direct main" description: flutter source: sdk version: "0.0.0" @@ -307,14 +299,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.7" - flutter_svg: - dependency: transitive - description: - name: flutter_svg - sha256: c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b - url: "https://pub.dev" - source: hosted - version: "2.0.17" flutter_test: dependency: "direct dev" description: flutter @@ -325,62 +309,30 @@ packages: description: flutter source: sdk version: "0.0.0" - google_fonts: - dependency: "direct main" - description: - name: google_fonts - sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 - url: "https://pub.dev" - source: hosted - version: "6.2.1" - google_identity_services_web: + glob: dependency: transitive description: - name: google_identity_services_web - sha256: "55580f436822d64c8ff9a77e37d61f5fb1e6c7ec9d632a43ee324e2a05c3c6c9" + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de url: "https://pub.dev" source: hosted - version: "0.3.3" - google_sign_in: + version: "2.1.3" + google_fonts: dependency: "direct main" description: - name: google_sign_in - sha256: d0a2c3bcb06e607bb11e4daca48bd4b6120f0bbc4015ccebbe757d24ea60ed2a - url: "https://pub.dev" - source: hosted - version: "6.3.0" - google_sign_in_android: - dependency: transitive - description: - name: google_sign_in_android - sha256: "4e52c64366bdb3fe758f683b088ee514cc7a95e69c52b5ee9fc5919e1683d21b" - url: "https://pub.dev" - source: hosted - version: "6.2.0" - google_sign_in_ios: - dependency: transitive - description: - name: google_sign_in_ios - sha256: "29cd125f58f50ceb40e8253d3c0209e321eee3e5df16cd6d262495f7cad6a2bd" - url: "https://pub.dev" - source: hosted - version: "5.8.1" - google_sign_in_platform_interface: - dependency: transitive - description: - name: google_sign_in_platform_interface - sha256: "5f6f79cf139c197261adb6ac024577518ae48fdff8e53205c5373b5f6430a8aa" + name: google_fonts + sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 url: "https://pub.dev" source: hosted - version: "2.5.0" - google_sign_in_web: + version: "6.2.1" + hashcodes: dependency: transitive description: - name: google_sign_in_web - sha256: "460547beb4962b7623ac0fb8122d6b8268c951cf0b646dd150d60498430e4ded" + name: hashcodes + sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" url: "https://pub.dev" source: hosted - version: "0.12.4+4" + version: "2.0.0" http: dependency: "direct main" description: @@ -405,6 +357,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.5.4" + image_size_getter: + dependency: transitive + description: + name: image_size_getter + sha256: "9a299e3af2ebbcfd1baf21456c3c884037ff524316c97d8e56035ea8fdf35653" + url: "https://pub.dev" + source: hosted + version: "2.4.0" intl: dependency: "direct main" description: @@ -485,6 +445,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.16.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" nm: dependency: transitive description: @@ -493,6 +469,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" path: dependency: transitive description: @@ -589,6 +573,22 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.1" + provider: + dependency: "direct main" + description: + name: provider + sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84" + url: "https://pub.dev" + source: hosted + version: "6.1.5" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" shared_preferences: dependency: "direct main" description: @@ -698,6 +698,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.4" + time: + dependency: transitive + description: + name: time + sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" + url: "https://pub.dev" + source: hosted + version: "2.1.5" transparent_image: dependency: "direct main" description: @@ -714,14 +722,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - vector_graphics: - dependency: transitive - description: - name: vector_graphics - sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de" - url: "https://pub.dev" - source: hosted - version: "1.1.18" vector_graphics_codec: dependency: transitive description: @@ -754,6 +754,14 @@ packages: url: "https://pub.dev" source: hosted version: "14.3.1" + watcher: + dependency: transitive + description: + name: watcher + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + url: "https://pub.dev" + source: hosted + version: "1.1.1" web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 64e511b..8beafe3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,6 +54,7 @@ dependencies: provider: ^6.1.4 flutter_localizations: sdk: flutter + flutter_gen: ^5.10.0 dev_dependencies: flutter_test: sdk: flutter @@ -71,7 +72,7 @@ dev_dependencies: # The following section is specific to Flutter packages. flutter: - generate: true # Add this line + generate: false # Add this line # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. diff --git a/web/favicon.png b/web/favicon.png index 8aaa46a..e6f4ff3 100644 Binary files a/web/favicon.png and b/web/favicon.png differ diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png index b749bfe..610d2b3 100644 Binary files a/web/icons/Icon-192.png and b/web/icons/Icon-192.png differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png index 88cfd48..89ca9c6 100644 Binary files a/web/icons/Icon-512.png and b/web/icons/Icon-512.png differ diff --git a/web/icons/Icon-maskable-192.png b/web/icons/Icon-maskable-192.png index eb9b4d7..cc9ba0a 100644 Binary files a/web/icons/Icon-maskable-192.png and b/web/icons/Icon-maskable-192.png differ diff --git a/web/icons/Icon-maskable-512.png b/web/icons/Icon-maskable-512.png index d69c566..5e573aa 100644 Binary files a/web/icons/Icon-maskable-512.png and b/web/icons/Icon-maskable-512.png differ diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 4ec5ae1..7bfdda0 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,17 +7,11 @@ #include "generated_plugin_registrant.h" #include -#include -#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); - DesktopWebviewAuthPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("DesktopWebviewAuthPlugin")); - FirebaseAuthPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); FirebaseCorePluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 58b38de..0e68a11 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,8 +4,6 @@ list(APPEND FLUTTER_PLUGIN_LIST connectivity_plus - desktop_webview_auth - firebase_auth firebase_core )