Compare commits
21 Commits
7056ad3cd3
...
a3c45b504e
Author | SHA1 | Date | |
---|---|---|---|
a3c45b504e | |||
da30dba368 | |||
|
51e2ab6f8a | ||
|
9091bbc251 | ||
7c26edf84e | |||
2d7bb234f4 | |||
c4d50293ff | |||
89971fb176 | |||
acad24dc06 | |||
|
55abe814c9 | ||
e33996c1f9 | |||
6ba3b6ec89 | |||
aa8214d015 | |||
e48a396990 | |||
79e14d45a1 | |||
64e8ebba85 | |||
5dc8d53503 | |||
86a16c13ce | |||
7c027825cd | |||
8e71592d88 | |||
75a715d002 |
@ -22,11 +22,16 @@ import { useSigitMeta } from '../../hooks/useSigitMeta'
|
|||||||
import { extractFileExtensions } from '../../utils/file'
|
import { extractFileExtensions } from '../../utils/file'
|
||||||
|
|
||||||
type SigitProps = {
|
type SigitProps = {
|
||||||
|
sigitCreateId: string
|
||||||
meta: Meta
|
meta: Meta
|
||||||
parsedMeta: SigitCardDisplayInfo
|
parsedMeta: SigitCardDisplayInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DisplaySigit = ({ meta, parsedMeta }: SigitProps) => {
|
export const DisplaySigit = ({
|
||||||
|
meta,
|
||||||
|
parsedMeta,
|
||||||
|
sigitCreateId: sigitCreateId
|
||||||
|
}: SigitProps) => {
|
||||||
const { title, createdAt, submittedBy, signers, signedStatus, isValid } =
|
const { title, createdAt, submittedBy, signers, signedStatus, isValid } =
|
||||||
parsedMeta
|
parsedMeta
|
||||||
|
|
||||||
@ -35,15 +40,19 @@ export const DisplaySigit = ({ meta, parsedMeta }: SigitProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemWrapper}>
|
<div className={styles.itemWrapper}>
|
||||||
<Link
|
{signedStatus === SigitStatus.Complete && (
|
||||||
to={
|
<Link
|
||||||
signedStatus === SigitStatus.Complete
|
to={appPublicRoutes.verify}
|
||||||
? appPublicRoutes.verify
|
state={{ meta }}
|
||||||
: appPrivateRoutes.sign
|
className={styles.insetLink}
|
||||||
}
|
></Link>
|
||||||
state={{ meta }}
|
)}
|
||||||
className={styles.insetLink}
|
{signedStatus !== SigitStatus.Complete && (
|
||||||
></Link>
|
<Link
|
||||||
|
to={`${appPrivateRoutes.sign}/${sigitCreateId}`}
|
||||||
|
className={styles.insetLink}
|
||||||
|
></Link>
|
||||||
|
)}
|
||||||
<p className={`line-clamp-2 ${styles.title}`}>{title}</p>
|
<p className={`line-clamp-2 ${styles.title}`}>{title}</p>
|
||||||
<div className={styles.users}>
|
<div className={styles.users}>
|
||||||
{submittedBy && (
|
{submittedBy && (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { CurrentUserMark } from '../../types/mark.ts'
|
import { CurrentUserMark } from '../../types/mark.ts'
|
||||||
import styles from './style.module.scss'
|
import styles from './style.module.scss'
|
||||||
|
|
||||||
import { MARK_TYPE_TRANSLATION, NEXT, SIGN } from '../../utils/const.ts'
|
import { MARK_TYPE_TRANSLATION } from '../../utils/const.ts'
|
||||||
import {
|
import {
|
||||||
findNextIncompleteCurrentUserMark,
|
findNextIncompleteCurrentUserMark,
|
||||||
isCurrentUserMarksComplete,
|
isCurrentUserMarksComplete,
|
||||||
@ -32,7 +32,6 @@ const MarkFormField = ({
|
|||||||
handleCurrentUserMarkChange
|
handleCurrentUserMarkChange
|
||||||
}: MarkFormFieldProps) => {
|
}: MarkFormFieldProps) => {
|
||||||
const [displayActions, setDisplayActions] = useState(true)
|
const [displayActions, setDisplayActions] = useState(true)
|
||||||
const getSubmitButtonText = () => (isReadyToSign() ? SIGN : NEXT)
|
|
||||||
const isReadyToSign = () =>
|
const isReadyToSign = () =>
|
||||||
isCurrentUserMarksComplete(currentUserMarks) ||
|
isCurrentUserMarksComplete(currentUserMarks) ||
|
||||||
isCurrentValueLast(currentUserMarks, selectedMark, selectedMarkValue)
|
isCurrentValueLast(currentUserMarks, selectedMark, selectedMarkValue)
|
||||||
@ -61,6 +60,7 @@ const MarkFormField = ({
|
|||||||
onClick={toggleActions}
|
onClick={toggleActions}
|
||||||
className={styles.triggerBtn}
|
className={styles.triggerBtn}
|
||||||
type="button"
|
type="button"
|
||||||
|
title="Toggle"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@ -93,7 +93,7 @@ const MarkFormField = ({
|
|||||||
/>
|
/>
|
||||||
<div className={styles.actionsBottom}>
|
<div className={styles.actionsBottom}>
|
||||||
<button type="submit" className={styles.submitButton}>
|
<button type="submit" className={styles.submitButton}>
|
||||||
{getSubmitButtonText()}
|
NEXT
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -257,6 +257,7 @@ export const HomePage = () => {
|
|||||||
.map((key) => (
|
.map((key) => (
|
||||||
<DisplaySigit
|
<DisplaySigit
|
||||||
key={`sigit-${key}`}
|
key={`sigit-${key}`}
|
||||||
|
sigitCreateId={key}
|
||||||
parsedMeta={parsedSigits[key]}
|
parsedMeta={parsedSigits[key]}
|
||||||
meta={sigits[key]}
|
meta={sigits[key]}
|
||||||
/>
|
/>
|
||||||
|
@ -35,7 +35,7 @@ export const LandingPage = () => {
|
|||||||
title: <>Open Source</>,
|
title: <>Open Source</>,
|
||||||
description: (
|
description: (
|
||||||
<>
|
<>
|
||||||
Code is MIT licenced and available at{' '}
|
Code is AGPL licenced and available at{' '}
|
||||||
<a href="https://git.nostrdev.com/sigit/sigit.io">
|
<a href="https://git.nostrdev.com/sigit/sigit.io">
|
||||||
https://git.nostrdev.com/sigit/sigit.io
|
https://git.nostrdev.com/sigit/sigit.io
|
||||||
</a>
|
</a>
|
||||||
@ -120,9 +120,7 @@ export const LandingPage = () => {
|
|||||||
<Container className={styles.container}>
|
<Container className={styles.container}>
|
||||||
<img className={styles.logo} src="/logo.svg" alt="Logo" width={300} />
|
<img className={styles.logo} src="/logo.svg" alt="Logo" width={300} />
|
||||||
<div className={styles.titleSection}>
|
<div className={styles.titleSection}>
|
||||||
<h1 className={styles.title}>
|
<h1 className={styles.title}>Secure & Private Agreements</h1>
|
||||||
Secure & Private Document Signing
|
|
||||||
</h1>
|
|
||||||
<p className={styles.subTitle}>
|
<p className={styles.subTitle}>
|
||||||
An open-source and self-hostable solution for secure document
|
An open-source and self-hostable solution for secure document
|
||||||
signing and verification.
|
signing and verification.
|
||||||
|
@ -7,7 +7,7 @@ import { MuiFileInput } from 'mui-file-input'
|
|||||||
import { Event, verifyEvent } from 'nostr-tools'
|
import { Event, verifyEvent } from 'nostr-tools'
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
import { useLocation, useNavigate, useParams } from 'react-router-dom'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import { LoadingSpinner } from '../../components/LoadingSpinner'
|
import { LoadingSpinner } from '../../components/LoadingSpinner'
|
||||||
import { NostrController } from '../../controllers'
|
import { NostrController } from '../../controllers'
|
||||||
@ -54,6 +54,7 @@ import {
|
|||||||
SigitFile
|
SigitFile
|
||||||
} from '../../utils/file.ts'
|
} from '../../utils/file.ts'
|
||||||
import { ARRAY_BUFFER, DEFLATE } from '../../utils/const.ts'
|
import { ARRAY_BUFFER, DEFLATE } from '../../utils/const.ts'
|
||||||
|
import { useAppSelector } from '../../hooks/store.ts'
|
||||||
enum SignedStatus {
|
enum SignedStatus {
|
||||||
Fully_Signed,
|
Fully_Signed,
|
||||||
User_Is_Next_Signer,
|
User_Is_Next_Signer,
|
||||||
@ -63,17 +64,39 @@ enum SignedStatus {
|
|||||||
export const SignPage = () => {
|
export const SignPage = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
const params = useParams()
|
||||||
|
|
||||||
|
const usersAppData = useAppSelector((state) => state.userAppData)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Received from `location.state`
|
||||||
|
*
|
||||||
* uploadedZip will be received from home page when a user uploads a sigit zip wrapper that contains keys.json
|
* uploadedZip will be received from home page when a user uploads a sigit zip wrapper that contains keys.json
|
||||||
* arrayBuffer will be received in navigation from create page in offline mode
|
* arrayBuffer (decryptedArrayBuffer) will be received in navigation from create page in offline mode
|
||||||
* meta will be received in navigation from create & home page in online mode
|
* meta (metaInNavState) will be received in navigation from create & home page in online mode
|
||||||
*/
|
*/
|
||||||
const {
|
let metaInNavState = location?.state?.meta || undefined
|
||||||
meta: metaInNavState,
|
const { arrayBuffer: decryptedArrayBuffer, uploadedZip } = location.state || {
|
||||||
arrayBuffer: decryptedArrayBuffer,
|
decryptedArrayBuffer: undefined,
|
||||||
uploadedZip
|
uploadedZip: undefined
|
||||||
} = location.state || {}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If userAppData (redux) is available, and we have the route param (sigit id)
|
||||||
|
* which is actually a `createEventId`, we will fetch a `sigit`
|
||||||
|
* based on the provided route ID and set fetched `sigit` to the `metaInNavState`
|
||||||
|
*/
|
||||||
|
if (usersAppData) {
|
||||||
|
const sigitCreateId = params.id
|
||||||
|
|
||||||
|
if (sigitCreateId) {
|
||||||
|
const sigit = usersAppData.sigits[sigitCreateId]
|
||||||
|
|
||||||
|
if (sigit) {
|
||||||
|
metaInNavState = sigit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const [displayInput, setDisplayInput] = useState(false)
|
const [displayInput, setDisplayInput] = useState(false)
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ export const privateRoutes = [
|
|||||||
element: <CreatePage />
|
element: <CreatePage />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: appPrivateRoutes.sign,
|
path: `${appPrivateRoutes.sign}/:id?`,
|
||||||
element: <SignPage />
|
element: <SignPage />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -4,8 +4,6 @@ export const EMPTY: string = ''
|
|||||||
export const MARK_TYPE_TRANSLATION: { [key: string]: string } = {
|
export const MARK_TYPE_TRANSLATION: { [key: string]: string } = {
|
||||||
[MarkType.FULLNAME.valueOf()]: 'Full Name'
|
[MarkType.FULLNAME.valueOf()]: 'Full Name'
|
||||||
}
|
}
|
||||||
export const SIGN: string = 'Sign'
|
|
||||||
export const NEXT: string = 'Next'
|
|
||||||
export const ARRAY_BUFFER = 'arraybuffer'
|
export const ARRAY_BUFFER = 'arraybuffer'
|
||||||
export const DEFLATE = 'DEFLATE'
|
export const DEFLATE = 'DEFLATE'
|
||||||
|
|
||||||
|
@ -153,6 +153,11 @@ const findOtherUserMarks = (marks: Mark[], pubkey: string): Mark[] => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_TOOLBOX: DrawTool[] = [
|
export const DEFAULT_TOOLBOX: DrawTool[] = [
|
||||||
|
{
|
||||||
|
identifier: MarkType.TEXT,
|
||||||
|
icon: faT,
|
||||||
|
label: 'Text'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
identifier: MarkType.FULLNAME,
|
identifier: MarkType.FULLNAME,
|
||||||
icon: faIdCard,
|
icon: faIdCard,
|
||||||
@ -177,11 +182,6 @@ export const DEFAULT_TOOLBOX: DrawTool[] = [
|
|||||||
label: 'Date Time',
|
label: 'Date Time',
|
||||||
isComingSoon: true
|
isComingSoon: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
identifier: MarkType.TEXT,
|
|
||||||
icon: faT,
|
|
||||||
label: 'Text'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
identifier: MarkType.NUMBER,
|
identifier: MarkType.NUMBER,
|
||||||
icon: fa1,
|
icon: fa1,
|
||||||
|
Loading…
Reference in New Issue
Block a user