ソースを参照

fix: Fix API paths and share link management for anonymous users

- Fix double /api prefix in SDK requests (use /images instead of /api/images)
- Fix ShareModal to use imageIdentifier fallback when shortCode is missing
- Enables proper short URL generation and deletion for anonymous uploads
Fszontagh 4 時間 前
コミット
88fc04cafc

+ 2 - 2
src/components/AnalyticsDashboard.tsx

@@ -34,14 +34,14 @@ export default function AnalyticsDashboard({ shortCode, onClose }: AnalyticsDash
     try {
       // Fetch image info, analytics, and share links in parallel using SDK
       const [imageResponse, analyticsResponse, links] = await Promise.all([
-        client.request<{ image_url: string; short_url?: string; path: string }>(`/api/images/${shortCode}`),
+        client.request<{ image_url: string; short_url?: string; path: string }>(`/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`),
+        }>(`/images/${shortCode}/analytics`),
         listShareLinks(client, shortCode),
       ]);
 

+ 9 - 6
src/components/ShareModal.tsx

@@ -26,18 +26,22 @@ export default function ShareModal({ isOpen, onClose, image }: ShareModalProps)
   const maxLinks = isAuthenticated ? 10 : 3;
   const expiryOptions = isAuthenticated ? SHARE_LINK_EXPIRY_OPTIONS : ANON_EXPIRY_OPTIONS;
 
+  // Use shortCode if available, otherwise use image.id as identifier
+  // This allows logged-in users (who don't have shortCodes) to create share links
+  const imageIdentifier = image.shortCode || image.id;
+
   const loadLinks = useCallback(async () => {
-    if (!image.shortCode) return;
+    if (!imageIdentifier) return;
     setIsLoading(true);
     try {
-      const data = await listShareLinks(client, image.shortCode);
+      const data = await listShareLinks(client, imageIdentifier);
       setLinks(data);
     } catch (err) {
       setError(err instanceof Error ? err.message : 'Failed to load links');
     } finally {
       setIsLoading(false);
     }
-  }, [image.shortCode, client]);
+  }, [imageIdentifier, client]);
 
   useEffect(() => {
     if (isOpen) {
@@ -46,12 +50,12 @@ export default function ShareModal({ isOpen, onClose, image }: ShareModalProps)
   }, [isOpen, loadLinks]);
 
   const handleCreateLink = async () => {
-    if (!image.shortCode) return;
+    if (!imageIdentifier) return;
     setIsCreating(true);
     setError(null);
     try {
       const sessionToken = getSessionToken();
-      await createShareLink(client, image.shortCode, expiresIn, sessionToken, image.id);
+      await createShareLink(client, imageIdentifier, expiresIn, sessionToken, image.id);
       await loadLinks();
     } catch (err) {
       setError(err instanceof Error ? err.message : 'Failed to create link');
@@ -61,7 +65,6 @@ export default function ShareModal({ isOpen, onClose, image }: ShareModalProps)
   };
 
   const handleRevokeLink = async (linkCode: string) => {
-    if (!image.shortCode) return;
     try {
       await revokeShareLink(client, linkCode);
       await loadLinks();

+ 3 - 3
src/hooks/useImages.ts

@@ -34,7 +34,7 @@ export function useImages(bucket: string = PUBLIC_BUCKET) {
       let imageMetadata: Record<string, { shortCode: string; shortUrl: string; downloadAllowed: boolean }> = {};
       try {
         const apiResponse = await client.request<{ items: Array<{ path: string; short_code: string; short_url: string; download_allowed: boolean }> }>(
-          '/api/images',
+          '/images',
           {
             headers: { 'X-Session-Token': sessionToken },
           }
@@ -117,7 +117,7 @@ export function useImages(bucket: string = PUBLIC_BUCKET) {
         if (!isAuthenticated) {
           const sessionToken = getSessionToken();
           const apiResponse = await client.request<{ short_code: string }>(
-            '/api/images',
+            '/images',
             {
               method: 'POST',
               headers: { 'X-Session-Token': sessionToken },
@@ -176,7 +176,7 @@ export function useImages(bucket: string = PUBLIC_BUCKET) {
         if (image.shortCode) {
           const sessionToken = getSessionToken();
           const apiResponse = await client.request(
-            `/api/images/${image.shortCode}`,
+            `/images/${image.shortCode}`,
             {
               method: 'DELETE',
               headers: { 'X-Session-Token': sessionToken },