HydroNutrify_Ari_e41221567/lib/ui/shared/components
aryaziz22 250c4d1e50 upload project skripsi 2026-07-07 09:58:33 +07:00
..
README.md upload project skripsi 2026-07-07 09:58:33 +07:00
components.dart upload project skripsi 2026-07-07 09:58:33 +07:00
custom_appbar.dart upload project skripsi 2026-07-07 09:58:33 +07:00
custom_button.dart upload project skripsi 2026-07-07 09:58:33 +07:00
custom_card.dart upload project skripsi 2026-07-07 09:58:33 +07:00
custom_dialog.dart upload project skripsi 2026-07-07 09:58:33 +07:00
custom_switch.dart upload project skripsi 2026-07-07 09:58:33 +07:00
custom_textfield.dart upload project skripsi 2026-07-07 09:58:33 +07:00
empty_state.dart upload project skripsi 2026-07-07 09:58:33 +07:00
error_widget.dart upload project skripsi 2026-07-07 09:58:33 +07:00
loading_indicator.dart upload project skripsi 2026-07-07 09:58:33 +07:00
section_header.dart upload project skripsi 2026-07-07 09:58:33 +07:00
status_badge.dart upload project skripsi 2026-07-07 09:58:33 +07:00

README.md

UI Components Library

Koleksi komponen UI yang reusable untuk aplikasi HydroNutrify.

📁 Struktur

ui/shared/components/
├── custom_button.dart          # Button components
├── custom_textfield.dart       # Text input components
├── custom_card.dart            # Card & container components
├── custom_dialog.dart          # Dialog & bottom sheet
├── custom_switch.dart          # Switch, checkbox, radio
├── custom_appbar.dart          # AppBar components
├── loading_indicator.dart      # Loading states
├── empty_state.dart            # Empty states
├── error_widget.dart           # Error handling
├── status_badge.dart           # Status & notification badges
├── section_header.dart         # Section headers & dividers
└── components.dart             # Barrel export file

🎨 Komponen

1. CustomButton

Button dengan berbagai jenis dan ukuran.

// Primary Button
CustomButton(
  text: 'Login',
  onPressed: () {},
  isLoading: false,
  type: ButtonType.primary,
  size: ButtonSize.medium,
)

// Secondary Button with Icon
CustomButton(
  text: 'Save',
  icon: Icons.save,
  type: ButtonType.secondary,
  onPressed: () {},
)

// Danger Button
CustomButton(
  text: 'Delete',
  type: ButtonType.danger,
  onPressed: () {},
)

ButtonType: primary, secondary, text, danger
ButtonSize: small, medium, large


2. CustomTextField

Text input field dengan fitur lengkap.

CustomTextField(
  controller: emailController,
  labelText: 'Email',
  hintText: 'Enter your email',
  prefixIcon: Icons.email,
  keyboardType: TextInputType.emailAddress,
  validator: (value) => value?.isEmpty == true ? 'Required' : null,
)

// Password Field dengan toggle
CustomTextField(
  controller: passwordController,
  labelText: 'Password',
  obscureText: true,
  showPasswordToggle: true,
  prefixIcon: Icons.lock,
)

3. CustomCard

Card container yang fleksibel.

// Basic Card
CustomCard(
  child: Text('Content'),
  padding: EdgeInsets.all(16),
  elevation: 2,
)

// Stat Card
StatCard(
  title: 'Total Users',
  value: '1,234',
  subtitle: '+12% from last month',
  icon: Icons.people,
  iconColor: AppColors.primary,
)

// Info Card
InfoCard(
  title: 'Update Available',
  description: 'Version 2.0 is ready to install',
  icon: Icons.system_update,
)

4. LoadingIndicator

Loading states dengan berbagai variasi.

// Simple Loading
LoadingIndicator(
  size: 40,
  message: 'Loading...',
)

// Overlay Loading
OverlayLoading(
  message: 'Processing...',
)

// Shimmer Loading
ShimmerLoading(
  width: 200,
  height: 20,
  borderRadius: BorderRadius.circular(8),
)

// Linear Progress
CustomLinearProgress(
  value: 0.6,
  height: 4,
)

5. EmptyState

Widget untuk menampilkan empty state.

// Custom Empty State
EmptyState(
  title: 'No Data Found',
  message: 'Try adding some items first',
  icon: Icons.inbox_outlined,
  actionText: 'Add Item',
  onAction: () {},
)

// No Data Widget
NoDataWidget(
  message: 'No records available',
)

// No Connection Widget
NoConnectionWidget(
  onRetry: () {},
)

6. CustomErrorWidget

Error handling dan display.

// Error Widget
CustomErrorWidget(
  title: 'Something went wrong',
  message: 'Please try again later',
  type: ErrorType.general,
  actionText: 'Retry',
  onAction: () {},
)

// Error Snackbar
ErrorSnackbar.show(
  context,
  'Failed to load data',
  type: ErrorType.network,
)

// Success Snackbar
SuccessSnackbar.show(
  context,
  'Data saved successfully',
)

ErrorType: general, network, notFound, permission, timeout


7. CustomDialog

Dialog dan bottom sheet.

// Confirmation Dialog
final result = await CustomDialog.showConfirmation(
  context: context,
  title: 'Delete Item',
  message: 'Are you sure?',
  confirmText: 'Delete',
  isDangerous: true,
);

// Info Dialog
await CustomDialog.showInfo(
  context: context,
  title: 'Information',
  message: 'Operation completed successfully',
);

// Loading Dialog
CustomDialog.showLoading(context, message: 'Saving...');
Navigator.pop(context); // Close when done

// Bottom Sheet
await CustomBottomSheet.show(
  context: context,
  title: 'Select Option',
  child: YourWidget(),
  height: 300,
);

8. Form Controls

Switch, checkbox, dan radio buttons.

// Custom Switch
CustomSwitch(
  value: isEnabled,
  onChanged: (value) {},
)

// Labeled Switch
LabeledSwitch(
  label: 'Enable Notifications',
  description: 'Receive updates and alerts',
  value: isEnabled,
  icon: Icons.notifications,
  onChanged: (value) {},
)

// Labeled Checkbox
LabeledCheckbox(
  label: 'I agree to terms',
  value: isAgreed,
  onChanged: (value) {},
)

// Labeled Radio
LabeledRadio<String>(
  label: 'Option 1',
  value: 'option1',
  initialGroupValue: selectedOption,
  onChanged: (value) {},
)

9. StatusBadge

Status dan notification badges.

// Success Badge
StatusBadge.success('Active')

// Warning Badge
StatusBadge.warning('Pending')

// Error Badge
StatusBadge.error('Failed')

// Info Badge
StatusBadge.info('New')

// Notification Badge
NotificationBadge(count: 5)

// Dot Badge
DotBadge(color: AppColors.error)

BadgeSize: small, medium, large


10. SectionHeader

Headers untuk section.

// Section Header
SectionHeader(
  title: 'Recent Activity',
  subtitle: 'Last 7 days',
  trailingText: 'See All',
  onTrailingTap: () {},
  showDivider: true,
)

// Simple Section Header
SimpleSectionHeader(
  title: 'Personal Information',
)

// Icon Section Header
IconSectionHeader(
  title: 'Settings',
  icon: Icons.settings,
  onTap: () {},
)

// Divider with Text
DividerWithText(text: 'OR')

11. CustomAppBar

AppBar components.

// Custom AppBar
CustomAppBar(
  title: 'Home',
  actions: [
    IconButton(
      icon: Icon(Icons.search),
      onPressed: () {},
    ),
  ],
)

// Custom Tab Bar
CustomTabBar(
  tabs: [
    Tab(text: 'Tab 1'),
    Tab(text: 'Tab 2'),
  ],
)

// Sliver AppBar
CustomSliverAppBar(
  title: 'Profile',
  expandedHeight: 200,
  flexibleSpace: YourWidget(),
)

📦 Cara Penggunaan

Import dari barrel file untuk menggunakan semua komponen:

import 'package:mobile_monitoring/ui/shared/components/components.dart';

Atau import spesifik:

import 'package:mobile_monitoring/ui/shared/components/custom_button.dart';
import 'package:mobile_monitoring/ui/shared/components/custom_textfield.dart';

🎯 Keuntungan

Konsisten - Semua komponen menggunakan theme dan colors yang sama
Reusable - Mudah digunakan di seluruh aplikasi
Maintainable - Update sekali, berpengaruh di semua tempat
Customizable - Banyak parameter untuk customisasi
Type-safe - Menggunakan enums untuk parameter


🔧 Refactoring yang Sudah Dilakukan

  1. login_form.dart - Menggunakan CustomTextField, CustomButton, CustomCard
  2. register_form.dart - Menggunakan CustomTextField, CustomButton, CustomCard

📝 Todo

  • Refactor file-file lain untuk menggunakan komponen baru
  • Tambah animasi pada komponen
  • Tambah dark mode support
  • Tambah accessibility features