import { Button, TextField } from '@mui/material' import JSZip from 'jszip' import { useEffect, useRef, useState } from 'react' import { useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' import { useAppSelector } from '../../hooks' import { appPrivateRoutes, appPublicRoutes } from '../../routes' import { Meta, ProfileMetadata } from '../../types' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faSearch } from '@fortawesome/free-solid-svg-icons' import { Select } from '../../components/Select' import { DisplaySigit } from '../../components/DisplaySigit' import { Container } from '../../components/Container' import styles from './style.module.scss' import { extractSigitInfo, SigitInfo, SignedStatus } from '../../hooks/useSigitMeta' // Unsupported Filter options are commented const FILTERS = [ 'Show all', // 'Drafts', 'In-progress', 'Completed', 'Archived' ] as const type Filter = (typeof FILTERS)[number] const SORT_BY = [ { label: 'Newest', value: 'desc' }, { label: 'Oldest', value: 'asc' } ] as const type Sort = (typeof SORT_BY)[number]['value'] export const HomePage = () => { const navigate = useNavigate() const fileInputRef = useRef(null) const [sigits, setSigits] = useState<{ [key: string]: Meta }>({}) const [parsedSigits, setParsedSigits] = useState<{ [key: string]: SigitInfo }>({}) const [profiles, setProfiles] = useState<{ [key: string]: ProfileMetadata }>( {} ) const usersAppData = useAppSelector((state) => state.userAppData) useEffect(() => { if (usersAppData) { const getSigitInfo = async () => { for (const key in usersAppData.sigits) { if (Object.prototype.hasOwnProperty.call(usersAppData.sigits, key)) { const sigitInfo = await extractSigitInfo(usersAppData.sigits[key]) if (sigitInfo) { setParsedSigits((prev) => { return { ...prev, [key]: sigitInfo } }) } } } } setSigits(usersAppData.sigits) getSigitInfo() } }, [usersAppData]) const handleUploadClick = () => { if (fileInputRef.current) { fileInputRef.current.click() } } const handleFileChange = async ( event: React.ChangeEvent ) => { const file = event.target.files?.[0] if (file) { // Check if the file extension is .sigit.zip const fileName = file.name const fileExtension = fileName.slice(-10) // ".sigit.zip" has 10 characters if (fileExtension === '.sigit.zip') { const zip = await JSZip.loadAsync(file).catch((err) => { console.log('err in loading zip file :>> ', err) toast.error(err.message || 'An error occurred in loading zip file.') return null }) if (!zip) return // navigate to sign page if zip contains keys.json if ('keys.json' in zip.files) { return navigate(appPrivateRoutes.sign, { state: { uploadedZip: file } }) } // navigate to verify page if zip contains meta.json if ('meta.json' in zip.files) { return navigate(appPublicRoutes.verify, { state: { uploadedZip: file } }) } toast.error('Invalid zip file') return } // navigate to create page navigate(appPrivateRoutes.create, { state: { uploadedFile: file } }) } } const [search, setSearch] = useState('') const [filter, setFilter] = useState('Show all') const [sort, setSort] = useState('desc') return (
{ return { ...s } })} />
{ e.preventDefault() const searchInput = e.currentTarget.elements.namedItem( 'q' ) as HTMLInputElement setSearch(searchInput.value) }} > { // Handle the case when users click native search input's clear or x if (e.currentTarget.value === '') { setSearch(e.currentTarget.value) } }} sx={{ width: '100%', fontSize: '16px', borderTopLeftRadius: 'var(----mui-shape-borderRadius)', borderBottomLeftRadius: 'var(----mui-shape-borderRadius)', '& .MuiInputBase-root': { borderTopRightRadius: 0, borderBottomRightRadius: 0 }, '& .MuiInputBase-input': { padding: '7px 14px' }, '& .MuiOutlinedInput-notchedOutline': { display: 'none' } }} />
Click or drag files to upload!
{Object.keys(parsedSigits) .filter((s) => { const { title, signedStatus } = parsedSigits[s] const isMatch = title?.toLowerCase().includes(search.toLowerCase()) switch (filter) { case 'Completed': return signedStatus === SignedStatus.Complete && isMatch case 'In-progress': return signedStatus === SignedStatus.Partial && isMatch case 'Show all': return isMatch default: console.error('Filter case not handled.') } }) .sort((a, b) => { const x = parsedSigits[a].createdAt ?? 0 const y = parsedSigits[b].createdAt ?? 0 return sort === 'desc' ? y - x : x - y }) .map((key) => ( ))}
) }