Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refresh design #191

Merged
merged 5 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions examples/with-html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ <h1 id="heading">idkit-js</h1>

IDKit.init({
signal: 'test_signal',
app_id: 'wid_staging_a8d860d5b3450f05ae09e8f4aa935b90',
app_id: 'app_ce4cb73cb75fc3b73b71ffb4de178410',
action: 'test-action',
bridge_url: 'https://wallet-bridge.stage-crypto.worldcoin.org',
action_description: 'Test action description',
credential_types: ['phone', 'device'],
handleVerify: response => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"prepublishOnly": "npm run build"
},
"devDependencies": {
"turbo": "^1.10.14"
"turbo": "^1.10.16"
}
}
79 changes: 24 additions & 55 deletions packages/react/src/components/IDKitWidget/BaseWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@ import { shallow } from 'zustand/shallow'
import XMarkIcon from '../Icons/XMarkIcon'
import ErrorState from './States/ErrorState'
import { ConfigSource } from '@/types/config'
import LoadingIcon from '../Icons/LoadingIcon'
import * as Toast from '@radix-ui/react-toast'
import type { IDKitStore } from '@/store/idkit'
import PrivacyState from './States/PrivacyState'
import SuccessState from './States/SuccessState'
import WorldIDState from './States/WorldIDState'
import * as Dialog from '@radix-ui/react-dialog'
import type { WidgetProps } from '@/types/config'
import WorldcoinIcon from '../Icons/WorldcoinIcon'
import { Fragment, useEffect, useMemo } from 'react'
import WorldIDWordmark from '../Icons/WorldIDWordmark'
import { AnimatePresence, motion } from 'framer-motion'
import ArrowLongLeftIcon from '../Icons/ArrowLongLeftIcon'
import HostAppVerificationState from './States/HostAppVerificationState'
Expand Down Expand Up @@ -106,7 +105,7 @@ const IDKitWidget: FC<WidgetProps> = ({ children, ...config }) => {
}}
transition={{ layout: { duration: 0.15 } }}
className={
'relative z-50 w-full rounded-t-2xl bg-white pt-6 shadow focus:outline-none focus-visible:ring focus-visible:ring-purple-500/75 dark:bg-0d151d md:max-w-md md:rounded-b-2xl'
'relative z-50 flex min-h-[35rem] w-full flex-col rounded-t-2xl bg-white pt-6 shadow focus:outline-none focus-visible:ring focus-visible:ring-purple-500/75 dark:bg-0d151d md:max-w-md md:rounded-b-2xl'
}
>
<Toast.Provider>
Expand All @@ -123,62 +122,32 @@ const IDKitWidget: FC<WidgetProps> = ({ children, ...config }) => {
<ArrowLongLeftIcon className="w-4" />
</button>

<Dialog.Close className="flex h-8 w-8 items-center justify-center rounded-full bg-gray-100 dark:bg-d3dfea/15 dark:text-white">
<Dialog.Close className="flex items-center justify-center rounded-full dark:text-white">
<XMarkIcon className="h-5 w-5" />
</Dialog.Close>
</div>
<div className="relative">
<motion.div
className="mx-6 mb-6"
layout="position"
animate={{
visibility: processing ? 'hidden' : 'visible',
}}
transition={{ layout: { duration: 0.15 } }}
>
<StageContent />
</motion.div>
<AnimatePresence>
{processing && (
<motion.div
className="absolute inset-0 flex items-center justify-center pb-10"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<LoadingIcon className="h-24 w-24" />
</motion.div>
)}
</AnimatePresence>
<div className="relative mx-6 mb-6 flex flex-1 flex-col items-center justify-center">
<StageContent />
</div>
<div className="flex items-center justify-between px-5 py-3 md:rounded-b-2xl">
<p className="flex items-center gap-1 text-sm text-9eafc0">
<span>{__('Verified with')}</span>
<a
href="https://worldcoin.org/world-id"
target="_blank"
rel="noreferrer"
>
<WorldIDWordmark className="h-4 text-0d151d dark:text-white" />
</a>
</p>
{stage != IDKITStage.PRIVACY ? (
<button
onClick={() => setStage(IDKITStage.PRIVACY)}
className="text-sm text-9eafc0 hover:underline"
>
{__('Privacy')}
</button>
) : (
<a
target="_blank"
href="https://docs.worldcoin.org/privacy"
className="text-sm text-9eafc0 hover:underline dark:text-9eafc0"
rel="noreferrer"
>
{__('Learn More')} &rarr;
</a>
)}
<div className="flex items-center justify-between border-t border-f5f5f7 p-7 md:rounded-b-2xl">
<a
href="https://worldcoin.org/world-id"
target="_blank"
rel="noreferrer"
className="flex items-center gap-1 text-sm text-9eafc0"
>
<WorldcoinIcon className="w-4 text-9eafc0 dark:text-white" />
<span>{__('Powered by Worldcoin')}</span>
</a>

<a
href="https://developer.worldcoin.org/privacy-statement"
target="_blank"
rel="noreferrer"
className="text-sm text-9eafc0 hover:underline"
>
{__('Terms & Privacy')}
</a>
</div>
</Toast.Provider>
</motion.div>
Expand Down
30 changes: 9 additions & 21 deletions packages/react/src/components/IDKitWidget/States/ErrorState.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { __ } from '@/lang'
import useIDKitStore from '@/store/idkit'
import type { IDKitStore } from '@/store/idkit'
import XMarkIcon from '@/components/Icons/XMarkIcon'
import ErrorIcon from '@/components/Icons/ErrorIcon'
import { AppErrorCodes } from '@worldcoin/idkit-core'

const getParams = ({ retryFlow, errorState }: IDKitStore) => ({ retryFlow, errorState })

const ERROR_TITLES: Partial<Record<AppErrorCodes, string>> = {
[AppErrorCodes.GenericError]: __('Something went wrong'),
[AppErrorCodes.FailedByHostApp]: __('Verification Declined'),
[AppErrorCodes.GenericError]: __('Verification Failed'),
}

const ERROR_MESSAGES: Record<AppErrorCodes, string> = {
[AppErrorCodes.ConnectionFailed]: __('Connection to the World App or identity wallet failed. Please try again.'),
[AppErrorCodes.VerificationRejected]: __('Verification request rejected in the World App.'),
[AppErrorCodes.ConnectionFailed]: __('Connection to your wallet failed. Please try again.'),
[AppErrorCodes.VerificationRejected]: __('You rejected the verification request.'),
[AppErrorCodes.MaxVerificationsReached]: __(
'You have already verified the maximum number of times for this action.'
),
[AppErrorCodes.AlreadySigned]: __('You have already verified for this action.'),
[AppErrorCodes.CredentialUnavailable]: __('It seems you do not have the credential required by this app.'),
[AppErrorCodes.CredentialUnavailable]: __('It seems you do not have the verification level required by this app.'),
[AppErrorCodes.MalformedRequest]: __(
'There was a problem with this request. Please try again or contact the app owner.'
),
Expand All @@ -27,12 +26,10 @@ const ERROR_MESSAGES: Record<AppErrorCodes, string> = {
),
[AppErrorCodes.InclusionProofFailed]: __('There was an issue fetching your credential. Please try again.'),
[AppErrorCodes.InclusionProofPending]: __(
'Your credential is still being registered. Please wait a few minutes and try again.'
'Your identity is still being registered. Please wait a few minutes and try again.'
),
[AppErrorCodes.FailedByHostApp]: __('Verification failed by the app. Please contact the app owner for details.'),
[AppErrorCodes.UnexpectedResponse]: __(
'Unexpected response from the World App or identity wallet. Please try again.'
),
[AppErrorCodes.UnexpectedResponse]: __('Unexpected response from your wallet. Please try again.'),
[AppErrorCodes.GenericError]: __('Something unexpected went wrong. Please try again.'),
}

Expand All @@ -42,17 +39,13 @@ const ErrorState = () => {
return (
<div className="space-y-8">
<div className="-mt-5 flex items-center justify-center">
<div className="inline-flex aspect-square items-center justify-center rounded-full bg-red-100 p-5">
<div className="flex aspect-square items-center justify-center rounded-full bg-red-500 p-5">
<XMarkIcon className="w-8 text-white" />
</div>
</div>
<ErrorIcon className="w-24" />
</div>
<div>
<p className="text-center text-2xl font-semibold text-gray-900 dark:text-white">
{(errorState?.code && ERROR_TITLES[errorState.code]) || ERROR_TITLES[AppErrorCodes.GenericError]}
</p>
<p className="mt-2 text-center text-lg text-gray-400">
<p className="mx-auto mt-2 max-w-[14rem] text-center text-657080">
{/* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing */}
{errorState?.message || ERROR_MESSAGES[errorState?.code ?? AppErrorCodes.GenericError]}
</p>
Expand All @@ -66,11 +59,6 @@ const ErrorState = () => {
{__('Try Again')}
</button>
</div>
<div>
<p className="mt-4 text-xs text-gray-400">
{__('If you are the app owner, check the console for further details.')}
</p>
</div>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ const SuccessState = () => {
return (
<div className="space-y-6">
<div className="-mt-5 flex items-center justify-center">
<div className="inline-flex aspect-square items-center justify-center rounded-full bg-green-100 p-5">
<div className="flex aspect-square items-center justify-center rounded-full bg-green-500 p-5">
<CheckIcon className="w-8 text-white" />
</div>
</div>
<CheckIcon className="w-24 text-white" />
</div>
<div>
<p className="text-center text-2xl font-semibold text-gray-900 dark:text-white">{__('Success! 🎉')}</p>
{/* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing */}
<p className="text-70868f mt-2 text-center text-lg">{__('World ID verification was successful')}</p>
<p className="text-center text-2xl font-semibold text-gray-900 dark:text-white">
{__('Successfully verified')}
</p>
<p className="text-657080 mt-2 max-w-[14rem] text-center text-lg">
{__('Your World ID verification was successful')}
</p>
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useCallback, useState } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import LoadingIcon from '@/components/Icons/LoadingIcon'
import WorldcoinIcon from '@/components/Icons/WorldcoinIcon'
import QRPlaceholderIcon from '@/components/Icons/QRPlaceholderIcon'

type Props = {
qrData: string | null
Expand Down Expand Up @@ -80,7 +81,7 @@ const QRState: FC<Props> = ({ qrData, showQR, setShowQR }) => {
</div>
) : (
<div className="flex h-[244px] w-[244px] items-center justify-center">
<LoadingIcon className="h-[72px] w-[72px]" />
<QRPlaceholderIcon className="h-[244px] w-[244px] animate-pulse" />
</div>
)}
</div>
Expand Down
23 changes: 8 additions & 15 deletions packages/react/src/components/IDKitWidget/States/WorldIDState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,27 +56,21 @@ const WorldIDState = () => {
setErrorState({ code: errorCode ?? AppErrorCodes.GenericError })
}

if (result) {
return handleVerify(result)
}
if (result) return handleVerify(result)
}, [result, reset, handleVerify, verificationState, setStage, errorCode, setErrorState])

return (
<div className="-mt-6 space-y-6">
<div className="-mt-6 space-y-10">
<div>
<div className="mb-2 flex items-center justify-center">
<WorldcoinIcon className="h-8 text-0d151d dark:text-white" />
<div className="mb-4 flex items-center justify-center">
<WorldcoinIcon className="h-10 text-0d151d dark:text-white" />
</div>
<p className="text-center font-sora text-2xl font-semibold text-gray-900 dark:text-white">
{verificationState === VerificationState.WaitingForApp
? __('Confirm in World App')
: __('Continue with Worldcoin')}
{__('Verify with World ID')}
</p>
<p className="mt-3 text-center text-657080 dark:text-9eafc0 md:mt-2">
Please use your World App to scan the QR code
</p>
{verificationState === VerificationState.WaitingForApp && (
<p className="mt-3 text-center text-70868f dark:text-9eafc0 md:mt-2">
Please confirm the request in your app to continue.
</p>
)}
</div>
{verificationState === VerificationState.WaitingForApp ? (
<div className="flex items-center justify-center">
Expand All @@ -85,7 +79,6 @@ const WorldIDState = () => {
) : (
<QRState showQR={showQR} setShowQR={setShowQR} qrData={connectorURI} />
)}
{(media == 'desktop' || !showQR) && <AboutWorldID />}
</div>
)
}
Expand Down
48 changes: 44 additions & 4 deletions packages/react/src/components/Icons/CheckIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,54 @@
import type { FC, HTMLAttributes } from 'react'

const CheckIcon: FC<HTMLAttributes<SVGElement>> = props => (
<svg {...props} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 11 8">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 100 100" {...props}>
<circle
cx="50"
cy="50"
r="49.375"
fill="url(#success-a)"
fillOpacity=".65"
stroke="url(#success-b)"
strokeWidth="1.25"
/>
<g filter="url(#success-c)">
<circle cx="50" cy="50" r="35" fill="#fff" />
<circle cx="50" cy="50" r="34.432" stroke="#CCEBCC" strokeWidth="1.136" />
</g>
<path
stroke="currentColor"
stroke="#090"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.6"
d="M9.868 1 3.771 7 1 4.273"
strokeWidth="3.75"
d="m41.25 52.5 4.375 4.375 13.125-13.75"
/>
<defs>
<linearGradient id="success-a" x1="50" x2="50" y1="0" y2="100" gradientUnits="userSpaceOnUse">
<stop stopColor="#99D699" />
<stop offset="1" stopColor="#99D699" stopOpacity="0" />
</linearGradient>
<linearGradient id="success-b" x1="50" x2="50" y1="0" y2="100" gradientUnits="userSpaceOnUse">
<stop stopColor="#99D699" />
<stop offset=".713" stopColor="#99D699" stopOpacity="0" />
</linearGradient>
<filter
id="success-c"
width="77.5"
height="77.5"
x="11.25"
y="13.125"
colorInterpolationFilters="sRGB"
filterUnits="userSpaceOnUse"
>
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" />
<feOffset dy="1.875" />
<feGaussianBlur stdDeviation="1.875" />
<feColorMatrix values="0 0 0 0 0.8 0 0 0 0 0.921569 0 0 0 0 0.8 0 0 0 0.45 0" />
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_39_712" />
<feBlend in="SourceGraphic" in2="effect1_dropShadow_39_712" result="shape" />
</filter>
</defs>
</svg>
)

Expand Down
47 changes: 47 additions & 0 deletions packages/react/src/components/Icons/ErrorIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type { FC, HTMLAttributes } from 'react'

const ErrorIcon: FC<HTMLAttributes<SVGElement>> = props => (
<svg {...props} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="49.375" fill="url(#a)" fillOpacity=".65" stroke="url(#b)" strokeWidth="1.25" />
<g filter="url(#c)">
<circle cx="50" cy="50" r="35" fill="#fff" />
<circle cx="50" cy="50" r="34.432" stroke="#FFC9AD" strokeWidth="1.136" />
</g>
<path
stroke="#FF4732"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="3.75"
d="m57.5 42.5-15 14.999m15 .001-15-14.999"
/>
<defs>
<linearGradient id="a" x1="50" x2="50" y1="0" y2="100" gradientUnits="userSpaceOnUse">
<stop stopColor="#FFA483" />
<stop offset="1" stopColor="#FFA483" stopOpacity="0" />
</linearGradient>
<linearGradient id="b" x1="50" x2="50" y1="0" y2="100" gradientUnits="userSpaceOnUse">
<stop stopColor="#FFA483" />
<stop offset=".713" stopColor="#FFA483" stopOpacity="0" />
</linearGradient>
<filter
id="c"
width="77.5"
height="77.5"
x="11.25"
y="13.125"
colorInterpolationFilters="sRGB"
filterUnits="userSpaceOnUse"
>
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" />
<feOffset dy="1.875" />
<feGaussianBlur stdDeviation="1.875" />
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.788235 0 0 0 0 0.678431 0 0 0 0.45 0" />
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_39_740" />
<feBlend in="SourceGraphic" in2="effect1_dropShadow_39_740" result="shape" />
</filter>
</defs>
</svg>
)

export default ErrorIcon
Loading
Loading