Implement light minimalistic tech redesign with Material 3
Complete transformation from dark to light theme with a professional, tech-forward design system featuring: - Material 3 theming with cyan-based color palette (#0891B2 primary) - Inter font family integration via Google Fonts - Comprehensive theme system (colors, spacing, typography, shadows) - Responsive component redesign across all screens - Enhanced UX with hover animations, Hero transitions, and shimmer loading - Accessibility features (reduced motion support, high contrast) - Clean architecture with zero hardcoded values Theme System: - Created app_colors.dart with semantic color constants - Created app_spacing.dart with 8px base spacing scale - Created app_theme.dart with complete Material 3 configuration - Added shimmer_loading.dart for image loading states UI Components Updated: - Book cards with hover effects and Hero animations - Bottom navigation with refined styling - All screens migrated to theme-based colors and typography - Forms and inputs using consistent design system Documentation: - Added REDESIGN_SUMMARY.md with complete implementation overview - Added IMPLEMENTATION_CHECKLIST.md with detailed task completion status All components now use centralized theme with no hardcoded values, ensuring consistency and easy future customization. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
76
books_flutter/lib/bloc/book_bloc.dart
Normal file
76
books_flutter/lib/bloc/book_bloc.dart
Normal file
@@ -0,0 +1,76 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../models/models.dart';
|
||||
import '../constants/constants.dart';
|
||||
|
||||
// Events
|
||||
sealed class BookEvent {}
|
||||
|
||||
class AddBook extends BookEvent {
|
||||
final Book book;
|
||||
AddBook(this.book);
|
||||
}
|
||||
|
||||
class UpdateBook extends BookEvent {
|
||||
final Book book;
|
||||
UpdateBook(this.book);
|
||||
}
|
||||
|
||||
class DeleteBook extends BookEvent {
|
||||
final String id;
|
||||
DeleteBook(this.id);
|
||||
}
|
||||
|
||||
class ToggleFavorite extends BookEvent {
|
||||
final String id;
|
||||
ToggleFavorite(this.id);
|
||||
}
|
||||
|
||||
// State
|
||||
class BookState {
|
||||
final List<Book> books;
|
||||
const BookState({required this.books});
|
||||
}
|
||||
|
||||
// Bloc
|
||||
class BookBloc extends Bloc<BookEvent, BookState> {
|
||||
BookBloc() : super(const BookState(books: initialBooks)) {
|
||||
on<AddBook>((event, emit) {
|
||||
emit(BookState(books: [...state.books, event.book]));
|
||||
});
|
||||
|
||||
on<UpdateBook>((event, emit) {
|
||||
final updated = state.books.map((b) {
|
||||
return b.id == event.book.id ? event.book : b;
|
||||
}).toList();
|
||||
emit(BookState(books: updated));
|
||||
});
|
||||
|
||||
on<DeleteBook>((event, emit) {
|
||||
emit(
|
||||
BookState(books: state.books.where((b) => b.id != event.id).toList()),
|
||||
);
|
||||
});
|
||||
|
||||
on<ToggleFavorite>((event, emit) {
|
||||
final updated = state.books.map((b) {
|
||||
if (b.id != event.id) return b;
|
||||
return (
|
||||
id: b.id,
|
||||
title: b.title,
|
||||
author: b.author,
|
||||
genre: b.genre,
|
||||
annotation: b.annotation,
|
||||
coverUrl: b.coverUrl,
|
||||
pages: b.pages,
|
||||
language: b.language,
|
||||
publishedYear: b.publishedYear,
|
||||
rating: b.rating,
|
||||
status: b.status,
|
||||
progress: b.progress,
|
||||
isFavorite: !b.isFavorite,
|
||||
);
|
||||
}).toList();
|
||||
emit(BookState(books: updated));
|
||||
});
|
||||
}
|
||||
}
|
||||
53
books_flutter/lib/bloc/navigation_bloc.dart
Normal file
53
books_flutter/lib/bloc/navigation_bloc.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../models/models.dart';
|
||||
|
||||
// Events
|
||||
sealed class NavigationEvent {}
|
||||
|
||||
class NavigateTo extends NavigationEvent {
|
||||
final AppScreen screen;
|
||||
final Book? selectedBook;
|
||||
final Book? prefilledData;
|
||||
NavigateTo(this.screen, {this.selectedBook, this.prefilledData});
|
||||
}
|
||||
|
||||
// State
|
||||
class NavigationState {
|
||||
final AppScreen screen;
|
||||
final Book? selectedBook;
|
||||
final Book? prefilledData;
|
||||
const NavigationState({
|
||||
this.screen = AppScreen.library,
|
||||
this.selectedBook,
|
||||
this.prefilledData,
|
||||
});
|
||||
|
||||
NavigationState copyWith({
|
||||
AppScreen? screen,
|
||||
Book? Function()? selectedBook,
|
||||
Book? Function()? prefilledData,
|
||||
}) {
|
||||
return NavigationState(
|
||||
screen: screen ?? this.screen,
|
||||
selectedBook: selectedBook != null ? selectedBook() : this.selectedBook,
|
||||
prefilledData: prefilledData != null
|
||||
? prefilledData()
|
||||
: this.prefilledData,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Bloc
|
||||
class NavigationBloc extends Bloc<NavigationEvent, NavigationState> {
|
||||
NavigationBloc() : super(const NavigationState()) {
|
||||
on<NavigateTo>((event, emit) {
|
||||
emit(
|
||||
NavigationState(
|
||||
screen: event.screen,
|
||||
selectedBook: event.selectedBook ?? state.selectedBook,
|
||||
prefilledData: event.prefilledData,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user