lors de la création d'une annonce nous ne prenons pas en compte la catégory de l'annonce, maintenant je veux que ce soit le cas, nous devons utilise BuildTypeAnnoncesDistant  et selectionner la catégory voulu depuis une combobox: import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

import 'package:sae_mobile/models/User.dart' as user_model;
import 'package:sae_mobile/models/Builder.dart' as builder_model;

import 'package:sae_mobile/models/queries/local/annonce.dart' as aq;

final SupabaseClient supabaseClient = Supabase.instance.client;

class CreateAnnonce extends StatefulWidget {
  const CreateAnnonce({Key? key}) : super(key: key);

  @override
  State<CreateAnnonce> createState() => _CreateAnnonceState();
}

class _CreateAnnonceState extends State<CreateAnnonce> {
  final TextEditingController _titleController = TextEditingController();
  final TextEditingController _descriptionController = TextEditingController();
  final TextEditingController _dateDebController = TextEditingController();
  final TextEditingController _dateFinController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Create Annonce'),
        TextField(
          controller: _titleController,
          decoration: const InputDecoration(labelText: 'Title'),
        ),
        TextField(
          controller: _descriptionController,
          decoration: const InputDecoration(labelText: 'Description'),
        ),
        TextField(
            controller: _dateDebController,
            decoration: const InputDecoration(
                icon: Icon(Icons.calendar_today), labelText: "Enter Date"),
            readOnly: true,
            onTap: () async {
              DateTime? date = await showDatePicker(
                context: context,
                initialDate: DateTime.now(),
                firstDate: DateTime(2000),
                lastDate: DateTime(2100),
              );
              if (date != null) {
                _dateDebController.text = date.toString();
              }
            }),
        TextField(
            controller: _dateFinController,
            decoration: const InputDecoration(
                icon: Icon(Icons.calendar_today), labelText: "Enter Date"),
            readOnly: true,
            onTap: () async {
              DateTime? date = await showDatePicker(
                context: context,
                initialDate: DateTime.now(),
                firstDate: DateTime(2000),
                lastDate: DateTime(2100),
              );
              if (date != null) {
                _dateFinController.text = date.toString();
              }
            }),
        FutureBuilder(
          future: builder_model.Builder.buildUserById(
              supabaseClient.auth.currentUser!.id),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const CircularProgressIndicator();
            }
            if (snapshot.hasError) {
              return Text('Error: ${snapshot.error}');
            }
            final user = snapshot.data as user_model.User;

            return ElevatedButton(
              onPressed: () async {
                await aq.AnnonceQueries.createAnnonce(
                  user.id,
                  _titleController.text,
                  _descriptionController.text,
                  DateTime.parse(_dateDebController.text),
                  DateTime.parse(_dateFinController.text),
                  1,
                  1,
                  1,
                );

                Navigator.pushNamed(context, '/category');
              },
              child: Text('Create Annonce'),
            );
          },
        ),
      ],
    );
  }
}
import 'package:sae_mobile/models/Objet.dart';
import 'package:sae_mobile/models/TypeAnnonce.dart';
import 'package:sae_mobile/models/annonce.dart';
import 'package:sae_mobile/models/queries/distant/user.dart' as uqd;
import 'package:sae_mobile/models/queries/distant/annonce.dart' as aqd;

import 'package:sae_mobile/models/queries/local/annonce.dart' as aql;
import 'package:sae_mobile/models/queries/local/objet.dart';
import 'package:sae_mobile/models/queries/local/typeAnnonce.dart';

import 'package:sae_mobile/models/User.dart' as user_model;

import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:sae_mobile/models/queries/distant/typeAnnonce.dart' as tqd;

final SupabaseClient supabaseClient = Supabase.instance.client;

/// Classe Builder
///
/// Cette classe permet de construire des objets à partir de données distantes ou locales.
class Builder {
  /// Construit un utilisateur à partir de son id.
  ///
  /// [id] est l'id de l'utilisateur.
  ///
  /// Retourne un objet de type [user_model.User].
  static Future<user_model.User> buildUserById(String id) async {
    final data =
        await uqd.UserQueries.getUserById(id).then((value) => value.first);

    return user_model.User.fromJson(data);
  }

  /// Construit une liste d'annonces à partir de données distantes.
  ///
  /// Retourne une liste d'annonces.
  static Future<List<Annonce>> buildAnnoncesDistant() async {
    final data = await aqd.AnnonceQueries.getAnnonces().then((value) => value);

    List<Annonce> annonces = [];
    for (var annonce in data) {
      String user_id = await aqd.AnnonceQueries.getAuteurAnnonce(annonce['id']);
      annonces.add(Annonce.fromJson(annonce, (await buildUserById(user_id))));
    }

    return annonces;
  }

  static Future<List<Annonce>> buildAnnoncesDistantByType(String type) async {
    final data =
        await aqd.AnnonceQueries.getAnnoncesByType(type).then((value) => value);

    List<Annonce> annonces = [];
    for (var annonce in data) {
      print("les annonces du type $type sont : $annonce");
      String user_id = await aqd.AnnonceQueries.getAuteurAnnonce(annonce['id']);
      annonces.add(Annonce.fromJson(annonce, (await buildUserById(user_id))));
    }

    return annonces;
  }

  /// Construit une liste d'annonces non répondues à partir de données distantes.
  ///
  /// Retourne une liste d'annonces.
  static Future<List<Annonce>> buildAnnoncesDistantNonRepondu() async {
    final data =
        await aqd.AnnonceQueries.getAnnonceNonRepondu().then((value) => value);

    List<Annonce> annonces = [];
    for (var annonce in data) {
      String user_id = await aqd.AnnonceQueries.getAuteurAnnonce(annonce['id']);
      annonces.add(Annonce.fromJson(annonce, (await buildUserById(user_id))));
    }

    return annonces;
  }

  /// Construit une liste d'annonces répondues par l'utilisateur à partir de données distantes.
  ///
  /// [id] est l'id de l'utilisateur.
  ///
  /// Retourne une liste d'annonces.
  static Future<List<Annonce>> buildAnnoncesDistantRepondu(String id) async {
    print("L'id de l'utilisateur est annonce distant repondu : $id");
    final data =
        await aqd.AnnonceQueries.getAnnonceRepondu(id).then((value) => value);

    List<Annonce> annonces = [];
    for (var annonce in data) {
      String user_id = await aqd.AnnonceQueries.getAuteurAnnonce(annonce['id']);
      annonces.add(Annonce.fromJson(annonce, (await buildUserById(user_id))));
    }
    print("Les annonces répondues : $annonces");
    return annonces;
  }

  static Future<List<Annonce>> buildAnnoncesLocalUtilisateur(String id) async {
    final data = await aql.AnnonceQueries.getAnnoncesByUser(id);

    List<Annonce> annonces = [];
    for (var annonce in data) {
      annonces.add(Annonce.fromJson(annonce, await buildUserById(id)));
    }
    print("Les annonces locales : $annonces");
    return annonces;
  }

  /// Construit une liste d'annonces par id de l'annonce à partir de données distantes.
  ///
  /// [id] est l'id de l'annonce.
  ///
  /// Retourne une liste d'annonces.
  static Future<Annonce> buildAnnonceByIdDistant(String id) async {
    final data = await aqd.AnnonceQueries.getAnnonceById(id)
        .then((value) => value.first);

    String user_id = await aqd.AnnonceQueries.getAnnonceById(data['id'])
        .then((value) => value.first['id_user']);
    return Annonce.fromJson(data, await buildUserById(user_id));
  }

  /// Construit une liste d'annonces à partir de données locales.
  static Future<List<Annonce>> buildAnnoncesLocal() async {
    final data = await aql.AnnonceQueries.getAnnonces().then((value) => value);
    List<Annonce> annonces = [];
    print(data);
    for (var annonce in data) {
      annonces.add(Annonce.fromJson(
          annonce, await buildUserById(supabaseClient.auth.currentUser!.id)));
    }

    return annonces;
  }

  /// Construit une liste d'annonces par id de l'annonce à partir de données locales.
  static Future<Annonce> buildAnnonceByIdLocal(String id) async {
    final data = await aql.AnnonceQueries.getAnnonceById(id);

    return Annonce.fromJson(
        data, await buildUserById(supabaseClient.auth.currentUser!.id));
  }

  /// Construit une liste d'objets à partir de données locales.
  ///
  /// Retourne une liste d'objets.
  static Future<List<Objet>> buildObjets() async {
    final data = await ObjetQueries.getObjets().then((value) => value);

    List<Objet> objets = [];
    for (var objet in data) {
      objets.add(Objet.fromJson(objet));
    }

    return objets;
  }

  /// Construit une liste de types d'annonces à partir de données locales.
  ///
  /// Retourne une liste de types d'annonces.
  static Future<List<TypeAnnonce>> buildTypesAnnonce() async {
    final data =
        await TypeAnnoncesQueries.getTypeAnnonces().then((value) => value);

    List<TypeAnnonce> typesAnnonce = [];
    for (var typeAnnonce in data) {
      print('la categorie est : $typeAnnonce');
      typesAnnonce.add(TypeAnnonce.fromJson(typeAnnonce));
    }

    return typesAnnonce;
  }

  static Future<List<TypeAnnonce>> buildTypesAnnonceDistant() async {
    final data =
        await tqd.TypeAnnonceQueries.getTypeAnnonces().then((value) => value);

    List<TypeAnnonce> typesAnnonce = [];
    for (var typeAnnonce in data) {
      print(typeAnnonce);
      typesAnnonce.add(TypeAnnonce.fromJson(typeAnnonce));
    }

    return typesAnnonce;
  }
}
import 'package:sae_mobile/models/annonce.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

final SupabaseClient supabaseClient = Supabase.instance.client;

class AnnonceQueries {
  static Future<String> publishAnnonce(Annonce annonce) async {
    print("publishAnnonce");
    print(annonce.dateDeb.toIso8601String());
    print(annonce.dateFin.toIso8601String());
    print(annonce.titre);
    PostgrestList result = await supabaseClient.from('ANNONCES').insert({
      'titre': annonce.titre,
      'description': annonce.description,
      'dateDeb': annonce.dateDeb.toIso8601String(),
      'dateFin': annonce.dateFin.toIso8601String(),
      'idType': 1,
      'idEtat': 2,
    }).select('id');
    print("result");

    if (result.isEmpty) {
      throw Exception('Failed to create annonce');
    }

    String id = result[0]['id'];

    await supabaseClient.from('PUBLIE').insert({
      'id_a': id,
      'id_user': annonce.auteur.id,
    });

    return id;
  }


  static Future<void> updateAnnonceEtat(String id, int etat) async {
    await supabaseClient.from('ANNONCES').update({'idEtat': etat}).eq('id', id);
  }

  static Future<void> mettreAvis(String id_a, String id_u, String avis) async {
    await supabaseClient.from('AVIS').insert({
      'id_a': id_a,
      'id_user': id_u,
      'avis': avis,
    });
  }

  static Future<PostgrestList> getAnnonceAvis(String id_a) async {
    final response =
        await supabaseClient.from('AVIS').select().eq('id_a', id_a);
    if (response.isEmpty) {
      throw Exception('Failed to get avis');
    }
    return response;
  }
}