frame for onboarding process

This commit is contained in:
Anton Tranelis 2025-05-27 12:08:11 +02:00
parent 296a2b1bd1
commit 9be07334f5
6 changed files with 176 additions and 21 deletions

View File

@ -1,8 +1,5 @@
import { useEffect } from 'react'
/**
* @category Gaming
*/
export function Modal({
children,
showOnStartup,
@ -12,25 +9,24 @@ export function Modal({
}) {
useEffect(() => {
if (showOnStartup) {
window.my_modal_3.showModal()
window.my_modal_3?.showModal()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return (
<>
{/* You can open the modal using ID.showModal() method */}
<dialog id='my_modal_3' className='tw:modal tw:transition-all tw:duration-300'>
<form method='dialog' className='tw:modal-box tw:transition-none'>
<button className='tw:btn tw:btn-sm tw:btn-circle tw:btn-ghost tw:absolute tw:right-2 tw:top-2 tw:focus:outline-hidden'>
</button>
{children}
</form>
<form method='dialog' className='tw:modal-backdrop'>
<button>close</button>
</form>
</dialog>
</>
<dialog id="my_modal_3" className="tw:modal tw:transition-all tw:duration-300">
<div className="tw:modal-box tw:transition-none">
<button
className="tw:btn tw:btn-sm tw:btn-circle tw:btn-ghost tw:absolute tw:right-2 tw:top-2"
onClick={() => window.my_modal_3?.close()}
>
</button>
{children}
</div>
<form method="dialog" className="tw:modal-backdrop">
<button>close</button>
</form>
</dialog>
)
}
}

View File

View File

@ -0,0 +1,156 @@
import { useState } from 'react'
import SVG from 'react-inlinesvg'
import { Link, useNavigate } from 'react-router-dom'
import { useLayers } from '#components/Map/hooks/useLayers'
import { AvatarWidget } from '#components/Profile/Subcomponents/AvatarWidget'
import type { LayerProps } from '#src/index'
// Schritt-Komponenten
const Step1 = () => {
const layers = useLayers()
return (
<div>
<h2 className='tw:text-lg tw:font-bold tw:mb-2'>
Willkommen auf der Karte der Menschlich Wirtschaften eG
</h2>
<p className='tw:mb-2'>
Diese interaktiven Karte zeigt das Netzwerk von Menschlich Wirtschaften eG.
</p>
<p className='tw:mb-4'>Hier findest du verschiedene Layer:</p>
{layers.map((layer: LayerProps) => (
<span className='tw:flex tw:flex-row tw:mt-2 tw:pl-4' key={layer.name}>
<SVG
src={layer.menuIcon}
className='tw:w-6 tw:h-6 tw:mr-2'
preProcessor={(code: string) => code.replace(/fill=".*?"/g, 'fill="currentColor"')}
/>
<p>{layer.name}</p>
</span>
))}
<p className='tw:mt-4'>Erstelle dir im nächsten Schritt dein Profil zu erstellen </p>
</div>
)
}
const Step2 = () => {
const [userName, setUserName] = useState<string>('')
const [email, setEmail] = useState<string>('')
const [password, setPassword] = useState<string>('')
return (
<div className='tw:space-y-2'>
<h3 className='tw:text-lg tw:font-bold'>Erstelle dir deinen Acount</h3>
<p className='tw:my-4'>
Werde Teil des Netzwerks und erstelle dir dein Profil und zeige dich auf der Karte!
</p>
<input
type='text'
placeholder='Name'
value={userName}
onChange={(e) => setUserName(e.target.value)}
className='tw:input tw:input-bordered tw:w-full tw:max-w-xs'
/>
<input
type='email'
placeholder='E-Mail'
value={email}
onChange={(e) => setEmail(e.target.value)}
className='tw:input tw:input-bordered tw:w-full tw:max-w-xs'
/>
<input
type='password'
placeholder='Password'
onChange={(e) => setPassword(e.target.value)}
className='tw:input tw:input-bordered tw:w-full tw:max-w-xs'
/>
<p className='tw:mt-4 tw:mb-8'>
Du hast schon einen Account?{' '}
<Link
className='tw:inline-block tw:hover:text-primary tw:hover:underline tw:hover:cursor-pointer tw:transition tw:duration-200 tw:text-primary'
onClick={() => close()}
to='/login'
>
Dann logge dich ein!
</Link>
</p>
</div>
)
}
const Step3 = () => {
const [avatar, setAvatar] = useState<string>('')
return (
<div>
<h3 className='tw:text-lg tw:font-bold tw:text-center'>Lade ein Bild von dir hoch</h3>
<div className='tw:mt-4 tw:flex tw:justify-center tw:items-center'>
<AvatarWidget avatar={avatar} setAvatar={setAvatar} />
</div>
<div className='tw:mt-4 tw:flex tw:justify-center'>
<button className='tw:btn tw:justify-center' onClick={() => setAvatar('')}>
Select
</button>
</div>
</div>
)
}
const Step4 = () => (
<div>
<h3 className='tw:text-lg tw:font-bold'>Place your Profile on the Map!</h3>
<p>Let&apos;s get started! Add your first project or profile.</p>
</div>
)
const stepsTitles = ['Willkommen', 'Account', 'Avatar', 'Marker']
export const Onboarding = () => {
const close = () => {
navigate('/')
}
const navigate = useNavigate()
const [stepIndex, setStepIndex] = useState(0)
const steps = [<Step1 key={1} />, <Step2 key={2} />, <Step3 key={3} />, <Step4 key={4} />]
const isLast = stepIndex === steps.length - 1
const isFirst = stepIndex === 0
return (
<div className='tw:max-w-xl tw:w-full tw:mx-auto tw:p-4'>
<div>
{steps[stepIndex]}
<div className='tw:flex tw:justify-between tw:mt-6'>
<button
className={`${isFirst ? 'tw:invisible' : 'tw:btn'}`}
onClick={() => setStepIndex((i) => i - 1)}
>
Back
</button>
<div className='tw:flex tw:items-center tw:justify-center tw:my-4 tw:gap-2'>
{Array.from({ length: steps.length }).map((_, i) => (
<div
key={i}
className={`tw:w-3 tw:h-3 tw:rounded-full ${
i <= stepIndex ? 'tw:bg-primary' : 'tw:bg-gray-300'
}`}
></div>
))}
</div>
{!isLast ? (
<button className='tw:btn tw:btn-primary' onClick={() => setStepIndex((i) => i + 1)}>
Next
</button>
) : (
<button className='tw:btn tw:btn-success' onClick={() => close()}>
Close
</button>
)}
</div>
</div>
</div>
)
}

View File

@ -0,0 +1 @@
export { Onboarding } from './Onboarding'

View File

@ -169,7 +169,7 @@ export const AvatarWidget: React.FC<AvatarWidgetProps> = ({ avatar, setAvatar })
className='tw:file-input tw:w-full tw:max-w-xs'
onChange={onImageChange}
/>
<div className='button tw:btn tw:btn-lg tw:btn-circle tw:animate-none'>
<div className='button tw:mt-2 tw:ml-2 tw:btn tw:btn-lg tw:btn-circle tw:animate-none'>
<ArrowUpTrayIcon className='tw:w-6 tw:h-6' />
</div>
{avatar ? (

View File

@ -9,10 +9,12 @@ export * from './Components/Gaming'
export * from './Components/Templates'
export * from './Components/Input'
export * from './Components/Item'
export * from './Components/Onboarding'
declare global {
interface Window {
my_modal_3: {
[x: string]: any
showModal(): void
}
}