diff --git a/pages/admin.tsx b/pages/admin.tsx index 9c3a899..3e4e2d5 100644 --- a/pages/admin.tsx +++ b/pages/admin.tsx @@ -5,10 +5,109 @@ import useSWR from "swr"; import { convertDate } from "@/utils/mapping"; import Image from "next/image"; +import { createErrorToast, createSuccessToast } from '@/components/Toast'; import { motion } from "framer-motion"; +import { useToast } from '@chakra-ui/react'; import { Spinner } from "@chakra-ui/react"; import LoadingSpinner from "@/components/LoadingSpinner"; +const fetcher = (url: string) => fetch(url).then((res) => res.json()); + import { BsTrash3, BsYoutube } from "react-icons/bs"; + const toast = useToast(); + const { data: photosData, error: photosError, mutate: mutatePhotos } = useSWR('/api/photos/get-cloudinary-photos', fetcher); + const [newFolderName, setNewFolderName] = useState(''); + const [selectedFolder, setSelectedFolder] = useState(''); + const [photoFile, setPhotoFile] = useState(null); + + const handleCreateFolder = async () => { + try { + await fetch('/api/photos/create-folder', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ folderName: newFolderName }) + }); + createSuccessToast(toast, 'Folder created successfully'); + mutatePhotos(); + } catch (error) { + createErrorToast(toast, 'Failed to create folder'); + } + }; + + const handlePhotoUpload = async () => { + const reader = new FileReader(); + reader.onloadend = async () => { + try { + await fetch('/api/photos/upload-photo', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ folderName: selectedFolder, file: reader.result }) + }); + createSuccessToast(toast, 'Photo uploaded successfully'); + mutatePhotos(); + } catch (error) { + createErrorToast(toast, 'Failed to upload photo'); + } + }; + if (photoFile) { + reader.readAsDataURL(photoFile); + } + }; + + if (photosError) { + return
Failed to load photos.
; + } + + return ( +
+
+

Manage Cloudinary Photos

+ {photosData ? ( +
+

Folders:

+
    + {photosData.folders.map((folder: any) => ( +
  • {folder.name}
  • + ))} +
+

Images:

+
    + {photosData.images.map((image: any) => ( +
  • + {image.public_id} +
  • + ))} +
+
+ ) : ( +
Loading...
+ )} +
+ setNewFolderName(e.target.value)} + placeholder="New Folder Name" + /> + +
+
+ setPhotoFile(e.target.files?.[0] || null)} /> + + +
+
+
+ ); + import DatePicker from "react-datepicker"; diff --git a/pages/api/photos/create-folder.ts b/pages/api/photos/create-folder.ts new file mode 100644 index 0000000..9939ee7 --- /dev/null +++ b/pages/api/photos/create-folder.ts @@ -0,0 +1,18 @@ +import { v2 as cloudinary } from 'cloudinary'; +import type { NextApiRequest, NextApiResponse } from 'next'; + +cloudinary.config({ + cloud_name: process.env.CLOUDINARY_CLOUD_NAME, + api_key: process.env.CLOUDINARY_API_KEY, + api_secret: process.env.CLOUDINARY_API_SECRET, +}); + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const { folderName } = req.body; + try { + await cloudinary.api.create_folder(folderName); + res.status(201).json({ message: 'Folder created successfully' }); + } catch (error) { + res.status(500).json({ error: 'Failed to create folder in Cloudinary' }); + } +} \ No newline at end of file diff --git a/pages/api/photos/upload-photo.ts b/pages/api/photos/upload-photo.ts new file mode 100644 index 0000000..47cde09 --- /dev/null +++ b/pages/api/photos/upload-photo.ts @@ -0,0 +1,20 @@ +import { v2 as cloudinary } from 'cloudinary'; +import type { NextApiRequest, NextApiResponse } from 'next'; + +cloudinary.config({ + cloud_name: process.env.CLOUDINARY_CLOUD_NAME, + api_key: process.env.CLOUDINARY_API_KEY, + api_secret: process.env.CLOUDINARY_API_SECRET, +}); + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const { folderName, file } = req.body; + try { + const uploadResponse = await cloudinary.uploader.upload(file, { + folder: folderName + }); + res.status(201).json({ imageUrl: uploadResponse.secure_url }); + } catch (error) { + res.status(500).json({ error: 'Failed to upload photo to Cloudinary' }); + } +} \ No newline at end of file