simple_quotes_plus 1.0.1
simple_quotes_plus: ^1.0.1 copied to clipboard
A Dart package for accessing motivational, love, and wisdom quotes.lling and animation.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:simple_quotes_plus/simple_quotes_plus.dart';
import 'widgets/quote_card.dart';
void main() {
runApp(const QuoteApp());
}
class QuoteApp extends StatelessWidget {
const QuoteApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Quotes App',
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: Colors.teal,
brightness: Brightness.light,
),
home: const QuoteHomePage(),
debugShowCheckedModeBanner: false,
);
}
}
class QuoteHomePage extends StatefulWidget {
const QuoteHomePage({super.key});
@override
State<QuoteHomePage> createState() => _QuoteHomePageState();
}
class _QuoteHomePageState extends State<QuoteHomePage> {
final QuoteRepository repo = QuoteRepository();
List<Quote> displayedQuotes = [];
String? selectedCategory;
String searchQuery = '';
@override
void initState() {
super.initState();
displayedQuotes = [repo.getRandom()];
}
void _filterByCategory(String? category) {
setState(() {
selectedCategory = category;
displayedQuotes = category == null
? repo.getAll()
: repo.getAll().where((q) => q.category == category).toList();
});
}
void _searchQuotes(String query) {
setState(() {
searchQuery = query;
displayedQuotes = repo.search(query);
});
}
@override
Widget build(BuildContext context) {
final categories = repo.getCategories();
return Scaffold(
appBar: AppBar(
title: const Text('✨ Simple Quotes'),
centerTitle: true,
elevation: 0,
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
bottom: PreferredSize(
preferredSize: const Size.fromHeight(60),
child: Padding(
padding: const EdgeInsets.all(12),
child: TextField(
onChanged: _searchQuotes,
decoration: InputDecoration(
hintText: 'Search quotes...',
prefixIcon: const Icon(Icons.search),
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.symmetric(vertical: 12),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
),
),
),
),
),
body: Column(
children: [
Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
alignment: Alignment.centerLeft,
child: Text(
'Categories',
style: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(fontWeight: FontWeight.bold),
),
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 2),
child: Row(
children: [
ChoiceChip(
label: const Text('All'),
selected: selectedCategory == null,
onSelected: (_) => _filterByCategory(null),
),
const SizedBox(width: 8),
...categories.map((cat) => Padding(
padding: const EdgeInsets.only(right: 8),
child: ChoiceChip(
label: Text(cat),
selected: selectedCategory == cat,
onSelected: (_) => _filterByCategory(cat),
),
)),
],
),
),
const SizedBox(height: 8),
Expanded(
child: displayedQuotes.isEmpty
? const Center(child: Text('No quotes found.'))
: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: displayedQuotes.length,
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: QuoteCard(
quote: displayedQuotes[index],
cardColor: const Color(0xFFF4F4F4),
textStyle: const TextStyle(
fontSize: 18, color: Colors.black87),
authorStyle: const TextStyle(
fontWeight: FontWeight.w600,
color: Color.fromARGB(255, 64, 66, 67),
),
chipColor: Colors.teal.shade100,
elevation: 3,
padding: const EdgeInsets.all(20),
borderRadius: BorderRadius.circular(16),
),
),
),
),
],
),
);
}
}