mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-12-18 01:54:29 -05:00
feat(gui): Add a Introduction for new users (#287)
* feat(gui): add IntroductionModal component * feat(gui): add interactivity to IntroductionModal * feat(gui): create SlideTemplate component for IntroductionModal Slides * feat(gui): add generic slides to IntroductionModal with images and content * feat(gui): add Slide with SwapStatusAlert to IntroductionModal * feat(gui): show the introduction only on the first app start * feat(gui): make external links functional * fix(gui): update github link to link to active repo * feat(gui): replace old images with new mockups and update Slide05 content * feat(gui): add CardSelectionGroup and CardSelectionOption components for improved card selection UI * feat(gui): add FiatPricePreference slide to IntroductionModal * feat(gui): save user preference regarding fiat prices I set the initial store configuration for fetching fiat prices to false to avoid any calls to coingecko without user consent * refactor(gui): remove old Slide05 component for improved codebase maintenance * fix(gui): add UnstoppableSwap logo to FiatPricePreference slide * refactor(gui): update image imports and improve slide content for introduction modal * fix(gui): introduce ExternalLink component and update Slide05 to use it for external navigation * fix(gui): replace webp images for introduction with svg mockups for improved quality * fix(gui): change order of introduction slides, to asking for fiat price preference at the end * refactor(gui): implement CardSelectionContext for managing card selection state * refactor: texts in intro modakl * fix(gui): update currency fetching SVG for improved design and clarity * feat(gui): added changelog entry for introduction --------- Co-authored-by: Binarybaron <binarybaron@protonmail.com>
This commit is contained in:
parent
66313ad91f
commit
31e68b2671
25 changed files with 869 additions and 3 deletions
|
|
@ -0,0 +1,39 @@
|
|||
import { createContext, useContext, useState, ReactNode } from 'react'
|
||||
|
||||
interface CardSelectionContextType {
|
||||
selectedValue: string
|
||||
setSelectedValue: (value: string) => void
|
||||
}
|
||||
|
||||
const CardSelectionContext = createContext<CardSelectionContextType | undefined>(undefined)
|
||||
|
||||
export function CardSelectionProvider({
|
||||
children,
|
||||
initialValue,
|
||||
onChange
|
||||
}: {
|
||||
children: ReactNode
|
||||
initialValue: string
|
||||
onChange?: (value: string) => void
|
||||
}) {
|
||||
const [selectedValue, setSelectedValue] = useState(initialValue)
|
||||
|
||||
const handleValueChange = (value: string) => {
|
||||
setSelectedValue(value)
|
||||
onChange?.(value)
|
||||
}
|
||||
|
||||
return (
|
||||
<CardSelectionContext.Provider value={{ selectedValue, setSelectedValue: handleValueChange }}>
|
||||
{children}
|
||||
</CardSelectionContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useCardSelection() {
|
||||
const context = useContext(CardSelectionContext)
|
||||
if (context === undefined) {
|
||||
throw new Error('useCardSelection must be used within a CardSelectionProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import { Box } from '@material-ui/core'
|
||||
import CheckIcon from '@material-ui/icons/Check'
|
||||
import { CardSelectionProvider } from './CardSelectionContext'
|
||||
|
||||
interface CardSelectionGroupProps {
|
||||
children: React.ReactElement<{ value: string }>[]
|
||||
value: string
|
||||
onChange: (value: string) => void
|
||||
}
|
||||
|
||||
export default function CardSelectionGroup({
|
||||
children,
|
||||
value,
|
||||
onChange,
|
||||
}: CardSelectionGroupProps) {
|
||||
return (
|
||||
<CardSelectionProvider initialValue={value} onChange={onChange}>
|
||||
<Box style={{ display: 'flex', flexDirection: 'column', gap: 12, marginTop: 12 }}>
|
||||
{children}
|
||||
</Box>
|
||||
</CardSelectionProvider>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import { Box } from "@material-ui/core";
|
||||
import CheckIcon from '@material-ui/icons/Check'
|
||||
import { useCardSelection } from './CardSelectionContext'
|
||||
|
||||
// The value prop is used by the parent CardSelectionGroup to determine which option is selected
|
||||
export default function CardSelectionOption({children, value}: {children: React.ReactNode, value: string}) {
|
||||
const { selectedValue, setSelectedValue } = useCardSelection()
|
||||
const selected = value === selectedValue
|
||||
|
||||
return (
|
||||
<Box
|
||||
onClick={() => setSelectedValue(value)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
gap: 16,
|
||||
border: selected ? '2px solid #FF5C1B' : '2px solid #555',
|
||||
borderRadius: 16,
|
||||
padding: '1em',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
border: selected ? '2px solid #FF5C1B' : '2px solid #555',
|
||||
borderRadius: 99999,
|
||||
width: 28,
|
||||
height: 28,
|
||||
background: selected ? '#FF5C1B' : 'transparent',
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
transform: selected ? 'scale(1.1)' : 'scale(1)',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
{selected ? (
|
||||
<CheckIcon
|
||||
style={{
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
transform: 'scale(1)',
|
||||
animation: 'checkIn 0.2s ease-in-out'
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</Box>
|
||||
<Box pt={0.5}>{children}</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue