Răsfoiți Sursa

refactor: Use SDK request method for all API calls

- Replace direct fetch() calls with client.request() in useImages.ts
- Update AnalyticsDashboard to use SDK for image info and analytics
- SDK handles auth headers automatically
- Consistent API pattern throughout the demo
Fszontagh 10 ore în urmă
părinte
comite
231b5a0549
2 a modificat fișierele cu 54 adăugiri și 70 ștergeri
  1. 16 17
      src/components/AnalyticsDashboard.tsx
  2. 38 53
      src/hooks/useImages.ts

+ 16 - 17
src/components/AnalyticsDashboard.tsx

@@ -32,25 +32,25 @@ export default function AnalyticsDashboard({ shortCode, onClose }: AnalyticsDash
     setError(null);
 
     try {
-      const token = client.accessToken;
-      const headers = {
-        'Authorization': token ? `Bearer ${token}` : '',
-      };
-
-      // Fetch image info, analytics, and share links in parallel
+      // Fetch image info, analytics, and share links in parallel using SDK
       const [imageResponse, analyticsResponse, links] = await Promise.all([
-        fetch(`/api/images/${shortCode}`, { headers }),
-        fetch(`/api/images/${shortCode}/analytics`, { headers }),
+        client.request<{ image_url: string; short_url?: string; path: string }>(`/api/images/${shortCode}`),
+        client.request<{
+          total_views: number;
+          unique_visitors: number;
+          proxy_views_count: number;
+          views_by_referrer: Record<string, number>;
+          recent_views: Array<Record<string, unknown>>;
+        }>(`/api/images/${shortCode}/analytics`),
         listShareLinks(client, shortCode),
       ]);
 
       // Handle image info
-      if (imageResponse.ok) {
-        const imgData = await imageResponse.json();
+      if (!imageResponse.error && imageResponse.data) {
         setImageInfo({
-          imageUrl: imgData.image_url,
-          shortUrl: imgData.short_url || `/i/${shortCode}`,
-          path: imgData.path,
+          imageUrl: imageResponse.data.image_url,
+          shortUrl: imageResponse.data.short_url || `/i/${shortCode}`,
+          path: imageResponse.data.path,
         });
       }
 
@@ -58,12 +58,11 @@ export default function AnalyticsDashboard({ shortCode, onClose }: AnalyticsDash
       setShareLinks(links);
 
       // Handle analytics
-      if (!analyticsResponse.ok) {
-        const errorData = await analyticsResponse.json().catch(() => ({}));
-        throw new Error(errorData.error || 'Failed to load analytics');
+      if (analyticsResponse.error || !analyticsResponse.data) {
+        throw new Error(analyticsResponse.error?.message || 'Failed to load analytics');
       }
 
-      const data = await analyticsResponse.json();
+      const data = analyticsResponse.data;
       setAnalytics({
         totalViews: data.total_views,
         uniqueVisitors: data.unique_visitors,

+ 38 - 53
src/hooks/useImages.ts

@@ -28,23 +28,20 @@ export function useImages(bucket: string = PUBLIC_BUCKET) {
 
       if (listError) throw listError;
 
-      // Also fetch from image API to get shortCodes
+      // Also fetch from image API to get shortCodes using SDK's request method
       const sessionToken = getSessionToken();
-      const headers: Record<string, string> = {
-        'X-Session-Token': sessionToken,
-      };
-      const accessToken = client.accessToken;
-      if (accessToken) {
-        headers['Authorization'] = `Bearer ${accessToken}`;
-      }
 
       let imageMetadata: Record<string, { shortCode: string; shortUrl: string; downloadAllowed: boolean }> = {};
       try {
-        const apiResponse = await fetch('/api/images', { headers });
-        if (apiResponse.ok) {
-          const apiData = await apiResponse.json();
+        const apiResponse = await client.request<{ items: Array<{ path: string; short_code: string; short_url: string; download_allowed: boolean }> }>(
+          '/api/images',
+          {
+            headers: { 'X-Session-Token': sessionToken },
+          }
+        );
+        if (!apiResponse.error && apiResponse.data) {
           // Create a lookup by path
-          for (const img of apiData.items || []) {
+          for (const img of apiResponse.data.items || []) {
             imageMetadata[img.path] = {
               shortCode: img.short_code,
               shortUrl: img.short_url,
@@ -112,35 +109,28 @@ export function useImages(bucket: string = PUBLIC_BUCKET) {
 
         if (uploadError) throw uploadError;
 
-        // Register with image API for short URL and tracking
+        // Register with image API for short URL and tracking using SDK
         const sessionToken = getSessionToken();
-        const headers: Record<string, string> = {
-          'Content-Type': 'application/json',
-          'X-Session-Token': sessionToken,
-        };
-        // Include auth token if logged in
-        const accessToken = client.accessToken;
-        if (accessToken) {
-          headers['Authorization'] = `Bearer ${accessToken}`;
-        }
-        const apiResponse = await fetch('/api/images', {
-          method: 'POST',
-          headers,
-          body: JSON.stringify({
-            bucket,
-            path,
-            storage_object_id: data?.id,
-            download_allowed: options.downloadAllowed,
-            expires_at: expiresAt,
-          }),
-        });
+        const apiResponse = await client.request<{ short_code: string }>(
+          '/api/images',
+          {
+            method: 'POST',
+            headers: { 'X-Session-Token': sessionToken },
+            body: JSON.stringify({
+              bucket,
+              path,
+              storage_object_id: data?.id,
+              download_allowed: options.downloadAllowed,
+              expires_at: expiresAt,
+            }),
+          }
+        );
 
         let shortCode: string | undefined;
         let shortUrl: string | undefined;
 
-        if (apiResponse.ok) {
-          const imageData = await apiResponse.json();
-          shortCode = imageData.short_code;
+        if (!apiResponse.error && apiResponse.data) {
+          shortCode = apiResponse.data.short_code;
           shortUrl = `/i/${shortCode}`;
 
           // Track anonymous uploads for deletion capability
@@ -148,7 +138,7 @@ export function useImages(bucket: string = PUBLIC_BUCKET) {
             trackUpload(shortCode);
           }
         } else {
-          console.warn('Failed to register image with API:', await apiResponse.text());
+          console.warn('Failed to register image with API:', apiResponse.error);
         }
 
         const newImage: ImageFile = {
@@ -181,24 +171,19 @@ export function useImages(bucket: string = PUBLIC_BUCKET) {
   const deleteImage = useCallback(
     async (image: ImageFile): Promise<void> => {
       try {
-        // If we have a short code, delete via the image API (handles session auth)
+        // If we have a short code, delete via the image API using SDK
         if (image.shortCode) {
           const sessionToken = getSessionToken();
-          const headers: Record<string, string> = {
-            'X-Session-Token': sessionToken,
-          };
-          const accessToken = client.accessToken;
-          if (accessToken) {
-            headers['Authorization'] = `Bearer ${accessToken}`;
-          }
-          const apiResponse = await fetch(`/api/images/${image.shortCode}`, {
-            method: 'DELETE',
-            headers,
-          });
-
-          if (!apiResponse.ok) {
-            const errorData = await apiResponse.json().catch(() => ({}));
-            throw new Error(errorData.error || 'Delete failed');
+          const apiResponse = await client.request(
+            `/api/images/${image.shortCode}`,
+            {
+              method: 'DELETE',
+              headers: { 'X-Session-Token': sessionToken },
+            }
+          );
+
+          if (apiResponse.error) {
+            throw new Error(apiResponse.error.message || 'Delete failed');
           }
 
           // Remove from session tracking