💻
Gürkan Fikret Günak - Personal
  • 👨‍💻About me
    • 🌊Journey
  • 🎯Dart
    • 🔬What's Dart Algorithms?
    • 🔬What's Dart Structures?
    • 🧮#01 Algorithm Guidance: Implementing Calculation Algorithms
    • 🧮#02 Algorithm Guidance: Two Sum
  • 📄Guidances
    • Flutter MVVM Guidance
    • Dart Programming Guidance
    • E-Commerce Use Cases
    • E-Commerce Applications
    • Flutter App Color Palette Usage Guidance
    • Flutter Custom AppBar Usage Guidance
    • Flutter Network Image Cache Usage Guidance
    • Flutter Project Bitbucket SSH Guidance
    • Flutter Project GitHub SSH Guidance
    • Flutter SliverAppBar Usage Guidance
    • The Importance of BuildContext in Flutter Tests Guidance
    • Internship Basic Guidance v0.1.0
    • The Importance of Type Casting in Flutter
    • Effective and Detailed Pull Request Guide
    • Flutter Naming Conventions Guidance
    • Flutter Widget Guidance
    • Semantic Commit Guidance
    • Being Part of a Mobile Software Team and Working on a Shared Architecture
    • Understanding Deep Links for Any Development Platform
    • The Journey of a Developer: Stories of Becoming Junior, Middle, and Senior Developer
    • Becoming a Team Leader: Growing in Sync with Your Team
    • Why IP Changes Are Important for Mobile Applications in Flutter
    • Why Your Growing Mobile Team Needs CI/CD and How to Build a Winning Strategy
    • Dart in 2024: 20 Features You Need to Know With Code Examples and Scenarios
    • Remote Theme Management with API (JSON): Implementing a Helper in Flutter SDK
    • Understanding and Implementing Force Upgrade in Your Flutter Project
    • Life Lessons from the Bald Eagle: A Metaphor for Growth, Change, and Leadership
    • The Beauty of Imperfection: Why Today Doesn’t Need to Be Perfect
    • # The Reverse Curve of Productivity: When Social Cohesion in Software Teams Starts to Hurt **How str
    • 📱 Mobil Uygulamalarda GraphQL Tercihi: Bakım ve Maliyet Etkiler
    • 📉 Türkiye’de Yazılım Projelerinde Süreç Yönetimi ve Ekonomik Kayıp: Bir Bekâ Sorunu mu?
  • 📹VIDEOS
    • Introduction to Flutter Boilerplate! ( Turkish )
    • Flutter APIs effective using ( English )
    • Understand to SDK ( English )
  • Links
    • 💼 | Linkedin
    • 🆇 | x.com
    • 📧 | Mail me
Powered by GitBook
On this page
  • 1. View Product List from API
  • 2. Search Products from API
  • 3. View Product Details from API
  • 4. Add to Cart with Local Storage
  • 5. Checkout with API Integration
  • 6. View Categories and Subcategories from API
  • 7. View Featured Products from API
  • 8. View User Profile from API
  • 9. View Order History from API
  • 10. View Deals and Discounts from API
  1. Guidances

E-Commerce Use Cases

1. View Product List from API

In this use case, we will use MVVM with a repository to fetch a list of products from an API and display them in the e-commerce application.

Model:

class Product {
  final String name;
  final double price;
  final String imageUrl;

  Product({required this.name, required this.price, required this.imageUrl});
}

Repository:

class ProductRepository {
  Future<List<Product>> getProducts() async {
    // Fetch products from the API
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/products');
    // Parse the response and return the list of products
    // return List<Product>.from(response.data.map((productData) => Product(
    //   name: productData['name'],
    //   price: productData['price'],
    //   imageUrl: productData['imageUrl'],
    // )));
    // For this example, we will use a hardcoded list of products.
    return [
      Product(name: 'Smartphone', price: 499.99, imageUrl: 'https://example.com/smartphone.jpg'),
      Product(name: 'Laptop', price: 899.99, imageUrl: 'https://example.com/laptop.jpg'),
      Product(name: 'Headphones', price: 99.99, imageUrl: 'https://example.com/headphones.jpg'),
    ];
  }
}

ViewModel:

import 'package:flutter/material.dart';

class ProductListViewModel extends ChangeNotifier {
  final ProductRepository _repository;

  ProductListViewModel(this._repository);

  List<Product> _products = [];

  List<Product> get products => _products;

  Future<void> fetchProducts() async {
    _products = await _repository.getProducts();
    notifyListeners();
  }
}

View:

class ProductListView extends StatelessWidget {
  final ProductListViewModel viewModel;

  ProductListView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Product List')),
      body: ListView.builder(
        itemCount: viewModel.products.length,
        itemBuilder: (context, index) {
          final product = viewModel.products[index];
          return ListTile(
            leading: Image.network(product.imageUrl),
            title: Text(product.name),
            subtitle: Text('\$${product.price.toStringAsFixed(2)}'),
          );
        },
      ),
    );
  }
}

2. Search Products from API

In this use case, we will use MVVM with a repository to search for products based on user input by making API calls.

Repository:

class ProductRepository {
  // ... existing code ...

  Future<List<Product>> searchProducts(String query) async {
    // Fetch products from the API based on the query
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/products?q=$query');
    // Parse the response and return the list of products
    // return List<Product>.from(response.data.map((productData) => Product(
    //   name: productData['name'],
    //   price: productData['price'],
    //   imageUrl: productData['imageUrl'],
    // )));
    // For this example, we will use a hardcoded list of products for simplicity.
    return _products.where((product) => product.name.toLowerCase().contains(query.toLowerCase())).toList();
  }
}

ViewModel:

class ProductSearchViewModel extends ChangeNotifier {
  // ... existing code ...

  Future<void> searchProducts(String query) async {
    _products = await _repository.searchProducts(query);
    notifyListeners();
  }
}

View:

class ProductSearchView extends StatelessWidget {
  final ProductSearchViewModel viewModel;

  ProductSearchView({required this.viewModel});

  final TextEditingController _searchController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Search Products')),
      body: Column(
        children: [
          TextField(
            controller: _searchController,
            decoration: InputDecoration(labelText: 'Search'),
            onChanged: (query) => viewModel.searchProducts(query),
          ),
          // ... existing code ...
        ],
      ),
    );
  }
}

3. View Product Details from API

In this use case, we will use MVVM with a repository to fetch and display detailed information about a selected product from the API.

Repository:

class ProductRepository {
  // ... existing code ...

  Future<Product> getProductDetails(String productId) async {
    // Fetch product details from the API based on the productId
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/products/$productId');
    // Parse the response and return the product details
    // return Product(
    //   name: response.data['name'],
    //   price: response.data['price'],
    //   imageUrl: response.data['imageUrl'],
    // );
    // For this example, we will use a hardcoded product details.
    return Product(name: 'Smartphone', price: 499.99, imageUrl: 'https://example.com/smartphone.jpg');
  }
}

ViewModel:

class ProductDetailsViewModel extends ChangeNotifier {
  // ... existing code ...

  Product? _selectedProduct;

  Product? get selectedProduct => _selectedProduct;

  Future<void> fetchProductDetails(String productId) async {
    _selectedProduct = await _repository.getProductDetails(productId);
    notifyListeners();
  }
}

View:

class ProductDetailsView extends StatelessWidget {
  final ProductDetailsViewModel viewModel;

  ProductDetailsView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    // ... existing code ...
  }
}

4. Add to Cart with Local Storage

In this use case, we will use MVVM with a repository to add products to the shopping cart and store the cart locally on the device.

Model:

class CartItem {
  final Product product;
  int quantity;

  CartItem({required this.product, this.quantity = 1});
}

Repository:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class CartRepository {
  static const String _cartKey = 'cart';

  Future<List<CartItem>> getCartItems() async {
    final prefs = await SharedPreferences.getInstance();
    final cartData = prefs.getStringList(_cartKey);
    if (cartData == null) {
      return [];
    }
    return cartData.map((itemData) {
      final productData = itemData.split(',');
      final product = Product(name: productData[0], price: double.parse(productData[1]), imageUrl: productData[2]);
      return CartItem(product: product, quantity: int.parse(productData[3]));
    }).toList();
  }

  Future<void> addToCart(CartItem item) async {
    final prefs = await SharedPreferences.getInstance();
   

 final cartData = prefs.getStringList(_cartKey) ?? [];
    final itemData = '${item.product.name},${item.product.price},${item.product.imageUrl},${item.quantity}';
    cartData.add(itemData);
    await prefs.setStringList(_cartKey, cartData);
  }

  Future<void> clearCart() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_cartKey);
  }
}

ViewModel:

class ShoppingCartViewModel extends ChangeNotifier {
  final CartRepository _repository;

  ShoppingCartViewModel(this._repository);

  List<CartItem> _cartItems = [];

  List<CartItem> get cartItems => _cartItems;

  Future<void> fetchCartItems() async {
    _cartItems = await _repository.getCartItems();
    notifyListeners();
  }

  Future<void> addToCart(Product product) async {
    var existingItem = _cartItems.firstWhere((item) => item.product == product, orElse: () => null);
    if (existingItem != null) {
      existingItem.quantity++;
    } else {
      _cartItems.add(CartItem(product: product));
    }
    notifyListeners();
    await _repository.addToCart(_cartItems.last);
  }

  Future<void> clearCart() async {
    _cartItems.clear();
    notifyListeners();
    await _repository.clearCart();
  }
}

View:

class ShoppingCartView extends StatelessWidget {
  final ShoppingCartViewModel viewModel;

  ShoppingCartView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Shopping Cart')),
      body: ListView.builder(
        itemCount: viewModel.cartItems.length,
        itemBuilder: (context, index) {
          // ... existing code ...
        },
      ),
    );
  }
}

5. Checkout with API Integration

In this use case, we will use MVVM with a repository to handle the checkout process and place an order by making API calls.

Repository:

class OrderRepository {
  Future<void> placeOrder(List<CartItem> items) async {
    // Perform order placement logic using API
    // Example API call using http package:
    // await http.post('https://api.example.com/orders', body: {'items': items});
    // For this example, we will simply print the order details.
    print('Order Placed:');
    for (var item in items) {
      print(' - ${item.product.name} x ${item.quantity}');
    }
  }
}

ViewModel:

class CheckoutViewModel extends ChangeNotifier {
  // ... existing code ...

  final OrderRepository _orderRepository;

  CheckoutViewModel(this._orderRepository);

  Future<void> checkout() async {
    await _orderRepository.placeOrder(_cartItems);
    _cartItems.clear();
    notifyListeners();
  }
}

View:

class CheckoutView extends StatelessWidget {
  final CheckoutViewModel viewModel;

  CheckoutView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Checkout')),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          // ... existing code ...
        ],
      ),
    );
  }
}

6. View Categories and Subcategories from API

In this use case, we will use MVVM with a repository to fetch and display product categories and their subcategories from an API.

Model:

class Category {
  final String name;
  final List<String> subcategories;

  Category({required this.name, required this.subcategories});
}

Repository:

class CategoryRepository {
  Future<List<Category>> getCategories() async {
    // Fetch categories from the API
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/categories');
    // Parse the response and return the list of categories
    // return List<Category>.from(response.data.map((categoryData) => Category(
    //   name: categoryData['name'],
    //   subcategories: List<String>.from(categoryData['subcategories']),
    // )));
    // For this example, we will use a hardcoded list of categories.
    return [
      Category(name: 'Electronics', subcategories: ['Smartphones', 'Laptops', 'Headphones']),
      Category(name: 'Clothing', subcategories: ['T-Shirts', 'Jeans', 'Dresses']),
      Category(name: 'Home & Living', subcategories: ['Furniture', 'Bedding', 'Decor']),
    ];
  }
}

ViewModel:

class CategoryViewModel extends ChangeNotifier {
  // ... existing code ...

  List<Category> _categories = [];

  List<Category> get categories => _categories;

  Future<void> fetchCategories() async {
    _categories = await _repository.getCategories();
    notifyListeners();
  }
}

View:

class CategoryView extends StatelessWidget {
  final CategoryViewModel viewModel;

  CategoryView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Categories')),
      body: ListView.builder(
        itemCount: viewModel.categories.length,
        itemBuilder: (context, index) {
          final category = viewModel.categories[index];
          return ExpansionTile(
            title: Text(category.name),
            children: [
              for (var subcategory in category.subcategories) ListTile(title: Text(subcategory)),
            ],
          );
        },
      ),
    );
  }
}

7. View Featured Products from API

In this use case, we will use MVVM with a repository to fetch and display a list of featured products from an API.

Repository:

class FeaturedProductRepository {
  Future<List<Product>> getFeaturedProducts() async {
    // Fetch featured products from the API
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/featured');
    // Parse the response and return the list of featured products
    // return List<Product>.from(response.data.map((productData) => Product(
    //   name: productData['name'],
    //   price: productData['price'],
    //   imageUrl: productData['imageUrl'],
    // )));
    // For this example, we will use a hardcoded list of featured products.
    return [
      Product(name: 'Smartphone', price: 499.99, imageUrl: 'https://example.com/smartphone.jpg'),
      Product(name: 'Laptop', price: 899.99, imageUrl: 'https://example.com/laptop.jpg'),
      Product(name: 'Headphones', price: 99.99, imageUrl: 'https://example.com/headphones.jpg'),
    ];
  }
}

ViewModel:

class FeaturedProductViewModel extends ChangeNotifier {
  // ... existing code ...

  List<Product> _featuredProducts = [];

  List<Product> get featuredProducts => _featuredProducts;

  Future<void> fetchFeaturedProducts() async {
    _featuredProducts = await _repository.getFeaturedProducts();
    notifyListeners();
  }
}

View:

class FeaturedProductView extends StatelessWidget {
  final FeaturedProductViewModel viewModel;

  FeaturedProductView({required this.viewModel});

  @override
  Widget build(BuildContext context

) {
    return Scaffold(
      appBar: AppBar(title: Text('Featured Products')),
      body: ListView.builder(
        itemCount: viewModel.featuredProducts.length,
        itemBuilder: (context, index) {
          final product = viewModel.featuredProducts[index];
          return ListTile(
            leading: Image.network(product.imageUrl),
            title: Text(product.name),
            subtitle: Text('\$${product.price.toStringAsFixed(2)}'),
          );
        },
      ),
    );
  }
}

8. View User Profile from API

In this use case, we will use MVVM with a repository to fetch and display the user's profile information from an API.

Model:

class UserProfile {
  final String username;
  final String email;
  final String imageUrl;

  UserProfile({required this.username, required this.email, required this.imageUrl});
}

Repository:

class UserRepository {
  Future<UserProfile> getUserProfile() async {
    // Fetch user profile from the API
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/user');
    // Parse the response and return the user profile
    // return UserProfile(
    //   username: response.data['username'],
    //   email: response.data['email'],
    //   imageUrl: response.data['imageUrl'],
    // );
    // For this example, we will use a hardcoded user profile.
    return UserProfile(
      username: 'john_doe',
      email: '[email protected]',
      imageUrl: 'https://example.com/john_doe.jpg',
    );
  }
}

ViewModel:

class UserProfileViewModel extends ChangeNotifier {
  // ... existing code ...

  UserProfile? _userProfile;

  UserProfile? get userProfile => _userProfile;

  Future<void> fetchUserProfile() async {
    _userProfile = await _repository.getUserProfile();
    notifyListeners();
  }
}

View:

class UserProfileView extends StatelessWidget {
  final UserProfileViewModel viewModel;

  UserProfileView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('User Profile')),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SizedBox(height: 20),
          CircleAvatar(radius: 50, backgroundImage: NetworkImage(viewModel.userProfile!.imageUrl)),
          SizedBox(height: 20),
          Text('Username: ${viewModel.userProfile!.username}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          SizedBox(height: 10),
          Text('Email: ${viewModel.userProfile!.email}', style: TextStyle(fontSize: 18)),
        ],
      ),
    );
  }
}

9. View Order History from API

In this use case, we will use MVVM with a repository to fetch and display the user's order history from an API.

Model:

class Order {
  final String orderId;
  final List<CartItem> items;
  final double totalAmount;
  final DateTime orderDate;

  Order({required this.orderId, required this.items, required this.totalAmount, required this.orderDate});
}

Repository:

class OrderRepository {
  Future<List<Order>> getOrderHistory() async {
    // Fetch order history from the API
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/orders');
    // Parse the response and return the list of orders
    // return List<Order>.from(response.data.map((orderData) => Order(
    //   orderId: orderData['orderId'],
    //   items: List<CartItem>.from(orderData['items'].map((itemData) => CartItem(
    //     product: Product(name: itemData['name'], price: itemData['price'], imageUrl: itemData['imageUrl']),
    //     quantity: itemData['quantity'],
    //   ))),
    //   totalAmount: orderData['totalAmount'],
    //   orderDate: DateTime.parse(orderData['orderDate']),
    // )));
    // For this example, we will use a hardcoded list of orders.
    return [
      Order(
        orderId: '12345',
        items: [CartItem(product: Product(name: 'Smartphone', price: 499.99, imageUrl: 'https://example.com/smartphone.jpg')), CartItem(product: Product(name: 'Headphones', price: 99.99, imageUrl: 'https://example.com/headphones.jpg'))],
        totalAmount: 599.98,
        orderDate: DateTime.now().subtract(Duration(days: 5)),
      ),
      Order(
        orderId: '67890',
        items: [CartItem(product: Product(name: 'Laptop', price: 899.99, imageUrl: 'https://example.com/laptop.jpg')), CartItem(product: Product(name: 'Headphones', price: 99.99, imageUrl: 'https://example.com/headphones.jpg'))],
        totalAmount: 999.98,
        orderDate: DateTime.now().subtract(Duration(days: 10)),
      ),
    ];
  }
}

ViewModel:

class OrderHistoryViewModel extends ChangeNotifier {
  // ... existing code ...

  List<Order> _orderHistory = [];

  List<Order> get orderHistory => _orderHistory;

  Future<void> fetchOrderHistory() async {
    _orderHistory = await _repository.getOrderHistory();
    notifyListeners();
  }
}

View:

class OrderHistoryView extends StatelessWidget {
  final OrderHistoryViewModel viewModel;

  OrderHistoryView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Order History')),
      body: ListView.builder(
        itemCount: viewModel.orderHistory.length,
        itemBuilder: (context, index) {
          final order = viewModel.orderHistory[index];
          return ExpansionTile(
            title: Text('Order #${order.orderId}'),
            children: [
              for (var item in order.items) ListTile(title: Text('${item.product.name} - \$${item.product.price.toStringAsFixed(2)}')),
              ListTile(title: Text('Total Amount: \$${order.totalAmount.toStringAsFixed(2)}')),
              ListTile(title: Text('Order Date: ${order.orderDate.day}/${order.orderDate.month}/${order.orderDate.year}')),
            ],
          );
        },
      ),
    );
  }
}

10. View Deals and Discounts from API

In this use case, we will use MVVM with a repository to fetch and display a list of deals and discounts from an API.

Model:

class Deal {
  final String title;
  final String description;

  Deal({required this.title, required this.description});
}

Repository:

class DealRepository {
  Future<List<Deal>> getDeals() async {
    // Fetch deals from the API
    // Example API call using http package:
    // final response = await http.get('https://api.example.com/deals');
    // Parse the response and return the list of deals
    // return List<Deal>.from(response.data.map((dealData) => Deal(
    //   title: dealData['title'],
    //   description: dealData['description'],
    // )));
    // For this example

, we will use a hardcoded list of deals.
    return [
      Deal(title: '50% Off Smartphones', description: 'Get 50% off on all smartphones. Limited time offer.'),
      Deal(title: 'Flash Sale on Laptops', description: 'Flash sale on laptops. Grab them before they sell out.'),
      Deal(title: 'Buy 1 Get 1 Free Headphones', description: 'Buy one pair of headphones and get another one for free.'),
    ];
  }
}

ViewModel:

class DealsViewModel extends ChangeNotifier {
  // ... existing code ...

  List<Deal> _deals = [];

  List<Deal> get deals => _deals;

  Future<void> fetchDeals() async {
    _deals = await _repository.getDeals();
    notifyListeners();
  }
}

View:

class DealsView extends StatelessWidget {
  final DealsViewModel viewModel;

  DealsView({required this.viewModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Deals and Discounts')),
      body: ListView.builder(
        itemCount: viewModel.deals.length,
        itemBuilder: (context, index) {
          final deal = viewModel.deals[index];
          return ListTile(
            title: Text(deal.title),
            subtitle: Text(deal.description),
          );
        },
      ),
    );
  }
}
PreviousDart Programming GuidanceNextE-Commerce Applications
📄