Skip to content

Commit ba06730

Browse files
Fix tooltip clipping issues
1 parent 804e1de commit ba06730

File tree

4 files changed

+567
-5
lines changed

4 files changed

+567
-5
lines changed

functions/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { processStripeWebhook } from './processStripeWebhook';
55
import { validateTracking } from './validateTracking';
66
import { calculateCommissions } from './calculateCommissions';
77
import { antifraudCheck } from './antifraudCheck';
8+
import { wordpressConfig, shopifyInstall, generatePluginApiKey } from './pluginAPI';
89

910
// Initialize Firebase Admin
1011
admin.initializeApp();
@@ -15,5 +16,8 @@ export {
1516
processStripeWebhook,
1617
validateTracking,
1718
calculateCommissions,
18-
antifraudCheck
19+
antifraudCheck,
20+
wordpressConfig,
21+
shopifyInstall,
22+
generatePluginApiKey
1923
};

functions/src/pluginAPI.ts

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
import * as functions from 'firebase-functions';
2+
import * as admin from 'firebase-admin';
3+
import * as cors from 'cors';
4+
5+
const corsHandler = cors({ origin: true });
6+
7+
// Interface pour la configuration des plugins
8+
interface PluginConfig {
9+
pluginType: 'wordpress' | 'shopify';
10+
domain: string;
11+
apiKey?: string;
12+
campaignId: string;
13+
userId: string;
14+
settings: {
15+
autoInject?: boolean;
16+
trackingEnabled?: boolean;
17+
commissionRate?: number;
18+
};
19+
}
20+
21+
// Interface pour l'installation Shopify
22+
interface ShopifyInstall {
23+
shop: string;
24+
code: string;
25+
state: string;
26+
campaignId: string;
27+
}
28+
29+
// API pour la configuration WordPress
30+
export const wordpressConfig = functions.https.onRequest((request, response) => {
31+
corsHandler(request, response, async () => {
32+
if (request.method !== 'POST') {
33+
return response.status(405).json({ error: 'Method not allowed' });
34+
}
35+
36+
try {
37+
const config: PluginConfig = request.body;
38+
39+
// Validation
40+
if (!config.domain || !config.campaignId || !config.userId) {
41+
return response.status(400).json({ error: 'Missing required fields' });
42+
}
43+
44+
// Vérifier que la campagne existe et appartient à l'utilisateur
45+
const campaignDoc = await admin.firestore()
46+
.collection('campaigns')
47+
.doc(config.campaignId)
48+
.get();
49+
50+
if (!campaignDoc.exists || campaignDoc.data()?.userId !== config.userId) {
51+
return response.status(403).json({ error: 'Campaign not found or access denied' });
52+
}
53+
54+
// Stocker la configuration du plugin
55+
const pluginDoc = await admin.firestore()
56+
.collection('plugin_configs')
57+
.add({
58+
...config,
59+
pluginType: 'wordpress',
60+
createdAt: new Date(),
61+
updatedAt: new Date(),
62+
active: true
63+
});
64+
65+
// Générer le script de tracking personnalisé
66+
const trackingScript = generateWordPressTrackingScript(config.campaignId, config.domain);
67+
68+
response.json({
69+
success: true,
70+
pluginId: pluginDoc.id,
71+
trackingScript,
72+
message: 'WordPress plugin configured successfully'
73+
});
74+
75+
} catch (error) {
76+
console.error('WordPress config error:', error);
77+
response.status(500).json({ error: 'Internal server error' });
78+
}
79+
});
80+
});
81+
82+
// API pour l'installation Shopify
83+
export const shopifyInstall = functions.https.onRequest((request, response) => {
84+
corsHandler(request, response, async () => {
85+
if (request.method !== 'POST') {
86+
return response.status(405).json({ error: 'Method not allowed' });
87+
}
88+
89+
try {
90+
const installData: ShopifyInstall = request.body;
91+
92+
// Validation
93+
if (!installData.shop || !installData.code || !installData.campaignId) {
94+
return response.status(400).json({ error: 'Missing required fields' });
95+
}
96+
97+
// Échanger le code OAuth contre un access token (simulation)
98+
// En réalité, on ferait un appel à l'API Shopify
99+
const accessToken = 'simulated_access_token_' + Date.now();
100+
101+
// Stocker la configuration Shopify
102+
const shopifyDoc = await admin.firestore()
103+
.collection('plugin_configs')
104+
.add({
105+
pluginType: 'shopify',
106+
domain: installData.shop,
107+
campaignId: installData.campaignId,
108+
accessToken,
109+
createdAt: new Date(),
110+
updatedAt: new Date(),
111+
active: true,
112+
settings: {
113+
autoInject: true,
114+
trackingEnabled: true
115+
}
116+
});
117+
118+
response.json({
119+
success: true,
120+
pluginId: shopifyDoc.id,
121+
message: 'Shopify app installed successfully'
122+
});
123+
124+
} catch (error) {
125+
console.error('Shopify install error:', error);
126+
response.status(500).json({ error: 'Internal server error' });
127+
}
128+
});
129+
});
130+
131+
// API pour générer les clés API des plugins
132+
export const generatePluginApiKey = functions.https.onCall(async (data, context) => {
133+
if (!context.auth) {
134+
throw new functions.https.HttpsError('unauthenticated', 'User must be authenticated');
135+
}
136+
137+
const { campaignId } = data;
138+
139+
if (!campaignId) {
140+
throw new functions.https.HttpsError('invalid-argument', 'Campaign ID is required');
141+
}
142+
143+
// Vérifier que la campagne appartient à l'utilisateur
144+
const campaignDoc = await admin.firestore()
145+
.collection('campaigns')
146+
.doc(campaignId)
147+
.get();
148+
149+
if (!campaignDoc.exists || campaignDoc.data()?.userId !== context.auth.uid) {
150+
throw new functions.https.HttpsError('permission-denied', 'Campaign not found or access denied');
151+
}
152+
153+
// Générer une clé API unique
154+
const apiKey = 'rsp_' + Buffer.from(campaignId + '_' + Date.now()).toString('base64');
155+
156+
// Stocker la clé API
157+
await admin.firestore()
158+
.collection('plugin_api_keys')
159+
.doc(apiKey)
160+
.set({
161+
campaignId,
162+
userId: context.auth.uid,
163+
createdAt: new Date(),
164+
lastUsed: null,
165+
active: true
166+
});
167+
168+
return { apiKey };
169+
});
170+
171+
// Fonction utilitaire pour générer le script WordPress
172+
function generateWordPressTrackingScript(campaignId: string, domain: string): string {
173+
return `<?php
174+
// RefSpring Tracking Script for WordPress
175+
function refspring_add_tracking_script() {
176+
$campaign_id = '${campaignId}';
177+
$script_url = 'https://refspring.com/tracking.js';
178+
179+
echo '<script data-campaign="' . $campaign_id . '" src="' . $script_url . '"></script>';
180+
}
181+
add_action('wp_head', 'refspring_add_tracking_script');
182+
183+
// Hook pour WooCommerce conversions
184+
function refspring_woocommerce_conversion($order_id) {
185+
$order = wc_get_order($order_id);
186+
$total = $order->get_total();
187+
188+
echo '<script>
189+
if (window.RefSpring) {
190+
window.RefSpring.trackConversion(' . $total . ');
191+
}
192+
</script>';
193+
}
194+
add_action('woocommerce_thankyou', 'refspring_woocommerce_conversion');
195+
?>`;
196+
}

0 commit comments

Comments
 (0)