Skip to content
Merged

Dev #32

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,5 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ PODS:
- permission_handler_apple (9.3.0):
- Flutter
- Polyline (5.1.0)
- PostHog (3.36.0)
- PostHog (3.48.3)
- posthog_flutter (0.0.1):
- Flutter
- FlutterMacOS
Expand Down Expand Up @@ -211,7 +211,7 @@ SPEC CHECKSUMS:
path_provider_foundation: 0b743cbb62d8e47eab856f09262bb8c1ddcfe6ba
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
Polyline: 2a1f29f87f8d9b7de868940f4f76deb8c678a5b1
PostHog: 8e04df01d59971f1fd85d0273e18ba61076fef72
PostHog: 38e00e9376b90f0d92de958105029e4736ffe7f9
posthog_flutter: c7888a7df4a4eb0a6473c50da2e12520c33408c4
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f
Expand Down
7 changes: 5 additions & 2 deletions ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import Flutter
import UIKit

@main
@objc class AppDelegate: FlutterAppDelegate {
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
}
}
21 changes: 21 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,27 @@
<true/>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app may need photo access to upload images from gallery.</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneDelegateClassName</key>
<string>FlutterSceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
Expand Down
10 changes: 3 additions & 7 deletions lib/core/common/utils/name_validation.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import 'package:flutter/material.dart';
import 'package:form_builder_validators/form_builder_validators.dart';

final RegExp _latinNamePattern =
RegExp(r"^[A-Za-zÀ-ÖØ-öø-ÿ][A-Za-zÀ-ÖØ-öø-ÿ .'\-]*$");
final RegExp _latinNamePattern = RegExp(r"^[A-Za-zÀ-ÖØ-öø-ÿ][A-Za-zÀ-ÖØ-öø-ÿ .'\-]*$");

FormFieldValidator<String> nameValidator({
required String errorText,
bool required = false,
}) {
FormFieldValidator<String> nameValidator({required String errorText, bool required = false}) {
final validators = <FormFieldValidator<String>>[];
if (required) {
validators.add(FormBuilderValidators.required());
}
validators.add(
FormBuilderValidators.match(
_latinNamePattern.pattern,
_latinNamePattern.pattern as RegExp,
errorText: errorText,
checkNullOrEmpty: false,
),
Expand Down
2 changes: 2 additions & 0 deletions lib/core/config/theme/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class AnyStepTheme {
primary: AnyStepColors.blueBright,
onPrimaryContainer: AnyStepColors.navyDark,
secondary: AnyStepColors.blueDeep,
tertiary: AnyStepColors.purple,
secondaryContainer: AnyStepColors.blueBright20,
onSecondary: AnyStepColors.white,
surface: AnyStepColors.white,
Expand Down Expand Up @@ -92,6 +93,7 @@ class AnyStepTheme {
primary: AnyStepColors.blueBright,
onPrimaryContainer: AnyStepColors.navyDark,
secondary: AnyStepColors.blueDeep,
tertiary: AnyStepColors.purple,
secondaryContainer: AnyStepColors.blueBright20,
onSecondary: AnyStepColors.pureWhite,
surface: AnyStepColors.pureWhite,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,21 +335,27 @@ class _MonthlyHoursChart extends StatelessWidget {
.map((p) => p.hours)
.fold<double>(0, (max, v) => v > max ? v : max)
.clamp(1, double.infinity);
final minX = 0.0;
final maxX = (points.length - 1).toDouble().clamp(1, double.infinity);

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: Theme.of(
context,
).textTheme.labelMedium?.copyWith(color: foreground ?? theme.colorScheme.onSurface),
style: Theme.of(context).textTheme.labelMedium?.copyWith(
color: foreground ?? theme.colorScheme.onSurface,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: AnyStepSpacing.sm8),
SizedBox(
Container(
height: 120,
padding: const .symmetric(horizontal: AnyStepSpacing.md16),
child: LineChart(
LineChartData(
minX: minX,
maxX: maxX.toDouble(),
minY: 0,
maxY: maxY * 1.2,
gridData: const FlGridData(show: false),
Expand Down Expand Up @@ -388,19 +394,14 @@ class _MonthlyHoursChart extends StatelessWidget {
FlSpot(i.toDouble(), points[i].hours),
],
isCurved: true,
barWidth: 2.5,
color: foreground ?? theme.colorScheme.primary,
curveSmoothness: 0.25,
preventCurveOverShooting: true,
barWidth: 3,
color: theme.colorScheme.primary,
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
colors: [
(foreground ?? theme.colorScheme.primary).withAlpha(80),
Colors.transparent,
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
color: theme.colorScheme.primary.withAlpha(40),
),
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import 'package:anystep/core/features/events/utils/launch_calendar.dart';
import 'package:anystep/core/features/profile/data/current_user.dart';
import 'package:anystep/core/features/profile/domain/user_role.dart';
import 'package:anystep/core/features/screens.dart';
import 'package:anystep/core/features/user_events/presentation/add_attendee_screen.dart';
import 'package:anystep/core/features/user_events/presentation/sign_up_button.dart';
import 'package:anystep/core/common/widgets/share_button.dart';
import 'package:anystep/l10n/generated/app_localizations.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ class AttendanceList extends ConsumerWidget {
trailing: AnyStepBadge(
color: switch (user.role) {
UserRole.admin => Theme.of(context).colorScheme.tertiary,
UserRole.board => Theme.of(context).colorScheme.primary,
UserRole.volunteer => Theme.of(context).colorScheme.secondary,
UserRole.board => Theme.of(context).colorScheme.secondary,
UserRole.volunteer => Theme.of(context).colorScheme.primary,
},
child: Text(
user.role.displayName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ class SignUpList extends ConsumerWidget {
trailing: AnyStepBadge(
color: switch (user.role) {
UserRole.admin => Theme.of(context).colorScheme.tertiary,
UserRole.board => Theme.of(context).colorScheme.primary,
UserRole.volunteer => Theme.of(context).colorScheme.secondary,
UserRole.board => Theme.of(context).colorScheme.secondary,
UserRole.volunteer => Theme.of(context).colorScheme.primary,
},
child: Text(
user.role.displayName,
Expand Down
4 changes: 2 additions & 2 deletions lib/core/features/profile/presentation/user_feed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ class UserFeed extends StatelessWidget {
trailing: AnyStepBadge(
color: switch (user.role) {
UserRole.admin => Theme.of(context).colorScheme.tertiary,
UserRole.board => Theme.of(context).colorScheme.primary,
UserRole.volunteer => Theme.of(context).colorScheme.secondary,
UserRole.board => Theme.of(context).colorScheme.secondary,
UserRole.volunteer => Theme.of(context).colorScheme.primary,
},
child: Text(
user.role.displayName,
Expand Down
25 changes: 23 additions & 2 deletions lib/core/features/reports/data/volunteer_hours_providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,29 @@ List<MonthlyHoursPoint> _aggregateMonthlyHours(List<VolunteerHoursReport> report
}

List<MonthlyHoursPoint> _takeLastMonths(List<MonthlyHoursPoint> points, {int maxMonths = 6}) {
if (points.length <= maxMonths) return points;
return points.sublist(points.length - maxMonths);
final now = DateTime.now();
final baseMonths = <DateTime>[
for (var i = maxMonths - 1; i >= 0; i--) DateTime(now.year, now.month - i),
];
if (points.isEmpty) {
return baseMonths.map((month) => MonthlyHoursPoint(month: month, hours: 0)).toList();
}

final Map<String, double> byMonth = {
for (final p in points)
"${p.month.year.toString().padLeft(4, '0')}-${p.month.month.toString().padLeft(2, '0')}"
: p.hours,
};
return baseMonths
.map(
(month) => MonthlyHoursPoint(
month: month,
hours:
byMonth["${month.year.toString().padLeft(4, '0')}-${month.month.toString().padLeft(2, '0')}"] ??
0,
),
)
.toList();
}

@riverpod
Expand Down
35 changes: 17 additions & 18 deletions lib/core/features/user_events/presentation/add_attendee_screen.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:anystep/core/common/constants/spacing.dart';
import 'package:anystep/core/common/widgets/inputs/inputs.dart';
import 'package:anystep/core/common/widgets/widgets.dart';
import 'package:anystep/core/features/events/data/event_repository.dart';
import 'package:anystep/core/features/profile/domain/user_model.dart';
Expand Down Expand Up @@ -129,8 +128,7 @@ class _AddAttendeeScreenState extends ConsumerState<AddAttendeeScreen> {
labelText: loc.checkInLabel,
initialValue: initialCheckIn,
enabled: _attended,
validator:
_attended ? FormBuilderValidators.required() : null,
validator: _attended ? FormBuilderValidators.required() : null,
),
),
const SizedBox(width: AnyStepSpacing.sm2),
Expand All @@ -140,21 +138,22 @@ class _AddAttendeeScreenState extends ConsumerState<AddAttendeeScreen> {
labelText: loc.checkOutLabel,
initialValue: initialCheckOut,
enabled: _attended,
validator:
_attended
? FormBuilderValidators.compose([
FormBuilderValidators.required(),
(val) {
final checkIn =
formKey.currentState?.fields['checkInAt']?.value
as DateTime?;
if (val != null && checkIn != null && val.isBefore(checkIn)) {
return 'Check out must be after check in';
}
return null;
},
])
: null,
validator: _attended
? FormBuilderValidators.compose([
FormBuilderValidators.required(),
(val) {
final checkIn =
formKey.currentState?.fields['checkInAt']?.value
as DateTime?;
if (val != null &&
checkIn != null &&
val.isBefore(checkIn)) {
return 'Check out must be after check in';
}
return null;
},
])
: null,
),
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ import 'package:go_router/go_router.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class AttendeeSearchForm extends ConsumerStatefulWidget {
const AttendeeSearchForm({
super.key,
required this.eventId,
required this.onUserSelected,
});
const AttendeeSearchForm({super.key, required this.eventId, required this.onUserSelected});

final int eventId;
final ValueChanged<UserModel> onUserSelected;
Expand Down Expand Up @@ -56,7 +52,7 @@ class _AttendeeSearchFormState extends ConsumerState<AttendeeSearchForm> {
if (!mounted || userId == null) return;
final user = await ref.read(userRepositoryProvider).get(documentId: userId);
widget.onUserSelected(user);
if (mounted && context.canPop()) {
if (mounted && context.mounted && context.canPop()) {
context.pop();
}
},
Expand Down
Loading
Loading