Skip to content
Merged
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
6 changes: 5 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,9 @@
"eventCreatedSuccess": "Event created successfully",
"isPaidLabel": "Is the event paid?",
"selectPointonMapLabel": "Select location on map",
"locationRequiredError": "Please enter a location"
"locationRequiredError": "Please enter a location",
"eventsCount": "Events",
"followersCount": "Followers",
"followingCount": "Following",
"yourEvents": "Your events"
}
6 changes: 5 additions & 1 deletion lib/l10n/app_pl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,9 @@
"eventCreatedSuccess": "Wydarzenie zostało utworzone pomyślnie",
"isPaidLabel": "Czy wydarzenie jest płatne?",
"selectPointonMapLabel": "Wybierz lokalizacje na mapie",
"locationRequiredError": "Podaj lokalizację"
"locationRequiredError": "Podaj lokalizację",
"eventsCount": "Wydarzenia",
"followersCount": "Obserwujący",
"followingCount": "Obserwowani",
"yourEvents": "Twoje wydarzenia"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import 'package:interns2025b_mobile/src/features/auth/domain/usecases/login_usec
import 'package:interns2025b_mobile/src/features/auth/domain/usecases/logout_usecase.dart';
import 'package:interns2025b_mobile/src/features/auth/domain/usecases/register_usecase.dart';
import 'package:interns2025b_mobile/src/shared/domain/models/user_model.dart';
import 'package:interns2025b_mobile/src/shared/presentation/theme/app_colors.dart';
import 'package:shared_preferences/shared_preferences.dart';

class AuthController extends AsyncNotifier<User?> {
Expand Down Expand Up @@ -160,7 +161,7 @@ class AuthController extends AsyncNotifier<User?> {

void _showError(BuildContext context, String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message), backgroundColor: Colors.red),
SnackBar(content: Text(message), backgroundColor: AppColors.red),
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:interns2025b_mobile/l10n/generated/app_localizations.dart';
import 'package:interns2025b_mobile/src/shared/presentation/widgets/navigation_bar.dart';
import 'package:interns2025b_mobile/src/features/event/presentation/widgets/event_creation_form.dart';

Expand Down Expand Up @@ -43,9 +44,10 @@ class _EventCreationPageState extends ConsumerState<EventCreationPage> {

@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(
title: const Text('Create Event'),
title: Text(localizations.createEventButton),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
Expand Down
3 changes: 2 additions & 1 deletion lib/src/features/event/presentation/widgets/event_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:interns2025b_mobile/l10n/generated/app_localizations.dart';
import 'package:interns2025b_mobile/src/features/event/presentation/widgets/event_data_time_row.dart';
import 'package:interns2025b_mobile/src/features/event/presentation/widgets/event_image.dart';
import 'package:interns2025b_mobile/src/features/event/presentation/widgets/event_price_tag.dart';
import 'package:interns2025b_mobile/src/shared/domain/models/age_category.dart';
import 'package:interns2025b_mobile/src/shared/domain/models/event_model.dart';
import 'package:interns2025b_mobile/src/shared/presentation/theme/app_colors.dart';

Expand Down Expand Up @@ -61,7 +62,7 @@ class EventCard extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Text(
event.ageCategory!,
AgeCategory.fromString(event.ageCategory).localized(context),
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: AppColors.shadeGrey700,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class AgeCategoryDropdown extends StatelessWidget {
items: AgeCategory.values.map((category) {
return DropdownMenuItem(
value: category,
child: Text(category.label(context)),
child: Text(category.localized(context)),
);
}).toList(),
onChanged: onChanged,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:interns2025b_mobile/l10n/generated/app_localizations.dart';
import 'package:interns2025b_mobile/src/shared/presentation/widgets/labeled_text.dart';

class IsPaidCheckbox extends StatelessWidget {
final bool value;
final ValueChanged<bool?> onChanged;

const IsPaidCheckbox({
super.key,
required this.value,
required this.onChanged,
});

@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
LabeledText(localizations.isPaidLabel),
CheckboxListTile(
value: value,
onChanged: onChanged,
controlAffinity: ListTileControlAffinity.leading,
contentPadding: EdgeInsets.zero,
),
const SizedBox(height: 8),
],
);
}
}
21 changes: 21 additions & 0 deletions lib/src/features/profile/domain/utils/event_sorter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:interns2025b_mobile/src/shared/domain/models/event_model.dart';
import 'package:interns2025b_mobile/src/shared/domain/models/event_status.dart';

void sortEvents(List<Event> events) {
events.sort((a, b) {
bool aIsEndedOrCanceled =
a.status == EventStatus.canceled || a.status == EventStatus.ended;
bool bIsEndedOrCanceled =
b.status == EventStatus.canceled || b.status == EventStatus.ended;

if (aIsEndedOrCanceled && !bIsEndedOrCanceled) {
return 1;
} else if (!aIsEndedOrCanceled && bIsEndedOrCanceled) {
return -1;
}

final aDate = a.createdAt ?? DateTime.fromMillisecondsSinceEpoch(0);
final bDate = b.createdAt ?? DateTime.fromMillisecondsSinceEpoch(0);
return bDate.compareTo(aDate);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class DeleteUserRequestButton extends ConsumerWidget {
},
child: Text(
localizations.confirm,
style: const TextStyle(color: Colors.red),
style: TextStyle(color: AppColors.red),
),
),
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:interns2025b_mobile/src/shared/domain/models/event_status.dart';
import 'package:interns2025b_mobile/src/shared/presentation/theme/app_colors.dart';

class EventStatusBadge extends StatelessWidget {
final EventStatus status;

const EventStatusBadge({super.key, required this.status});

Color get _backgroundColor {
switch (status) {
case EventStatus.draft:
return AppColors.draftEventBadge.withValues(alpha: 0.5);
case EventStatus.published:
return AppColors.blueLabelBackground.withValues(alpha: 0.2);
case EventStatus.ongoing:
return AppColors.primary.withValues(alpha: 0.2);
case EventStatus.canceled:
case EventStatus.ended:
return AppColors.grey.withValues(alpha: 0.2);
}
}

@override
Widget build(BuildContext context) {
final color = _backgroundColor;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(8),
),
child: Text(
status.label(context),
style: const TextStyle(
color: AppColors.black,
fontSize: 12,
fontWeight: FontWeight.w500,
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:interns2025b_mobile/src/features/event/presentation/widgets/event_data_time_row.dart';
import 'package:interns2025b_mobile/src/features/event/presentation/widgets/event_image.dart';
import 'package:interns2025b_mobile/src/features/profile/presentation/widgets/event_status_badge.dart';
import 'package:interns2025b_mobile/src/shared/domain/models/event_model.dart';
import 'package:interns2025b_mobile/src/shared/presentation/theme/app_colors.dart';

class ProfileEventCard extends StatelessWidget {
final Event event;

const ProfileEventCard({super.key, required this.event});

@override
Widget build(BuildContext context) {
return ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 210),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
clipBehavior: Clip.antiAlias,
elevation: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: 16 / 9,
child: EventImage(
imageUrl: event.imageUrl,
width: double.infinity,
borderRadius: BorderRadius.zero,
),
),
Container(
color: AppColors.backgroundLight,
padding: const EdgeInsets.fromLTRB(12, 10, 12, 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
EventDateTimeRow(date: event.start),
const SizedBox(height: 6),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
event.title,
style: Theme.of(context).textTheme.bodyMedium
?.copyWith(
fontWeight: FontWeight.bold,
color: AppColors.black,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(width: 8),
EventStatusBadge(status: event.status),
],
),
],
),
),
],
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:interns2025b_mobile/l10n/generated/app_localizations.dart';
import 'package:interns2025b_mobile/src/core/routes/app_routes.dart';
import 'package:interns2025b_mobile/src/features/profile/presentation/widgets/profile_event_card.dart';
import 'package:interns2025b_mobile/src/shared/domain/models/event_model.dart';

class ProfileEventsSection extends ConsumerWidget {
final List<Event> events;

const ProfileEventsSection({super.key, required this.events});

@override
Widget build(BuildContext context, WidgetRef ref) {
if (events.isEmpty) {
return const SizedBox();
}

final localizations = AppLocalizations.of(context)!;

return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 24),
Text(
localizations.yourEvents,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 12),
SizedBox(
height: 200,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: events.length,
separatorBuilder: (_, _) => const SizedBox(width: 12),
itemBuilder: (context, index) {
final event = events[index];
return GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
AppRoutes.eventDetails,
arguments: event.id,
);
},
child: ProfileEventCard(event: event),
);
},
),
),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,33 @@ class ProfileInfoCard extends ConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
final screenHeight = MediaQuery.of(context).size.height;
final topPadding = MediaQuery.of(context).padding.top;

return Stack(
clipBehavior: Clip.none,
children: [
Container(
width: double.infinity,
constraints: BoxConstraints(
minHeight: screenHeight - topPadding - 170,
),
padding: const EdgeInsets.fromLTRB(24, 60, 24, 24),
decoration: BoxDecoration(
color: AppColors.backgroundLight,
borderRadius: BorderRadius.vertical(top: Radius.circular(50)),
boxShadow: [
borderRadius: const BorderRadius.vertical(top: Radius.circular(50)),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 12,
offset: Offset(0, -2),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const ProfileInfoContent(),
const SizedBox(height: 24),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 0),
child: ProfileEditSection(),
),
],
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: const [
ProfileInfoContent(),
SizedBox(height: 24),
ProfileEditSection(),
],
),
),
),
Positioned(
Expand Down
Loading