mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-01-16 01:44:43 +00:00
adjust invitepage
This commit is contained in:
parent
c1da299732
commit
eeb55832e1
@ -28,6 +28,7 @@ export function AppShell({
|
||||
<ContextWrapper>
|
||||
<div className='tw:flex tw:flex-col tw:h-full'>
|
||||
<SetAppState
|
||||
appName={appName}
|
||||
assetsApi={assetsApi}
|
||||
embedded={embedded}
|
||||
openCollectiveApiKey={openCollectiveApiKey}
|
||||
|
||||
@ -5,11 +5,13 @@ import { useSetAppState } from './hooks/useAppState'
|
||||
import type { AssetsApi } from '#types/AssetsApi'
|
||||
|
||||
export const SetAppState = ({
|
||||
appName,
|
||||
assetsApi,
|
||||
embedded,
|
||||
openCollectiveApiKey,
|
||||
hideSignup,
|
||||
}: {
|
||||
appName: string
|
||||
assetsApi: AssetsApi
|
||||
embedded?: boolean
|
||||
openCollectiveApiKey?: string
|
||||
@ -17,6 +19,10 @@ export const SetAppState = ({
|
||||
}) => {
|
||||
const setAppState = useSetAppState()
|
||||
|
||||
useEffect(() => {
|
||||
setAppState({ appName })
|
||||
}, [appName, setAppState])
|
||||
|
||||
useEffect(() => {
|
||||
setAppState({ assetsApi })
|
||||
}, [assetsApi, setAppState])
|
||||
|
||||
@ -4,6 +4,7 @@ import { useCallback, useState, createContext, useContext } from 'react'
|
||||
import type { AssetsApi } from '#types/AssetsApi'
|
||||
|
||||
interface AppState {
|
||||
appName: string
|
||||
assetsApi: AssetsApi
|
||||
sideBarOpen: boolean
|
||||
sideBarSlim: boolean
|
||||
@ -16,6 +17,7 @@ interface AppState {
|
||||
type UseAppManagerResult = ReturnType<typeof useAppManager>
|
||||
|
||||
const initialAppState: AppState = {
|
||||
appName: '',
|
||||
assetsApi: {} as AssetsApi,
|
||||
sideBarOpen: false,
|
||||
sideBarSlim: false,
|
||||
|
||||
@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
import { useAppState } from '#components/AppShell/hooks/useAppState'
|
||||
import { useAuth } from '#components/Auth/useAuth'
|
||||
import { useUpdateItem } from '#components/Map/hooks/useItems'
|
||||
import { useMyProfile } from '#components/Map/hooks/useMyProfile'
|
||||
@ -24,6 +25,7 @@ export function InvitePage({ inviteApi, itemsApi }: Props) {
|
||||
const { id } = useParams<{ id: string }>()
|
||||
const navigate = useNavigate()
|
||||
const updateItem = useUpdateItem()
|
||||
const { appName } = useAppState()
|
||||
|
||||
const { myProfile, isUserProfileLayerLoaded, createEmptyProfile } = useMyProfile()
|
||||
|
||||
@ -172,23 +174,25 @@ export function InvitePage({ inviteApi, itemsApi }: Props) {
|
||||
if (isAuthenticated) {
|
||||
return (
|
||||
<MapOverlayPage backdrop className='tw:max-w-xs tw:h-fit'>
|
||||
<h2 className='tw-text-2xl tw-font-semibold tw-mb-2 tw-text-center'>Confirmation</h2>
|
||||
<h2 className='tw:text-2xl tw:font-semibold tw:mb-2 tw:text-center'>Confirmation</h2>
|
||||
{invitingProfile ? (
|
||||
<div className='tw-text-center tw-mb-4'>
|
||||
<p className='tw-text-sm tw-text-gray-600'>
|
||||
<>
|
||||
<p className='tw:text-sm tw:text-base-content/70 tw:text-center'>
|
||||
Do you want to follow <strong>{invitingProfile.name}</strong>?
|
||||
</p>
|
||||
<div className='tw-flex tw:justify-center tw:mt-4'>
|
||||
<button className='tw-btn tw-btn-primary' onClick={confirmFollow}>
|
||||
Yes
|
||||
</button>
|
||||
<button className='tw-btn tw-btn-secondary' onClick={goToStart}>
|
||||
<div className='tw:card-actions tw:justify-between'>
|
||||
<button className='tw:btn tw:btn-ghost' onClick={goToStart}>
|
||||
No
|
||||
</button>
|
||||
<button className='tw:btn tw:btn-primary' onClick={confirmFollow}>
|
||||
Yes
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p className='tw-text-center'>Validating invite...</p>
|
||||
<div className='tw:flex tw:justify-center'>
|
||||
<span className='tw:loading tw:loading-spinner tw:loading-md'></span>
|
||||
</div>
|
||||
)}
|
||||
</MapOverlayPage>
|
||||
)
|
||||
@ -196,25 +200,28 @@ export function InvitePage({ inviteApi, itemsApi }: Props) {
|
||||
|
||||
return (
|
||||
<MapOverlayPage backdrop className='tw:max-w-xs tw:h-fit'>
|
||||
<h2 className='tw:text-2xl tw:font-semibold tw:mb-2 tw:text-center'>Invitation</h2>
|
||||
{invitingProfile ? (
|
||||
<div className='tw-text-center tw-mb-4'>
|
||||
<p className='tw-text-lg tw-font-semibold'>Welcome to Utopia!</p>
|
||||
<p className='tw-text-sm tw-text-gray-600'>
|
||||
You have been invited by: <strong>{invitingProfile.name}</strong> to join the Utopia
|
||||
community.
|
||||
<>
|
||||
<h2 className='tw:text-2xl tw:font-semibold tw:mb-2 tw:text-center'>
|
||||
Welcome{appName && <> to {appName}</>}!
|
||||
</h2>
|
||||
<p className='tw:text-sm tw:text-base-content/70 tw:text-center'>
|
||||
You have been invited by <strong>{invitingProfile.name}</strong> to join{' '}
|
||||
{appName || 'the community'}.
|
||||
</p>
|
||||
<div className='tw-flex tw:justify-center tw:mt-4'>
|
||||
<button className='tw-btn tw-btn-primary' onClick={goToSignup}>
|
||||
{'Sign Up'}
|
||||
</button>
|
||||
<button className='tw-btn tw-btn-secondary' onClick={goToLogin}>
|
||||
<div className='tw:card-actions tw:justify-between'>
|
||||
<button className='tw:btn tw:btn-ghost' onClick={goToLogin}>
|
||||
Login
|
||||
</button>
|
||||
<button className='tw:btn tw:btn-primary' onClick={goToSignup}>
|
||||
Sign Up
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<p className='tw-text-center'>Validating invite...</p>
|
||||
<div className='tw:flex tw:justify-center'>
|
||||
<span className='tw:loading tw:loading-spinner tw:loading-md'></span>
|
||||
</div>
|
||||
)}
|
||||
</MapOverlayPage>
|
||||
)
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { MapPinIcon } from '@heroicons/react/24/solid'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import { useAppState } from '#components/AppShell/hooks/useAppState'
|
||||
import { useItems } from '#components/Map/hooks/useItems'
|
||||
import { useReverseGeocode } from '#components/Map/hooks/useReverseGeocode'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
@ -13,6 +15,35 @@ interface Props {
|
||||
hideWhenEmpty?: boolean
|
||||
}
|
||||
|
||||
function RelationCard({ item }: { item: Item }) {
|
||||
const appState = useAppState()
|
||||
const avatar = item.image ? appState.assetsApi.url + item.image : null
|
||||
|
||||
const { address } = useReverseGeocode(
|
||||
item.position?.coordinates as [number, number] | undefined,
|
||||
true,
|
||||
'municipality',
|
||||
)
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={item.id}
|
||||
className='tw:flex tw:items-center tw:gap-3 tw:p-2 tw:rounded-lg tw:bg-base-200'
|
||||
>
|
||||
{avatar && (
|
||||
<div className='tw:avatar'>
|
||||
<div className='tw:w-12 tw:rounded-full'>
|
||||
<img src={avatar} alt={item.name ?? ''} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className='tw:flex-1 tw:min-w-0'>
|
||||
<div className='tw:font-bold tw:text-lg tw:truncate tw:text-base-content'>{item.name}</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
export const RelationsView = ({
|
||||
item,
|
||||
relation,
|
||||
@ -21,7 +52,6 @@ export const RelationsView = ({
|
||||
hideWhenEmpty = true,
|
||||
}: Props) => {
|
||||
const items = useItems()
|
||||
const appState = useAppState()
|
||||
|
||||
if (!item.relations) return
|
||||
|
||||
@ -60,32 +90,16 @@ export const RelationsView = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='tw:my-10 tw:mt-2 tw:px-6'>
|
||||
<h2 className='tw:text-lg tw:font-bold'>{heading}</h2>
|
||||
<div className='tw:my-4 tw:px-6'>
|
||||
<h2 className='tw:text-xl tw:font-bold tw:mb-3'>{heading}</h2>
|
||||
{hasRelatedItems ? (
|
||||
<ul>
|
||||
<div className='tw:grid tw:grid-cols-1 tw:@sm:grid-cols-2 tw:@lg:grid-cols-3 tw:gap-2'>
|
||||
{relatedItems.map((relatedItem) => (
|
||||
<li key={relatedItem.id}>
|
||||
<Link to={relatedItem.id} className='tw:flex tw:flex-row'>
|
||||
<div>
|
||||
{relatedItem.image ? (
|
||||
<img
|
||||
className='tw:size-10 tw:rounded-full'
|
||||
src={appState.assetsApi.url + '/' + relatedItem.image}
|
||||
/>
|
||||
) : (
|
||||
<div className='tw:size-10 tw:rounded-full tw:bg-gray-200' />
|
||||
)}
|
||||
</div>
|
||||
<div className='tw:ml-2 tw:flex tw:items-center tw:min-h-[2.5rem]'>
|
||||
<div>{relatedItem.name}</div>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
<RelationCard key={relatedItem.id} item={relatedItem} />
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
) : (
|
||||
<p>No related items found.</p>
|
||||
<p className='tw:text-base-content/70'>No related items found.</p>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user