feat(design): home page new design and functionality #135
45
package-lock.json
generated
45
package-lock.json
generated
@ -37,6 +37,7 @@
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-redux": "9.1.0",
|
||||
"react-router-dom": "6.22.1",
|
||||
"react-toastify": "10.0.4",
|
||||
@ -2680,6 +2681,15 @@
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/attr-accept": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
|
||||
"integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz",
|
||||
@ -3857,6 +3867,24 @@
|
||||
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
||||
},
|
||||
"node_modules/file-selector": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz",
|
||||
"integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/file-selector/node_modules/tslib": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
@ -5716,6 +5744,23 @@
|
||||
"react": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dropzone": {
|
||||
"version": "14.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz",
|
||||
"integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"attr-accept": "^2.2.2",
|
||||
"file-selector": "^0.6.0",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">= 16.8 || 18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
|
@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 32",
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 29",
|
||||
"lint:fix": "eslint . --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"lint:staged": "eslint --fix --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"formatter:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"",
|
||||
@ -47,6 +47,7 @@
|
||||
"react-dnd": "16.0.1",
|
||||
"react-dnd-html5-backend": "16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dropzone": "^14.2.3",
|
||||
"react-redux": "9.1.0",
|
||||
"react-router-dom": "6.22.1",
|
||||
"react-toastify": "10.0.4",
|
||||
|
@ -24,7 +24,7 @@ import JSZip from 'jszip'
|
||||
import { MuiFileInput } from 'mui-file-input'
|
||||
import { Event, kinds } from 'nostr-tools'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { DndProvider, DragSourceMonitor, useDrag, useDrop } from 'react-dnd'
|
||||
import { DndProvider, useDrag, useDrop } from 'react-dnd'
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
@ -68,7 +68,7 @@ import { Mark } from '../../types/mark.ts'
|
||||
export const CreatePage = () => {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const { uploadedFile } = location.state || {}
|
||||
const { uploadedFiles } = location.state || {}
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('')
|
||||
@ -134,10 +134,10 @@ export const CreatePage = () => {
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (uploadedFile) {
|
||||
setSelectedFiles([uploadedFile])
|
||||
if (uploadedFiles) {
|
||||
setSelectedFiles([...uploadedFiles])
|
||||
}
|
||||
}, [uploadedFile])
|
||||
}, [uploadedFiles])
|
||||
|
||||
useEffect(() => {
|
||||
if (usersPubkey) {
|
||||
@ -979,7 +979,7 @@ const SignerRow = ({
|
||||
item: () => {
|
||||
return { id: user.pubkey, index }
|
||||
},
|
||||
collect: (monitor: DragSourceMonitor) => ({
|
||||
collect: (monitor) => ({
|
||||
isDragging: monitor.isDragging()
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Button, TextField } from '@mui/material'
|
||||
import JSZip from 'jszip'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { toast } from 'react-toastify'
|
||||
import { useAppSelector } from '../../hooks'
|
||||
@ -10,7 +10,7 @@ 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 { useDropzone } from 'react-dropzone'
|
||||
import { Container } from '../../components/Container'
|
||||
import styles from './style.module.scss'
|
||||
import {
|
||||
@ -24,8 +24,8 @@ const FILTERS = [
|
||||
'Show all',
|
||||
// 'Drafts',
|
||||
'In-progress',
|
||||
'Completed',
|
||||
'Archived'
|
||||
'Completed'
|
||||
// 'Archived'
|
||||
] as const
|
||||
type Filter = (typeof FILTERS)[number]
|
||||
|
||||
@ -40,7 +40,6 @@ type Sort = (typeof SORT_BY)[number]['value']
|
||||
|
||||
export const HomePage = () => {
|
||||
const navigate = useNavigate()
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
const [sigits, setSigits] = useState<{ [key: string]: Meta }>({})
|
||||
const [parsedSigits, setParsedSigits] = useState<{
|
||||
@ -74,51 +73,52 @@ export const HomePage = () => {
|
||||
}
|
||||
}, [usersAppData])
|
||||
|
||||
const handleUploadClick = () => {
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.click()
|
||||
}
|
||||
}
|
||||
const onDrop = useCallback(
|
||||
async (acceptedFiles: File[]) => {
|
||||
// When uploading single file check if it's .sigit.zip
|
||||
if (acceptedFiles.length === 1) {
|
||||
const file = acceptedFiles[0]
|
||||
|
||||
const handleFileChange = async (
|
||||
event: React.ChangeEvent<HTMLInputElement>
|
||||
) => {
|
||||
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 }
|
||||
// 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
|
||||
})
|
||||
}
|
||||
|
||||
// navigate to verify page if zip contains meta.json
|
||||
if ('meta.json' in zip.files) {
|
||||
return navigate(appPublicRoutes.verify, {
|
||||
state: { uploadedZip: file }
|
||||
})
|
||||
}
|
||||
if (!zip) return
|
||||
|
||||
toast.error('Invalid zip file')
|
||||
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 SiGit zip file')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// navigate to create page
|
||||
navigate(appPrivateRoutes.create, { state: { uploadedFile: file } })
|
||||
}
|
||||
}
|
||||
navigate(appPrivateRoutes.create, {
|
||||
state: { uploadedFiles: acceptedFiles }
|
||||
})
|
||||
},
|
||||
[navigate]
|
||||
)
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })
|
||||
|
||||
const [search, setSearch] = useState('')
|
||||
const [filter, setFilter] = useState<Filter>('Show all')
|
||||
@ -202,15 +202,15 @@ export const HomePage = () => {
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.dropzone} onClick={handleUploadClick}>
|
||||
<input
|
||||
id="fileUpload"
|
||||
type="file"
|
||||
hidden
|
||||
ref={fileInputRef}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
<div>Click or drag files to upload!</div>
|
||||
<div className={styles.dropzone}>
|
||||
<div {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
{isDragActive ? (
|
||||
<p>Drop the files here ...</p>
|
||||
) : (
|
||||
<p>Click or drag files to upload!</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.submissions}>
|
||||
{Object.keys(parsedSigits)
|
||||
|
@ -120,6 +120,7 @@ export const queryNip05 = async (
|
||||
if (!match) throw new Error('Invalid nip05')
|
||||
|
||||
// Destructure the match result, assigning default value '_' to name if not provided
|
||||
// First variable from the match destructuring is ignored
|
||||
const [, name = '_', domain] = match
|
||||
|
||||
// Construct the URL to query the NIP-05 data
|
||||
|
Loading…
Reference in New Issue
Block a user