@@ -9,9 +9,11 @@ import {
99import { Button } from '@/components/ui/button' ;
1010import { Input } from '@/components/ui/input' ;
1111import { Label } from '@/components/ui/label' ;
12+ import { Select , SelectContent , SelectItem , SelectTrigger , SelectValue } from '@/components/ui/select' ;
1213import { ShoppingBag , ArrowRight } from 'lucide-react' ;
1314import { ShopifyPrivateAppDialog } from '@/components/ShopifyPrivateAppDialog' ;
14- import { supabase } from '@/integrations/supabase/client' ;
15+ import { useAuth } from '@/contexts/AuthContext' ;
16+ import { useCampaignData } from '@/hooks/useCampaignData' ;
1517import { toast } from '@/hooks/use-toast' ;
1618
1719interface ShopifyIntegrationDialogProps {
@@ -28,65 +30,36 @@ export const ShopifyIntegrationDialog: React.FC<ShopifyIntegrationDialogProps> =
2830 isLoading
2931} ) => {
3032 const [ shopName , setShopName ] = useState ( '' ) ;
33+ const [ selectedCampaignId , setSelectedCampaignId ] = useState ( '' ) ;
3134 const [ showPrivateAppDialog , setShowPrivateAppDialog ] = useState ( false ) ;
35+
36+ // Récupération des campagnes de l'utilisateur
37+ const { user, loading : authLoading } = useAuth ( ) ;
38+ const { campaigns, loading : campaignsLoading } = useCampaignData ( user ?. uid || null , authLoading ) ;
3239
3340 const handleSubmit = ( e : React . FormEvent ) => {
3441 e . preventDefault ( ) ;
35- if ( shopName . trim ( ) ) {
42+ if ( shopName . trim ( ) && selectedCampaignId ) {
3643 setShowPrivateAppDialog ( true ) ;
44+ } else if ( ! selectedCampaignId ) {
45+ toast ( {
46+ title : "Campagne requise" ,
47+ description : "Veuillez sélectionner une campagne avant de continuer" ,
48+ variant : "destructive"
49+ } ) ;
3750 }
3851 } ;
3952
4053 const handleClose = ( ) => {
4154 if ( ! isLoading ) {
4255 setShopName ( '' ) ;
56+ setSelectedCampaignId ( '' ) ;
4357 onOpenChange ( false ) ;
4458 }
4559 } ;
4660
47- const handleConnect = async ( accessToken : string , shopDomain : string ) => {
48- // Sauvegarder l'intégration via l'edge function
49- try {
50- const { data : { user } } = await supabase . auth . getUser ( ) ;
51- if ( ! user ) {
52- toast ( {
53- title : "Erreur" ,
54- description : "Vous devez être connecté" ,
55- variant : "destructive"
56- } ) ;
57- return ;
58- }
59-
60- const response = await supabase . functions . invoke ( 'shopify-private-app' , {
61- body : {
62- shopDomain,
63- accessToken,
64- campaignId : 'test-campaign-123' , // TODO: récupérer le vrai campaign ID
65- userId : user . id
66- }
67- } ) ;
68-
69- if ( response . error ) {
70- throw new Error ( response . error . message ) ;
71- }
72-
73- toast ( {
74- title : "Shopify connecté !" ,
75- description : `Boutique ${ response . data . shopInfo . name } connectée avec succès` ,
76- } ) ;
77-
78- setShowPrivateAppDialog ( false ) ;
79- handleClose ( ) ;
80-
81- } catch ( error ) {
82- console . error ( 'Erreur connexion Shopify:' , error ) ;
83- toast ( {
84- title : "Erreur" ,
85- description : error instanceof Error ? error . message : "Erreur lors de la connexion" ,
86- variant : "destructive"
87- } ) ;
88- }
89- } ;
61+ // Vérification si aucune campagne disponible
62+ const noCampaignsAvailable = ! campaignsLoading && campaigns . length === 0 ;
9063
9164 return (
9265 < >
@@ -106,22 +79,54 @@ export const ShopifyIntegrationDialog: React.FC<ShopifyIntegrationDialogProps> =
10679 </ div >
10780 </ DialogHeader >
10881
109- < form onSubmit = { handleSubmit } className = "space-y-4" >
110- < div className = "space-y-2" >
111- < Label htmlFor = "shopName" > Nom de votre boutique Shopify</ Label >
112- < Input
113- id = "shopName"
114- type = "text"
115- placeholder = "ma-boutique"
116- value = { shopName }
117- onChange = { ( e ) => setShopName ( e . target . value ) }
118- disabled = { isLoading }
119- className = "w-full"
120- />
121- < p className = "text-xs text-muted-foreground" >
122- Entrez uniquement le nom de votre boutique (sans .myshopify.com)
123- </ p >
82+ { noCampaignsAvailable ? (
83+ < div className = "text-center py-6 space-y-4" >
84+ < div className = "p-3 bg-orange-100 rounded-lg" >
85+ < h4 className = "font-medium text-orange-900 mb-2" > Aucune campagne disponible</ h4 >
86+ < p className = "text-sm text-orange-800" >
87+ Vous devez créer au moins une campagne avec un moyen de paiement configuré avant de pouvoir connecter Shopify.
88+ </ p >
89+ </ div >
90+ < Button variant = "outline" onClick = { handleClose } >
91+ Fermer
92+ </ Button >
12493 </ div >
94+ ) : (
95+ < form onSubmit = { handleSubmit } className = "space-y-4" >
96+ < div className = "space-y-2" >
97+ < Label htmlFor = "campaign" > Campagne à connecter</ Label >
98+ < Select value = { selectedCampaignId } onValueChange = { setSelectedCampaignId } >
99+ < SelectTrigger >
100+ < SelectValue placeholder = "Sélectionnez une campagne" />
101+ </ SelectTrigger >
102+ < SelectContent >
103+ { campaigns . map ( ( campaign ) => (
104+ < SelectItem key = { campaign . id } value = { campaign . id } >
105+ { campaign . name }
106+ </ SelectItem >
107+ ) ) }
108+ </ SelectContent >
109+ </ Select >
110+ < p className = "text-xs text-muted-foreground" >
111+ Cette boutique Shopify sera liée à la campagne sélectionnée
112+ </ p >
113+ </ div >
114+
115+ < div className = "space-y-2" >
116+ < Label htmlFor = "shopName" > Nom de votre boutique Shopify</ Label >
117+ < Input
118+ id = "shopName"
119+ type = "text"
120+ placeholder = "ma-boutique"
121+ value = { shopName }
122+ onChange = { ( e ) => setShopName ( e . target . value ) }
123+ disabled = { isLoading || campaignsLoading }
124+ className = "w-full"
125+ />
126+ < p className = "text-xs text-muted-foreground" >
127+ Entrez uniquement le nom de votre boutique (sans .myshopify.com)
128+ </ p >
129+ </ div >
125130
126131 < div className = "bg-green-50 p-4 rounded-lg space-y-2" >
127132 < h4 className = "font-medium text-green-900" > Nouvelle méthode simplifiée !</ h4 >
@@ -133,32 +138,34 @@ export const ShopifyIntegrationDialog: React.FC<ShopifyIntegrationDialogProps> =
133138 </ ul >
134139 </ div >
135140
136- < div className = "flex justify-between" >
137- < Button
138- type = "button"
139- variant = "outline"
140- onClick = { handleClose }
141- disabled = { isLoading }
142- >
143- Annuler
144- </ Button >
145- < Button
146- type = "submit"
147- disabled = { ! shopName . trim ( ) || isLoading }
148- className = "flex items-center space-x-2"
149- >
150- < ArrowRight className = "h-4 w-4" />
151- < span > Continuer</ span >
152- </ Button >
153- </ div >
154- </ form >
141+ < div className = "flex justify-between" >
142+ < Button
143+ type = "button"
144+ variant = "outline"
145+ onClick = { handleClose }
146+ disabled = { isLoading || campaignsLoading }
147+ >
148+ Annuler
149+ </ Button >
150+ < Button
151+ type = "submit"
152+ disabled = { ! shopName . trim ( ) || ! selectedCampaignId || isLoading || campaignsLoading }
153+ className = "flex items-center space-x-2"
154+ >
155+ < ArrowRight className = "h-4 w-4" />
156+ < span > Continuer</ span >
157+ </ Button >
158+ </ div >
159+ </ form >
160+ ) }
155161 </ DialogContent >
156162 </ Dialog >
157163
158164 < ShopifyPrivateAppDialog
159165 open = { showPrivateAppDialog }
160166 onOpenChange = { setShowPrivateAppDialog }
161167 shopName = { shopName }
168+ campaignId = { selectedCampaignId }
162169 onSuccess = { ( ) => {
163170 toast ( {
164171 title : "Configuration terminée !" ,
0 commit comments