Skip to content

Commit

Permalink
fix: various updates from implementing w3console
Browse files Browse the repository at this point in the history
when I actually tried to use these components I ran into a number of issues:
a) needed more classes in the authenticator to style it properly
b) needed an `onUploadComplete` callback in the `Uploader` in order to reload the uploads list post-upload
c) decided to rework the `Uploader` to keep the upload dropbox visible at all times
d) needed to move `useUploaderComponent` inside the `Uploader` that provides its context - it was totally broken as-is
e) restructured the `UploadsList` and added more styles
  • Loading branch information
travis committed Jan 13, 2023
1 parent abeedfe commit 3faa2bc
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 39 deletions.
6 changes: 3 additions & 3 deletions packages/react-ui/src/SimpleAuthenticator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function AuthenticationForm (): JSX.Element {
<label htmlFor='w3ui-simple-authenticator-email'>Email address:</label>
<Authenticator.EmailInput id='w3ui-simple-authenticator-email' required />
</div>
<button className='register' type='submit' disabled={submitted}>Register</button>
<button className='register w3ui-button' type='submit' disabled={submitted}>Register</button>
</Authenticator.Form>
)
}
Expand All @@ -22,7 +22,7 @@ export function AuthenticationSubmitted (): JSX.Element {
<div className='w3ui-simple-authenticator-verify-email'>
<h1 className='message'>Verify your email address!</h1>
<p className='detail'>Click the link in the email we sent to {email} to sign in.</p>
<Authenticator.CancelButton className='cancel'>
<Authenticator.CancelButton className='cancel w3ui-button'>
Cancel
</Authenticator.CancelButton>
</div>
Expand All @@ -43,7 +43,7 @@ export function AuthenticationEnsurer ({ children }: { children: JSX.Element | J

export function SimpleAuthenticator ({ children }: { children: JSX.Element | JSX.Element[] }): JSX.Element {
return (
<Authenticator>
<Authenticator as="div" className="w3ui-simple-authenticator">
<AuthenticationEnsurer>
{children}
</AuthenticationEnsurer>
Expand Down
86 changes: 61 additions & 25 deletions packages/react-ui/src/SimpleUploader.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { OnUploadComplete } from '@w3ui/react-uploader'

import React from 'react'
import { CARMetadata } from '@w3ui/uploader-core'
import { Status, Uploader, useUploaderComponent } from '@w3ui/react-uploader'
Expand Down Expand Up @@ -44,33 +46,67 @@ export const Done = ({ file, dataCID, storedDAGShards }: DoneProps): JSX.Element
)
}

export const SimpleUploader = (): JSX.Element => {
const UploaderForm = (): JSX.Element => {
const [{ file }] = useUploaderComponent()
return (
<Uploader.Form>
<div className='w3ui-uploader'>
<label className='w3ui-uploader__label'>File:</label>
<Uploader.Input className='w3ui-uploader__input' />
</div>
{(file !== undefined) && (
<div className='w3ui-uploader__file'>
<span className='name'>{file.name}</span>
<span className='type'>{file.type}</span>
<span className='size'>{file.size}</span>
</div>
)}
<button type='submit' className='w3ui-button' disabled={file === undefined}>
Upload
</button>
</Uploader.Form>
)
}

const UploaderConsole = (): JSX.Element => {
const [{ status, file, error, dataCID, storedDAGShards }] = useUploaderComponent()
switch (status) {
case Status.Uploading:
return <Uploading file={file} storedDAGShards={storedDAGShards} />
case Status.Succeeded:
return <Done file={file} dataCID={dataCID} storedDAGShards={storedDAGShards} />
case Status.Failed:
return <Errored error={error} />
default:
return (
<></>
)
}
}

const UploaderBody = (): JSX.Element => {
const [{ status }] = useUploaderComponent()

return (
<>
<UploaderForm />
{(status !== Status.Idle) && (
<div className='w3ui-uploader-console'>
<UploaderConsole />
</div>
)}
</>
)
}

export interface SimpleUploaderProps {
onUploadComplete?: OnUploadComplete
}

export const SimpleUploader = ({ onUploadComplete }: SimpleUploaderProps): JSX.Element => {
return (
<Uploader as='div' className='w3ui-uploader-wrapper'>
{(status === Status.Uploading)
? (
<Uploading file={file} storedDAGShards={storedDAGShards} />
)
: (
(status === Status.Succeeded)
? (
<Done file={file} dataCID={dataCID} storedDAGShards={storedDAGShards} />
)
: (status === Status.Failed)
? (
<Errored error={error} />
)
: (
<Uploader.Form>
<div className='w3ui-uploader'>
<label className='w3ui-uploader__label'>File:</label>
<Uploader.Input className='w3ui-uploader__input' />
</div>
<button type='submit' className='w3ui-button'>Upload</button>
</Uploader.Form>
)
)}
<Uploader as='div' className='w3ui-uploader-wrapper' onUploadComplete={onUploadComplete}>
<UploaderBody />
</Uploader>
)
}
48 changes: 38 additions & 10 deletions packages/react-ui/src/SimpleUploadsList.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,62 @@
import type { UploadListResult } from '@w3ui/uploads-list-core'
import React from 'react'
import { UploadsList } from '@w3ui/react-uploads-list'

export const SimpleUploadsList = (): JSX.Element => {
return (
<UploadsList>
{(props) => (
<div className='w3-uploads-list'>
function Uploads ({ uploads }: { uploads?: UploadListResult[] }): JSX.Element {
if ((uploads === undefined) || (uploads.length === 0)) {
return (
<>
<div>
<div>
No uploads
</div>
<nav>
<UploadsList.NextButton className='next'>
Next
</UploadsList.NextButton>
<UploadsList.ReloadButton className='reload'>
<UploadsList.ReloadButton className='reload w3ui-button'>
Reload
</UploadsList.ReloadButton>
</nav>
</div>
</>
)
} else {
return (
<>
<div className='w3-uploads-list-data'>
<table>
<thead>
<tr>
<th>Root CID</th>
</tr>
</thead>
<tbody>
{props.uploadsList?.[0].data?.map(({ root }) => (
{uploads.map(({ root }) => (
<tr key={root.toString()}>
<td>{root.toString()}</td>
</tr>
))}
</tbody>
</table>
</div>
<nav>
<UploadsList.NextButton className='next w3ui-button'>
Next
</UploadsList.NextButton>
<UploadsList.ReloadButton className='reload w3ui-button'>
Reload
</UploadsList.ReloadButton>
</nav>
</>
)
}
}

export const SimpleUploadsList = (): JSX.Element => {
return (
<UploadsList>
{(props) => (
<div className='w3-uploads-list'>
<Uploads uploads={props.uploadsList?.[0].data} />
</div>
)}
</UploadsList>
)
Expand Down
14 changes: 13 additions & 1 deletion packages/react-uploader/src/Uploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,16 @@ const UploaderComponentContext = createContext<UploaderComponentContextValue>([
}
])

export type UploaderRootOptions<T extends As = typeof Fragment> = Options<T>
interface OnUploadCompleteProps {
file?: File
dataCID?: Link<unknown, number, number, Version>
}

export type OnUploadComplete = (props: OnUploadCompleteProps) => void

export type UploaderRootOptions<T extends As = typeof Fragment> = Options<T> & {
onUploadComplete?: OnUploadComplete
}
export type UploaderRootProps<T extends As = typeof Fragment> = Props<UploaderRootOptions<T>>

/**
Expand All @@ -93,6 +102,9 @@ export const UploaderRoot: Component<UploaderRootProps> = createComponent((props
const cid = await uploaderActions.uploadFile(file)
setDataCID(cid)
setStatus(Status.Succeeded)
if (props.onUploadComplete !== undefined) {
props.onUploadComplete({ file, dataCID })
}
} catch (err: any) {
setError(err)
setStatus(Status.Failed)
Expand Down

0 comments on commit 3faa2bc

Please sign in to comment.