حذف الملاحظة (Delete Note) عبر نفس الطبقات:
UI → Cubit → UseCase → Repository → DataSource → SupabaseDart🧱 1) DataSource (تنفيذ الحذف فعلياً)
📁 notes_remote_datasource.dart
import 'package:supabase_flutter/supabase_flutter.dart';
import '../models/note_model.dart';
class NotesRemoteDataSource {
final SupabaseClient client;
NotesRemoteDataSource(this.client);
/// 🔥 حذف ملاحظة عبر id
Future<void> deleteNote(String id) async {
/// eq = where id = ...
await client
.from('notes')
.delete()
.eq('id', id);
}
}Dart🧠 شرح
هذا المكان الوحيد اللي يحكي مع Supabase
delete + eq = حذف الصف حسب idDart🧱 2) Repository (تعريف العملية)
📁 notes_repository.dart
abstract class NotesRepository {
Future<void> deleteNote(String id);
}Dart🧠 شرح
Domain يقول: يوجد حذف
لكن لا يعرف كيف يتمDart🧱 3) RepositoryImpl (تنفيذ الربط)
📁 notes_repository_impl.dart
import '../../domain/repository/notes_repository.dart';
import '../datasource/notes_remote_datasource.dart';
class NotesRepositoryImpl implements NotesRepository {
final NotesRemoteDataSource remote;
NotesRepositoryImpl(this.remote);
@override
Future<void> deleteNote(String id) async {
await remote.deleteNote(id);
}
}Dart🧠 شرح
يمرر الطلب من domain إلى dataDart🧱 4) UseCase
📁 delete_note_usecase.dart
import '../repository/notes_repository.dart';
class DeleteNoteUseCase {
final NotesRepository repo;
DeleteNoteUseCase(this.repo);
/// call = استدعاء مباشر
Future<void> call(String id) async {
await repo.deleteNote(id);
}
}Dart🧠 شرح
يمثل "عملية الحذف"Dart🧱 5) Cubit
📁 notes_cubit.dart
✏️ أضف:
final DeleteNoteUseCase deleteNoteUseCase;Dart✏️ عدّل constructor:
NotesCubit(
this.getNotesUseCase,
this.addNoteUseCase,
this.deleteNoteUseCase,
) : super(NotesInitial());Dart✏️ أضف دالة الحذف:
Future<void> deleteNote(String id) async {
try {
await deleteNoteUseCase(id);
/// 👇 إشعار نجاح
emit(NoteDeleted());
/// تحديث البيانات
fetchNotes();
} catch (e) {
emit(NotesError(e.toString()));
}
}Dart🧠 شرح
Cubit ينفذ العملية + يرسل state للـ UIDart🧱 6) إضافة حالة جديدة
📁 notes_state.dart
class NoteDeleted extends NotesState {}Dart🧠 ليش؟
حتى نعرض SnackBarDart🧱 7) UI (زر الحذف)
📁 داخل NoteCard
IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
context.read<NotesCubit>().deleteNote(note.id);
},
),Dart🧠 ماذا يحدث؟
ضغط زر → Cubit → حذف → تحديثDart🧱 8) SnackBar
📁 notes_page.dart
BlocListener<NotesCubit, NotesState>(
listener: (context, state) {
if (state is NoteDeleted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("تم حذف الملاحظة"),
),
);
}
},
child: Scaffold(...),
);Dart💥 التسلسل الكامل
ضغط حذف
↓
Cubit.deleteNote()
↓
UseCase
↓
Repository
↓
DataSource
↓
Supabase
↓
emit(NoteDeleted)
↓
SnackBar
↓
fetchNotes()
↓
UI يتحدثDart⚠️ تحسين مهم (اختياري)
تأكيد قبل الحذف
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text("تأكيد"),
content: const Text("هل تريد حذف الملاحظة؟"),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text("إلغاء"),
),
TextButton(
onPressed: () {
context.read<NotesCubit>().deleteNote(note.id);
Navigator.pop(context);
},
child: const Text("حذف"),
),
],
),
);Dart🧠 خلاصة
Delete = id فقط
Cubit = ينفذ + يحدث
UI = يطلب + يعرضDart