diff --git a/apps/open-spark/components/deviceList/AddNewDerModal.tsx b/apps/open-spark/components/deviceList/AddNewDerModal.tsx new file mode 100644 index 00000000..5a8fc70d --- /dev/null +++ b/apps/open-spark/components/deviceList/AddNewDerModal.tsx @@ -0,0 +1,137 @@ +import React, { useState } from 'react' +import BottomModalScan from '@beckn-ui/common/src/components/BottomModal/BottomModalScan' +import { Input, Typography } from '@beckn-ui/molecules' +import BecknButton from '@beckn-ui/molecules/src/components/button' +import { Box, Flex, Image } from '@chakra-ui/react' +import uploadIcon from '@public/images/upload_icon.svg' +import pdfIcon from '@public/images/PDF.svg' +import DragAndDropUpload from '@components/dragAndDropUpload' +import RenderDocuments from '@components/documentsRenderer' + +interface Proofs { + id: number + name: string + date: string +} + +interface DocumentProps { + icon: string + title: string + file: any + date: Date +} + +interface AddNewDerModalProps { + isOpen: boolean + onClose: () => void + proofs: Proofs[] + handleDelete: (id: number) => void + handleFileUpload: (event: any) => void + onSubmit: (category: string, uploadedFiles: File[]) => Promise + isLoading?: boolean +} + +const AddNewDerModal = (props: AddNewDerModalProps) => { + const [category, setCategory] = useState('Lorem Ipsum Dior') + const [uploadedFiles, setUploadedFiles] = useState([]) + const [allFilesProcessed, setAllFilesProcessed] = useState(false) + + const { isOpen, onClose, onSubmit, isLoading } = props + + const handleFileChange = (files: File[]) => { + if (files.length > 0) { + const docs = files.map(file => { + console.log('Selected file:', file) + return { title: file?.name!, icon: pdfIcon, date: new Date(), file: file } + }) + setUploadedFiles(prevState => (prevState ? [...prevState, ...docs] : docs)) + } + } + + const handleAddDevice = () => { + if (!category || uploadedFiles.length === 0) { + alert('Please provide all details.') + return + } + const files = uploadedFiles.map(doc => doc.file) + onSubmit(category, files) + } + const handleOnDelete = (index: number, document: DocumentProps, type: 'cred' | 'upload') => { + if (type === 'cred') { + setUploadedFiles(prevState => prevState!.filter((_, i) => i !== index)) + } + } + + return ( + + + + setCategory(e.target.value)} + /> + + { + setAllFilesProcessed(status) + }} + /> + + { + return ( + { + if (fileInputRef.current) { + fileInputRef.current.click() + } + }} + > + upload + + + + ) + }} + /> + + + + + ) +} + +export default AddNewDerModal diff --git a/apps/open-spark/components/deviceList/DeleteDErModal.tsx b/apps/open-spark/components/deviceList/DeleteDErModal.tsx new file mode 100644 index 00000000..79bf1527 --- /dev/null +++ b/apps/open-spark/components/deviceList/DeleteDErModal.tsx @@ -0,0 +1,58 @@ +import BottomModalScan from '@beckn-ui/common/src/components/BottomModal/BottomModalScan' +import { Typography } from '@beckn-ui/molecules' +import BecknButton from '@beckn-ui/molecules/src/components/button' +import { Box, Flex } from '@chakra-ui/react' +import React from 'react' +interface DeleteDErModalProps { + isOpen: boolean + onClose: () => void + handleConfirmDeleteDevice: () => void + isLoading?: boolean +} + +const DeleteDErModal = (props: DeleteDErModalProps) => { + const { isOpen, onClose, handleConfirmDeleteDevice, isLoading } = props + return ( + + + + + + + + + + + ) +} + +export default DeleteDErModal diff --git a/apps/open-spark/components/deviceList/DeviceList.tsx b/apps/open-spark/components/deviceList/DeviceList.tsx index 1503d14a..8c21652b 100644 --- a/apps/open-spark/components/deviceList/DeviceList.tsx +++ b/apps/open-spark/components/deviceList/DeviceList.tsx @@ -1,11 +1,15 @@ -'use client' - import React, { useState, useEffect } from 'react' import { Box, VStack, IconButton, Container, Flex } from '@chakra-ui/react' import { BiPlusCircle } from 'react-icons/bi' -import { CiCirclePlus, CiCircleMinus } from 'react-icons/ci' -import BecknButton from '@beckn-ui/molecules/src/components/button/Button' +import { CiCircleMinus } from 'react-icons/ci' import { Typography } from '@beckn-ui/molecules' +import AddNewDerModal from './AddNewDerModal' +import DeleteDErModal from './DeleteDErModal' +import axios from 'axios' +import { ROLE, ROUTE_TYPE } from '@lib/config' +import { useSelector } from 'react-redux' +import { RootState } from '@store/index' +import Cookies from 'js-cookie' interface Device { name: string @@ -15,30 +19,109 @@ interface Device { interface DeviceListProps { initialDevices: Device[] initialNearbyDevices: Device[] - onDeviceChange: (devices: Device[], nearbyDevices: Device[]) => void + onDeviceChange: (devices: Device[]) => void + fetchPairedData: () => void } -export default function DeviceList({ initialDevices, initialNearbyDevices, onDeviceChange }: DeviceListProps) { +export default function DeviceList({ initialDevices, onDeviceChange, fetchPairedData }: DeviceListProps) { const [devices, setDevices] = useState(initialDevices) - const [nearbyDevices, setNearbyDevices] = useState(initialNearbyDevices) + const [isModalOpen, setIsModalOpen] = useState(false) + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false) + const [selectedDeviceIndex, setSelectedDeviceIndex] = useState(null) + const [isLoading, setIsLoading] = useState(false) + const [isDeleteLoading, setIsDeleteLoading] = useState(false) - useEffect(() => { - onDeviceChange(devices, nearbyDevices) - }, [devices, nearbyDevices, onDeviceChange]) + const strapiUrl = process.env.NEXT_PUBLIC_STRAPI_URL + const { role } = useSelector((state: RootState) => state.auth) + const bearerToken = Cookies.get('authToken') + + const handleAddDevice = async (category: string, uploadedFiles: File[]) => { + setIsLoading(true) + try { + const type = role === ROLE.PRODUCER ? 'PRODUCER' : 'CONSUMER' + const formData = new FormData() + + formData.append('type', type) + formData.append('category', category) + uploadedFiles.forEach(file => formData.append('proofs', file)) + + const response = await axios.post(`${strapiUrl}${ROUTE_TYPE[role!]}/der`, formData, { + headers: { Authorization: `Bearer ${bearerToken}` }, + withCredentials: true + }) - const handleRemoveDevice = (index: number) => { - const newDevices = devices.filter((_, i) => i !== index) - setDevices(newDevices) + if (role === ROLE.PRODUCER) { + setDevices(response.data.production) + setIsLoading(false) + } else if (role === ROLE.CONSUMER) { + setDevices(response.data.consumption) + setIsLoading(false) + } + + fetchPairedData() + setIsModalOpen(false) + } catch (error) { + console.error('Error adding device:', error.message) + } finally { + setIsLoading(false) + handleModalClose() + } } - const handleAddDevice = (index: number) => { - const addedDevice = nearbyDevices[index] - const newNearbyDevices = nearbyDevices.filter((_, i) => i !== index) - const newDevices = [...devices, { ...addedDevice, paired: true }] - setNearbyDevices(newNearbyDevices) - setDevices(newDevices) + const handleModalOpen = () => setIsModalOpen(true) + const handleModalClose = () => setIsModalOpen(false) + + const handleDeleteModalOpen = (index: number) => { + setSelectedDeviceIndex(index) + setIsDeleteModalOpen(true) } + const handleDeleteModalClose = () => { + setSelectedDeviceIndex(null) + setIsDeleteModalOpen(false) + } + + const handleRemoveDevice = async (index: number) => { + setIsDeleteLoading(true) + const deviceToRemove = devices[index] + + try { + const response = await axios.delete(`${strapiUrl}${ROUTE_TYPE[role!]}/der`, { + params: { id: deviceToRemove.id }, + headers: { Authorization: `Bearer ${bearerToken}` }, + withCredentials: true + }) + + if (response.status === 200 || response.status === 204) { + if (role === ROLE.PRODUCER) { + setDevices(response.data.production) + setIsDeleteLoading(false) + } else if (role === ROLE.CONSUMER) { + setDevices(response.data.consumption) + setIsDeleteLoading(false) + } + } else { + console.error('Failed to delete the device:', response.data) + } + } catch (error) { + console.error('Error deleting device:', error.message) + } finally { + // setIsDeleteLoading(false) + handleDeleteModalClose() + } + } + + const handleConfirmDeleteDevice = () => { + if (selectedDeviceIndex !== null) { + handleRemoveDevice(selectedDeviceIndex) + handleDeleteModalClose() + } + } + + useEffect(() => { + onDeviceChange(devices) + }, [devices, onDeviceChange]) + return ( @@ -47,25 +130,26 @@ export default function DeviceList({ initialDevices, initialNearbyDevices, onDev spacing={4} > } variant="ghost" + onClick={handleModalOpen} /> handleRemoveDevice(index)} + onClick={() => handleDeleteModalOpen(index)} style={{ cursor: 'pointer' }} size={24} - opacity={'0.5'} + opacity="0.5" /> ))} - {nearbyDevices.length > 0 ? ( - <> - - - {nearbyDevices.map((device, index) => ( - - - handleAddDevice(index)} - style={{ cursor: 'pointer' }} - size={24} - opacity={0.5} - /> - - ))} - - - ) : null} - - + + + ) } diff --git a/apps/open-spark/pages/index.tsx b/apps/open-spark/pages/index.tsx index 6c920b20..ac7b364b 100644 --- a/apps/open-spark/pages/index.tsx +++ b/apps/open-spark/pages/index.tsx @@ -183,43 +183,47 @@ const Homepage = () => { ))} - - - - - - - - - {currentStatusmockData.map((data, index) => ( - + + + - ))} - - - + + + + + {currentStatusmockData.map((data, index) => ( + + ))} + + + + )} + router.push(role === ROLE.PRODUCER ? '/sellingPreference' : '/buyingPreference')} + sx={{ marginTop: '30px' }} /> { + const strapiUrl = process.env.NEXT_PUBLIC_STRAPI_URL + const { role } = useSelector((state: RootState) => state.auth) + const bearerToken = Cookies.get('authToken') const [devices, setDevices] = useState([ { name: 'Wifi', paired: true }, { name: 'Orient electric Fan', paired: true }, @@ -12,16 +20,36 @@ const MyDers = () => { { name: 'Solar Panel', paired: true } ]) - const [nearbyDevices, setNearbyDevices] = useState([{ name: 'Light', paired: false }]) - - const handleDeviceChange = ( - updatedDevices: React.SetStateAction<{ name: string; paired: boolean }[]>, - updatedNearbyDevices: React.SetStateAction<{ name: string; paired: boolean }[]> - ) => { + const handleDeviceChange = (updatedDevices: React.SetStateAction<{ name: string; paired: boolean }[]>) => { setDevices(updatedDevices) - setNearbyDevices(updatedNearbyDevices) } + const fetchPairedData = async () => { + try { + const response = await axios.get(`${strapiUrl}${ROUTE_TYPE[role!]}/der`, { + headers: { Authorization: `Bearer ${bearerToken}` }, + withCredentials: true + }) + + const result = response.data.data + console.log(result) + + if (role === ROLE.PRODUCER) { + setDevices(result.production) + } else if (role === ROLE.CONSUMER) { + setDevices(result.consumption) + } + } catch (error) { + console.error('Error fetching dashboard data:', error) + } + } + + useEffect(() => { + if (role && bearerToken && strapiUrl) { + fetchPairedData() + } + }, [role, bearerToken, strapiUrl]) + return ( { > ) diff --git a/apps/open-spark/public/images/PDF.svg b/apps/open-spark/public/images/PDF.svg index 04407277..00c01edf 100644 --- a/apps/open-spark/public/images/PDF.svg +++ b/apps/open-spark/public/images/PDF.svg @@ -1,5 +1,5 @@ - - - + + +