Skip to content

Commit

Permalink
Merge pull request #292 from us3r-network/F-nodeAsService-bufan
Browse files Browse the repository at this point in the history
F-nodeAsService-bufan
  • Loading branch information
sin-bufan authored Jan 17, 2024
2 parents 1f7b82a + 73b291d commit dad164b
Show file tree
Hide file tree
Showing 10 changed files with 545 additions and 18 deletions.
2 changes: 1 addition & 1 deletion packages/client/dashboard/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios from 'axios'
import { UPLOAD_API_URL } from '../constants'

enum ApiRespCode {
export enum ApiRespCode {
SUCCESS = 0,
ERROR = 1,
}
Expand Down
59 changes: 59 additions & 0 deletions packages/client/dashboard/src/api/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import axios, { AxiosPromise } from 'axios'
import { ApiResp } from '.'
import { APP_API_URL } from '../constants'
import { AccountType } from '../types.d'

export function getUserEmail(
didSession: string
): AxiosPromise<ApiResp<{ email: string }>> {
let host = APP_API_URL
return axios({
url: host + `/users/email`,
method: 'GET',
headers: {
'did-session': didSession,
},
})
}

export function postUserEmail(
didSession: string,
email: string,
): AxiosPromise<ApiResp<undefined>> {
if (!email) throw new Error('email id is required')

let host = APP_API_URL

return axios({
url: host + '/users/email',
method: 'POST',
headers: {
'did-session': didSession,
},
data: { email },
})
}

export function linkUserEmail(
didSession: string,
email: string,
code: string,
): AxiosPromise<ApiResp<undefined>> {
if (!email) throw new Error('email is required')
if (!code) throw new Error('code is required')

let host = APP_API_URL

return axios({
url: host + '/users/link',
method: 'POST',
headers: {
'did-session': didSession,
},
data: {
thirdpartyId: email,
code,
type: AccountType.EMAIL
},
})
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default function CheckCircleIcon({ bgc = '#5BA85A' }: { bgc?: string }) {
export default function CheckCircleIcon({ bgc = '#00b171' }: { bgc?: string }) {
return (
<svg
width="20"
Expand All @@ -7,10 +7,7 @@ export default function CheckCircleIcon({ bgc = '#5BA85A' }: { bgc?: string }) {
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.0003 18.3327C14.6027 18.3327 18.3337 14.6017 18.3337 9.99935C18.3337 5.39698 14.6027 1.66602 10.0003 1.66602C5.39795 1.66602 1.66699 5.39698 1.66699 9.99935C1.66699 14.6017 5.39795 18.3327 10.0003 18.3327Z"
fill={bgc}
/>
<circle cx='10' cy='10' r='8' stroke={bgc} stroke-width='4' fill={bgc}/>
<path
d="M6.25 10L8.75 12.5L13.75 7.5"
stroke="white"
Expand Down
13 changes: 13 additions & 0 deletions packages/client/dashboard/src/components/icons/CircleIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default function CircleIcon ({ bgc = '#5BA85A' }: { bgc?: string }) {
return (
<svg
width='20'
height='20'
viewBox='0 0 20 20'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<circle cx='10' cy='10' r='8' stroke={bgc} stroke-width='4' />
</svg>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { createCeramicNode } from '../../api/ceramicNode'
import { CeramicDBType, CeramicNetwork } from '../../types.d'
import EnumSelect from '../common/EnumSelect'
import CloseIcon from '../icons/CloseIcon'
import UserEmail from './UserEmail'
import { EmailStatus } from '../../hooks/useUserAccount'

export default function CreateCeramicNodeModal ({
fixedNetwork,
Expand Down Expand Up @@ -60,8 +62,17 @@ export default function CreateCeramicNodeModal ({
} finally {
setSubmitting(false)
}
}, [submitting, session, signIn, nodeName, network, dbType, onSussess, closeModal])

}, [
submitting,
session,
signIn,
nodeName,
network,
dbType,
onSussess,
closeModal
])
const [userEmailVerified, setUserEmailVerified] = useState(false)
return (
<CreateBox>
<div className='title'>
Expand Down Expand Up @@ -100,6 +111,11 @@ export default function CreateCeramicNodeModal ({
</div>
Enable Historic Sync
</Checkbox>
<UserEmail
emailStatusChange={stutas =>
setUserEmailVerified(stutas === EmailStatus.VERIFIED)
}
/>
</EditorBox>
<div className='btns'>
<button onClick={closeModal}>Cancel</button>
Expand All @@ -108,14 +124,15 @@ export default function CreateCeramicNodeModal ({
<img src='/loading.gif' alt='' />
</button>
)) || (
<button className='submit' onClick={submit}>
<button className='submit' onClick={submit} disabled={!userEmailVerified}>
Submit
</button>
)}
</div>
</CreateBox>
)
}

const EditorBox = styled.div`
display: flex;
flex-direction: column;
Expand Down
187 changes: 187 additions & 0 deletions packages/client/dashboard/src/components/node/NodeStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import styled from 'styled-components'
import { CeramicStatus } from '../../types.d'
import CircleIcon from '../icons/CircleIcon'
import CheckCircleIcon from '../icons/CheckCircleIcon'

import { ProgressBar, Label } from 'react-aria-components'
import { useEffect, useState } from 'react'

export default function NodeStatus ({
status,
}: {
status: CeramicStatus
}) {
const [prepageingPercentage, setPrepageingPercentage] = useState(0)
const [startingPercentage, setStartingPercentage] = useState(0)

useEffect(() => {
if (status !== CeramicStatus.PREPARING) return
if (prepageingPercentage < 100) {
console.log('set prepare timeout', prepageingPercentage)
setTimeout(() => {
setPrepageingPercentage(prepageingPercentage + 1)
}, 350)
}
}, [prepageingPercentage, status])

useEffect(() => {
if (status !== CeramicStatus.STARTING) return
if (startingPercentage < 100) {
console.log('set start timeout', startingPercentage)
setTimeout(() => {
setStartingPercentage(startingPercentage + 1)
}, 200)
}
}, [startingPercentage, status])

useEffect(() => {
switch (status) {
case CeramicStatus.PREPARING:
setPrepageingPercentage(0)
setStartingPercentage(0)
break
case CeramicStatus.STARTING:
setPrepageingPercentage(100)
setStartingPercentage(0)
break
case CeramicStatus.RUNNING:
setPrepageingPercentage(100)
setStartingPercentage(100)
break
default:
break
}
}, [status])

switch (status) {
case CeramicStatus.PREPARING:
return (
<Box>
<div>
<StepNode percentage={prepageingPercentage} />
<StepProgress percentage={prepageingPercentage} />
<StepNode />
<StepProgress />
<StepNode />
</div>
<div>
<Label className='green'>Preparing</Label>
<Label className='gray'>Start</Label>
<Label className='gray'>Run</Label>
</div>
</Box>
)
case CeramicStatus.STARTING:
return (
<Box>
<div>
<StepNode percentage={100} />
<StepProgress percentage={100} />
<StepNode percentage={startingPercentage} />
<StepProgress percentage={startingPercentage} />
<StepNode />
</div>
<div>
<Label className='green'>Prepared</Label>
<Label className='green'>Starting</Label>
<Label className='gray'>Run</Label>
</div>
</Box>
)
case CeramicStatus.RUNNING:
return (
<Box>
<div>
<StepNode percentage={100} />
<StepProgress percentage={100} />
<StepNode percentage={100} />
<StepProgress percentage={100} />
<StepNode percentage={1} />
</div>
<div>
<Label className='green'>Prepared</Label>
<Label className='green'>Started</Label>
<Label className='green'>Running</Label>
</div>
</Box>
)
default:
return null
}
}

const Box = styled.div`
width: 100%;
display: flex;
flex-direction: column;
gap: 10px;
> div {
width: 100%;
display: flex;
align-items: center;
gap: 10px;
justify-content: space-between;
}
.green {
color: #00b171;
}
.gray {
color: #718096;
}
label {
font-size: 12px;
font-weight: 500;
line-height: 1.2;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.react-aria-ProgressBar {
display: grid;
grid-template-areas: "label value"
"bar bar";
grid-template-columns: 1fr auto;
color: var(--text-color);
flex: 1;
.value {
grid-area: value;
}
.bar {
grid-area: bar;
box-shadow: inset 0px 0px 0px 1px #718096;
forced-color-adjust: none;
height: 2px;
overflow: hidden;
will-change: transform;
}
.fill {
background: #00b171;
height: 100%;
}
}
`
function StepNode ({ percentage = 0 }: { percentage?: number }) {
if (percentage === 0) {
return <CircleIcon bgc='#718096' />
} else if (percentage < 100) {
return <CircleIcon bgc='#00B171' />
} else if (percentage >= 100) {
return <CheckCircleIcon />
}
return null
}
function StepProgress ({ percentage = 0 }: { percentage?: number }) {
return (
<ProgressBar value={percentage}>
{({ percentage, valueText }) => (
<>
{/* <span className='value'>{valueText}</span> */}
<div className='bar'>
<div className='fill' style={{ width: percentage + '%' }} />
</div>
</>
)}
</ProgressBar>
)
}
Loading

0 comments on commit dad164b

Please sign in to comment.