utopia-ui/src/Components/Profile/ProfileForm.tsx
Anton Tranelis 9e6bcf1846
fix(source): update tailwind and daisyui (#196)
* removed daisy from config

* removed tw-elements artefact

* removed comments from tailwind config

* removed safelist

* migrated to tailwind4 and daisyui5

* deleted tailwind.config.js which is not eeded anymore

* 3.0.79

* version number

* fixed broken layouts

* more fixing

* more layout fixing

* tested theming

* small fixes

* adapt snapshots to changes

* package.json: add unit test update script

* more ui refactoring & theme controller

* ui improvements

* package-lock.json

* fix linting

* fixed tabs

* fix linting

* fixed typing

---------

Co-authored-by: mahula <lenzmath@posteo.de>
2025-04-25 16:03:42 +02:00

225 lines
7.1 KiB
TypeScript

/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { useEffect, useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import { toast } from 'react-toastify'
import { useAuth } from '#components/Auth/useAuth'
import { useItems, useUpdateItem, useAddItem } from '#components/Map/hooks/useItems'
import { useLayers } from '#components/Map/hooks/useLayers'
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
import { useAddTag, useGetItemTags, useTags } from '#components/Map/hooks/useTags'
import { MapOverlayPage } from '#components/Templates'
import { linkItem, onUpdateItem, unlinkItem } from './itemFunctions'
import { FormHeader } from './Subcomponents/FormHeader'
import { FlexForm } from './Templates/FlexForm'
import { OnepagerForm } from './Templates/OnepagerForm'
import { SimpleForm } from './Templates/SimpleForm'
import { TabsForm } from './Templates/TabsForm'
import type { FormState } from '#types/FormState'
import type { Item } from '#types/Item'
import type { Tag } from '#types/Tag'
/**
* @category Profile
*/
export function ProfileForm() {
const [state, setState] = useState<FormState>({
color: '',
id: '',
group_type: 'wuerdekompass',
status: 'active',
name: '',
subname: '',
text: '',
contact: '',
telephone: '',
next_appointment: '',
image: '',
marker_icon: '',
offers: [] as Tag[],
needs: [] as Tag[],
relations: [] as Item[],
start: '',
end: '',
openCollectiveSlug: '',
})
const [updatePermission, setUpdatePermission] = useState<boolean>(false)
const [loading, setLoading] = useState<boolean>(false)
const [item, setItem] = useState<Item>({} as Item)
const { user } = useAuth()
const updateItem = useUpdateItem()
const addItem = useAddItem()
const layers = useLayers()
const location = useLocation()
const tags = useTags()
const addTag = useAddTag()
const navigate = useNavigate()
const hasUserPermission = useHasUserPermission()
const getItemTags = useGetItemTags()
const items = useItems()
const [urlParams, setUrlParams] = useState(new URLSearchParams(location.search))
useEffect(() => {
item && hasUserPermission('items', 'update', item) && setUpdatePermission(true)
}, [hasUserPermission, item])
useEffect(() => {
const itemId = location.pathname.split('/')[2]
const item = items.find((i) => i.id === itemId)
item && setItem(item)
if (!item) {
if (items.some((i) => i.user_created?.id === user?.id && i.layer?.userProfileLayer)) {
navigate('/')
toast.error('Item does not exist')
} else {
const layer = layers.find((l) => l.userProfileLayer)
setItem({
id: crypto.randomUUID(),
name: user?.first_name ?? '',
text: '',
layer,
new: true,
})
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [items])
useEffect(() => {
const newColor =
item.color ??
(getItemTags(item) && getItemTags(item)[0]?.color
? getItemTags(item)[0].color
: item.layer?.markerDefaultColor)
const offers = (item.offers ?? []).reduce((acc: Tag[], o) => {
const offer = tags.find((t) => t.id === o.tags_id)
if (offer) acc.push(offer)
return acc
}, [])
const needs = (item.needs ?? []).reduce((acc: Tag[], o) => {
const need = tags.find((t) => t.id === o.tags_id)
if (need) acc.push(need)
return acc
}, [])
const relations = (item.relations ?? []).reduce((acc: Item[], r) => {
const relatedItem = items.find((i) => i.id === r.related_items_id)
if (relatedItem) acc.push(relatedItem)
return acc
}, [])
setState({
color: newColor ?? '',
id: item?.id ?? '',
group_type: item?.group_type ?? '',
status: item?.status ?? '',
name: item?.name ?? '',
subname: item?.subname ?? '',
text: item?.text ?? '',
contact: item?.contact ?? '',
telephone: item?.telephone ?? '',
next_appointment: item?.next_appointment ?? '',
image: item?.image ?? '',
// Do we actually mean marker_icon here?
marker_icon: item?.markerIcon ?? '',
offers,
needs,
relations,
start: item.start ?? '',
end: item.end ?? '',
openCollectiveSlug: item.openCollectiveSlug ?? '',
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [item, tags, items])
const [template, setTemplate] = useState<string>('')
useEffect(() => {
if (item.layer?.itemType.template) setTemplate(item.layer?.itemType.template)
else {
const userLayer = layers.find((l) => l.userProfileLayer === true)
if (userLayer) setTemplate(userLayer.itemType.template)
}
}, [item, layers])
return (
<>
<MapOverlayPage
backdrop
className='tw:mx-4 tw:mt-4 tw:mb-4 tw:overflow-x-hidden tw:w-[calc(100%-32px)] tw:md:w-[calc(50%-32px)] tw:max-w-3xl tw:left-auto! tw:top-0 tw:bottom-0'
>
<form
className='tw:h-full'
onSubmit={(e) => {
e.preventDefault()
void onUpdateItem(
state,
item,
tags,
addTag,
setLoading,
navigate,
updateItem,
addItem,
user,
urlParams,
)
}}
>
<div className='tw:flex tw:flex-col tw:h-full'>
<FormHeader item={item} state={state} setState={setState} />
{template === 'onepager' && (
<OnepagerForm item={item} state={state} setState={setState}></OnepagerForm>
)}
{template === 'simple' && <SimpleForm state={state} setState={setState}></SimpleForm>}
{template === 'flex' && (
<FlexForm item={item} state={state} setState={setState}></FlexForm>
)}
{template === 'tabs' && (
<TabsForm
loading={loading}
item={item}
state={state}
setState={setState}
updatePermission={updatePermission}
linkItem={(id) => linkItem(id, item, updateItem)}
unlinkItem={(id) => unlinkItem(id, item, updateItem)}
setUrlParams={setUrlParams}
></TabsForm>
)}
<div className='tw:mt-4 tw:flex-none'>
<button
className={`${loading ? ' tw:loading tw:btn tw:float-right' : 'tw:btn tw:float-right'}`}
type='submit'
style={{
// We could refactor this, it is used several times at different locations
backgroundColor: `${item.color ?? (getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item?.layer?.markerDefaultColor)}`,
color: '#fff',
}}
>
Update
</button>
</div>
</div>
</form>
</MapOverlayPage>
</>
)
}