Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import 'package:flutter/material.dart';
- import 'package:shared_preferences/shared_preferences.dart';
- import 'package:http/http.dart' as http;
- import 'dart:convert';
- void main() => runApp(CakeApp());
- class CakeApp extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- title: 'Cake List',
- home: CakeListScreen(),
- );
- }
- }
- class CakeListScreen extends StatefulWidget {
- @override
- _CakeListScreenState createState() => _CakeListScreenState();
- }
- class _CakeListScreenState extends State<CakeListScreen> {
- List<Cake> cakes = [];
- List<Cake> favoriteCakes = [];
- bool showFavorites = false;
- @override
- void initState() {
- super.initState();
- fetchCakes();
- loadFavorites();
- }
- void updateCake(Cake updatedCake) {
- setState(() {
- final index = cakes.indexWhere((cake) => cake.rowId == updatedCake.rowId);
- if (index != -1) {
- cakes[index] = updatedCake;
- }
- // Если обновленный торт в избранных, обновляем его
- if (favoriteCakes.contains(updatedCake)) {
- final favIndex = favoriteCakes.indexWhere((cake) => cake.rowId == updatedCake.rowId);
- if (favIndex != -1) {
- favoriteCakes[favIndex] = updatedCake;
- }
- }
- });
- }
- Future<void> fetchCakes() async {
- final uriString = "https://v1.slashapi.com/mirea/google-sheets/NdF76f0ELv/list1";
- final response = await http.get(Uri.parse(uriString));
- final jsonResponse = jsonDecode(response.body) as Map<String, dynamic>;
- setState(() {
- cakes = (jsonResponse['data'] as List)
- .map((cake) => Cake.fromJson(cake))
- .toList();
- });
- }
- Future<void> loadFavorites() async {
- final prefs = await SharedPreferences.getInstance();
- final favoriteIds = prefs.getStringList('favorites') ?? [];
- setState(() {
- favoriteCakes =
- cakes.where((cake) => favoriteIds.contains('${cake.rowId}')).toList();
- });
- }
- Future<void> toggleFavorite(Cake cake) async {
- final prefs = await SharedPreferences.getInstance();
- final favoriteIds = prefs.getStringList('favorites') ?? [];
- if (favoriteIds.contains('${cake.rowId}')) {
- favoriteIds.remove('${cake.rowId}');
- } else {
- favoriteIds.add('${cake.rowId}');
- }
- await prefs.setStringList('favorites', favoriteIds);
- loadFavorites();
- }
- void addNewCake(Cake cake) {
- setState(() {
- cakes.add(cake);
- });
- }
- @override
- Widget build(BuildContext context) {
- final displayedCakes = showFavorites ? favoriteCakes : cakes;
- return Scaffold(
- appBar: AppBar(
- title: Text('Cake List'),
- actions: [
- IconButton(
- icon: Icon(showFavorites ? Icons.favorite : Icons.favorite_border),
- onPressed: () {
- setState(() {
- showFavorites = !showFavorites;
- });
- },
- ),
- IconButton(
- icon: Icon(Icons.add),
- onPressed: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => AddCakeScreen(onAddCake: addNewCake),
- ),
- );
- },
- ),
- ],
- ),
- body: ListView.builder(
- itemCount: displayedCakes.length,
- itemBuilder: (context, index) {
- final cake = displayedCakes[index];
- return Card(
- child: ListTile(
- title: Text(cake.name),
- subtitle: Text(cake.description),
- trailing: IconButton(
- icon: Icon(favoriteCakes.contains(cake)
- ? Icons.favorite
- : Icons.favorite_border),
- onPressed: () => toggleFavorite(cake),
- ),
- onTap: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => CakeDetailScreen(cake: cake, onUpdateCake: updateCake),
- ),
- );
- },
- ),
- );
- },
- ),
- );
- }
- }
- class CakeDetailScreen extends StatelessWidget {
- final Cake cake;
- final Function(Cake) onUpdateCake;
- CakeDetailScreen({required this.cake, required this.onUpdateCake});
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text(cake.name),
- ),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text('Description: ${cake.description}', style: TextStyle(fontSize: 16)),
- SizedBox(height: 8),
- Text('Category: ${cake.category}', style: TextStyle(fontSize: 16)),
- SizedBox(height: 8),
- Text('Size: ${cake.size}', style: TextStyle(fontSize: 16)),
- SizedBox(height: 16),
- ElevatedButton(
- onPressed: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => EditCakeScreen(
- cake: cake,
- onUpdateCake: onUpdateCake,
- ),
- ),
- );
- },
- child: Text('Edit Cake'),
- ),
- ],
- ),
- ),
- );
- }
- }
- class EditCakeScreen extends StatefulWidget {
- final Cake cake;
- final Function(Cake) onUpdateCake;
- EditCakeScreen({required this.cake, required this.onUpdateCake});
- @override
- _EditCakeScreenState createState() => _EditCakeScreenState();
- }
- class _EditCakeScreenState extends State<EditCakeScreen> {
- final _formKey = GlobalKey<FormState>();
- late TextEditingController _nameController;
- late TextEditingController _descriptionController;
- late TextEditingController _categoryController;
- late TextEditingController _sizeController;
- @override
- void initState() {
- super.initState();
- _nameController = TextEditingController(text: widget.cake.name);
- _descriptionController = TextEditingController(text: widget.cake.description);
- _categoryController = TextEditingController(text: widget.cake.category);
- _sizeController = TextEditingController(text: widget.cake.size);
- }
- @override
- void dispose() {
- _nameController.dispose();
- _descriptionController.dispose();
- _categoryController.dispose();
- _sizeController.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('Edit Cake'),
- ),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Form(
- key: _formKey,
- child: Column(
- children: [
- TextFormField(
- controller: _nameController,
- decoration: InputDecoration(labelText: 'Name'),
- validator: (value) =>
- value == null || value.isEmpty ? 'Enter a name' : null,
- ),
- TextFormField(
- controller: _descriptionController,
- decoration: InputDecoration(labelText: 'Description'),
- validator: (value) =>
- value == null || value.isEmpty ? 'Enter a description' : null,
- ),
- TextFormField(
- controller: _categoryController,
- decoration: InputDecoration(labelText: 'Category'),
- ),
- TextFormField(
- controller: _sizeController,
- decoration: InputDecoration(labelText: 'Size'),
- ),
- SizedBox(height: 20),
- ElevatedButton(
- onPressed: () {
- if (_formKey.currentState?.validate() == true) {
- final updatedCake = Cake(
- name: _nameController.text,
- description: _descriptionController.text,
- category: _categoryController.text,
- size: _sizeController.text,
- rowId: widget.cake.rowId,
- );
- widget.onUpdateCake(updatedCake);
- Navigator.pop(context);
- }
- },
- child: Text('Save Changes'),
- ),
- ],
- ),
- ),
- ),
- );
- }
- }
- class AddCakeScreen extends StatefulWidget {
- final Function(Cake) onAddCake;
- AddCakeScreen({required this.onAddCake});
- @override
- _AddCakeScreenState createState() => _AddCakeScreenState();
- }
- class _AddCakeScreenState extends State<AddCakeScreen> {
- final _formKey = GlobalKey<FormState>();
- final _nameController = TextEditingController();
- final _descriptionController = TextEditingController();
- final _categoryController = TextEditingController();
- final _sizeController = TextEditingController();
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('Add New Cake'),
- ),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Form(
- key: _formKey,
- child: Column(
- children: [
- TextFormField(
- controller: _nameController,
- decoration: InputDecoration(labelText: 'Name'),
- validator: (value) =>
- value == null || value.isEmpty ? 'Enter a name' : null,
- ),
- TextFormField(
- controller: _descriptionController,
- decoration: InputDecoration(labelText: 'Description'),
- validator: (value) =>
- value == null || value.isEmpty ? 'Enter a description' : null,
- ),
- TextFormField(
- controller: _categoryController,
- decoration: InputDecoration(labelText: 'Category'),
- ),
- TextFormField(
- controller: _sizeController,
- decoration: InputDecoration(labelText: 'Size'),
- ),
- SizedBox(height: 20),
- ElevatedButton(
- onPressed: () {
- if (_formKey.currentState?.validate() == true) {
- final newCake = Cake(
- name: _nameController.text,
- description: _descriptionController.text,
- category: _categoryController.text,
- size: _sizeController.text,
- rowId: DateTime.now().millisecondsSinceEpoch,
- );
- widget.onAddCake(newCake);
- Navigator.pop(context);
- }
- },
- child: Text('Add Cake'),
- ),
- ],
- ),
- ),
- ),
- );
- }
- }
- class Cake {
- final String name;
- final String description;
- final String category;
- final String size;
- final int rowId;
- Cake({
- required this.name,
- required this.description,
- required this.category,
- required this.size,
- required this.rowId,
- });
- factory Cake.fromJson(Map<String, dynamic> json) {
- return Cake(
- name: json['name'],
- description: json['description'],
- category: json['category'],
- size: json['size'],
- rowId: json['row_id'],
- );
- }
- Map<String, dynamic> toJson() {
- return {
- 'name': name,
- 'description': description,
- 'category': category,
- 'size': size,
- 'row_id': rowId,
- };
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement