diff --git a/package-lock.json b/package-lock.json index eeeb13f3..cf3dde9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "utopia-ui", "version": "3.0.10", - "license": "MIT", + "license": "GPL-3.0-only", "dependencies": { "@heroicons/react": "^2.0.17", "@tanstack/react-query": "^5.17.8", diff --git a/src/Components/AppShell/AppShell.tsx b/src/Components/AppShell/AppShell.tsx index 5827a2b8..3d5acebc 100644 --- a/src/Components/AppShell/AppShell.tsx +++ b/src/Components/AppShell/AppShell.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import NavBar from './NavBar' -import { SetAssetsApi } from './SetAssetsApi' +import { SetAppState } from './SetAppState' import { AssetsApi } from '../../types' import { ContextWrapper } from './ContextWrapper' @@ -18,7 +18,7 @@ export function AppShell({ return (
- +
{children} diff --git a/src/Components/AppShell/ContextWrapper.tsx b/src/Components/AppShell/ContextWrapper.tsx index 9cae2738..b93d6593 100644 --- a/src/Components/AppShell/ContextWrapper.tsx +++ b/src/Components/AppShell/ContextWrapper.tsx @@ -9,7 +9,7 @@ import { LeafletRefsProvider } from '../Map/hooks/useLeafletRefs' import { PermissionsProvider } from '../Map/hooks/usePermissions' import { SelectPositionProvider } from '../Map/hooks/useSelectPosition' import { TagsProvider } from '../Map/hooks/useTags' -import { AssetsProvider } from './hooks/useAssets' +import { AppStateProvider } from './hooks/useAppState' import { useContext, createContext } from 'react' import { BrowserRouter as Router, useLocation } from 'react-router-dom' @@ -71,7 +71,7 @@ export const Wrappers = ({ children }) => { - + { {children} - + diff --git a/src/Components/AppShell/SetAppState.tsx b/src/Components/AppShell/SetAppState.tsx new file mode 100644 index 00000000..fb0275de --- /dev/null +++ b/src/Components/AppShell/SetAppState.tsx @@ -0,0 +1,24 @@ +import { useSetAppState } from './hooks/useAppState' +import { AssetsApi } from '../../types' +import { useEffect } from 'react' + +export const SetAppState = ({ + assetsApi, + userType, +}: { + assetsApi: AssetsApi + userType: string +}) => { + const setAppState = useSetAppState() + + useEffect(() => { + setAppState({ assetsApi }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [assetsApi]) + + useEffect(() => { + setAppState({ userType }) + }, [setAppState, userType]) + + return <> +} diff --git a/src/Components/AppShell/SetAssetsApi.tsx b/src/Components/AppShell/SetAssetsApi.tsx deleted file mode 100644 index d1a69d3d..00000000 --- a/src/Components/AppShell/SetAssetsApi.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useSetAssetApi } from './hooks/useAssets' -import { AssetsApi } from '../../types' -import { useEffect } from 'react' - -export const SetAssetsApi = ({ assetsApi }: { assetsApi: AssetsApi }) => { - const setAssetsApi = useSetAssetApi() - - useEffect(() => { - setAssetsApi(assetsApi) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [assetsApi]) - - return <> -} diff --git a/src/Components/AppShell/hooks/useAppState.tsx b/src/Components/AppShell/hooks/useAppState.tsx new file mode 100644 index 00000000..0124fb9d --- /dev/null +++ b/src/Components/AppShell/hooks/useAppState.tsx @@ -0,0 +1,50 @@ +import { useCallback, useState, createContext, useContext } from 'react' +import * as React from 'react' +import { AssetsApi } from '../../../types' + +type AppState = { + assetsApi: AssetsApi + userType: string +} + +type UseAppManagerResult = ReturnType + +const initialAppState: AppState = { + assetsApi: {} as AssetsApi, + userType: '', +} + +const AppContext = createContext({ + state: initialAppState, + setAppState: () => {}, +}) + +function useAppManager(): { + state: AppState + setAppState: (newState: Partial) => void +} { + const [state, setState] = useState(initialAppState) + + const setAppState = useCallback((newState: Partial) => { + setState((prevState) => ({ + ...prevState, + ...newState, + })) + }, []) + + return { state, setAppState } +} + +export const AppStateProvider: React.FunctionComponent<{ + children?: React.ReactNode +}> = ({ children }) => {children} + +export const useAppState = (): AppState => { + const { state } = useContext(AppContext) + return state +} + +export const useSetAppState = (): UseAppManagerResult['setAppState'] => { + const { setAppState } = useContext(AppContext) + return setAppState +} diff --git a/src/Components/AppShell/hooks/useAssets.tsx b/src/Components/AppShell/hooks/useAssets.tsx deleted file mode 100644 index c3e4465e..00000000 --- a/src/Components/AppShell/hooks/useAssets.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { useCallback, useState, createContext, useContext } from 'react' - -import * as React from 'react' -import { AssetsApi } from '../../../types' - -type UseAssetManagerResult = ReturnType - -const AssetContext = createContext({ - api: {} as AssetsApi, - setAssetsApi: () => {}, -}) - -function useAssetsManager(): { - api: AssetsApi - setAssetsApi: (api: AssetsApi) => void -} { - const [api, setApi] = useState({} as AssetsApi) - - const setAssetsApi = useCallback((api: AssetsApi) => { - setApi(api) - }, []) - - return { api, setAssetsApi } -} - -export const AssetsProvider: React.FunctionComponent<{ - children?: React.ReactNode -}> = ({ children }) => ( - {children} -) - -export const useAssetApi = (): AssetsApi => { - const { api } = useContext(AssetContext) - return api -} - -export const useSetAssetApi = (): UseAssetManagerResult['setAssetsApi'] => { - const { setAssetsApi } = useContext(AssetContext) - return setAssetsApi -} diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx index be0d5571..e6a9e03c 100644 --- a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx +++ b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx @@ -2,7 +2,7 @@ import * as React from 'react' import { Item, ItemsApi } from '../../../../types' import { useHasUserPermission } from '../../hooks/usePermissions' import { getValue } from '../../../../Utils/GetValue' -import { useAssetApi } from '../../../AppShell/hooks/useAssets' +import { useAppState } from '../../../AppShell/hooks/useAppState' import DialogModal from '../../../Templates/DialogModal' import { useNavigate } from 'react-router-dom' @@ -41,17 +41,17 @@ export function HeaderView({ const hasUserPermission = useHasUserPermission() const navigate = useNavigate() - const assetsApi = useAssetApi() + const appState = useAppState() const avatar = itemAvatarField && getValue(item, itemAvatarField) - ? assetsApi.url + + ? appState.assetsApi.url + getValue(item, itemAvatarField) + `${big ? '?width=160&heigth=160' : '?width=80&heigth=80'}` : item.layer?.itemAvatarField && item && getValue(item, item.layer?.itemAvatarField) && - assetsApi.url + + appState.assetsApi.url + getValue(item, item.layer?.itemAvatarField) + `${big ? '?width=160&heigth=160' : '?width=80&heigth=80'}` const title = itemNameField diff --git a/src/Components/Profile/ProfileForm.tsx b/src/Components/Profile/ProfileForm.tsx index 03ea4271..97c0794d 100644 --- a/src/Components/Profile/ProfileForm.tsx +++ b/src/Components/Profile/ProfileForm.tsx @@ -1,4 +1,3 @@ -/* eslint-disable no-constant-condition */ import { useItems, useUpdateItem, useAddItem } from '../Map/hooks/useItems' import { useEffect, useState } from 'react' import { getValue } from '../../Utils/GetValue' @@ -14,21 +13,23 @@ import { linkItem, onUpdateItem, unlinkItem } from './itemFunctions' import { SimpleForm } from './Templates/SimpleForm' import { TabsForm } from './Templates/TabsForm' import { FormHeader } from './Subcomponents/FormHeader' +import { useAppState } from '../AppShell/hooks/useAppState' +import { FlexForm } from './Templates/FlexForm' -export function ProfileForm({ userType }: { userType: string }) { +export function ProfileForm() { const [state, setState] = useState({ color: '', id: '', - groupType: 'wuerdekompass', + group_type: 'wuerdekompass', status: 'active', name: '', subname: '', text: '', contact: '', telephone: '', - nextAppointment: '', + next_appointment: '', image: '', - markerIcon: '', + marker_icon: '', offers: [] as Tag[], needs: [] as Tag[], relations: [] as Item[], @@ -50,13 +51,13 @@ export function ProfileForm({ userType }: { userType: string }) { const hasUserPermission = useHasUserPermission() const getItemTags = useGetItemTags() const items = useItems() + const appState = useAppState() const [urlParams, setUrlParams] = useState(new URLSearchParams(location.search)) useEffect(() => { item && hasUserPermission('items', 'update', item) && setUpdatePermission(true) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [item]) + }, [hasUserPermission, item]) useEffect(() => { const itemId = location.pathname.split('/')[2] @@ -64,9 +65,8 @@ export function ProfileForm({ userType }: { userType: string }) { const item = items.find((i) => i.id === itemId) item && setItem(item) - const layer = layers.find((l) => l.itemType.name === userType) - - !item && + if (!item) { + const layer = layers.find((l) => l.itemType.name === appState.userType) setItem({ id: crypto.randomUUID(), name: user ? user.first_name : '', @@ -74,6 +74,7 @@ export function ProfileForm({ userType }: { userType: string }) { layer, new: true, }) + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [items]) @@ -107,16 +108,16 @@ export function ProfileForm({ userType }: { userType: string }) { setState({ color: newColor, id: item?.id ?? '', - groupType: item?.group_type ?? 'wuerdekompass', + group_type: item?.group_type ?? 'wuerdekompass', status: item?.status ?? 'active', name: item?.name ?? '', subname: item?.subname ?? '', text: item?.text ?? '', contact: item?.contact ?? '', telephone: item?.telephone ?? '', - nextAppointment: item?.next_appointment ?? '', + next_appointment: item?.next_appointment ?? '', image: item?.image ?? '', - markerIcon: item?.marker_icon ?? '', + marker_icon: item?.marker_icon ?? '', offers, needs, relations, @@ -129,8 +130,8 @@ export function ProfileForm({ userType }: { userType: string }) { const [template, setTemplate] = useState('') useEffect(() => { - setTemplate(item.layer?.itemType.template || userType) - }, [userType, item]) + setTemplate(item.layer?.itemType.template || appState.userType) + }, [appState.userType, item]) return ( <> @@ -147,6 +148,10 @@ export function ProfileForm({ userType }: { userType: string }) { {template === 'simple' && } + {template === 'flex' && ( + + )} + {template === 'tabs' && ( Update diff --git a/src/Components/Profile/ProfileView.tsx b/src/Components/Profile/ProfileView.tsx index a85a31fd..c0e73fa5 100644 --- a/src/Components/Profile/ProfileView.tsx +++ b/src/Components/Profile/ProfileView.tsx @@ -16,14 +16,10 @@ import { OnepagerView } from './Templates/OnepagerView' import { SimpleView } from './Templates/SimpleView' import { handleDelete, linkItem, unlinkItem } from './itemFunctions' import { useTags } from '../Map/hooks/useTags' +import { FlexView } from './Templates/FlexView' +import { useAppState } from '../AppShell/hooks/useAppState' -export function ProfileView({ - userType, - attestationApi, -}: { - userType: string - attestationApi?: ItemsApi -}) { +export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi }) { const [item, setItem] = useState() const [updatePermission, setUpdatePermission] = useState(false) const [relations, setRelations] = useState>([]) @@ -44,6 +40,7 @@ export function ProfileView({ const setSelectPosition = useSetSelectPosition() const clusterRef = useClusterRef() const leafletRefs = useLeafletRefs() + const appState = useAppState() const [attestations, setAttestations] = useState>([]) @@ -149,8 +146,8 @@ export function ProfileView({ }, [selectPosition]) useEffect(() => { - setTemplate(item?.layer?.itemType.template || userType) - }, [userType, item]) + setTemplate(item?.layer?.itemType.template || appState.userType) + }, [appState.userType, item]) return ( <> @@ -176,13 +173,14 @@ export function ProfileView({ />
- {template === 'onepager' && } + {template === 'onepager' && } {template === 'simple' && } + {template === 'flex' && } + {template === 'tabs' && ( = ({ avatar, setAvatar }) const [cropModalOpen, setCropModalOpen] = useState(false) const [cropping, setCropping] = useState(false) - const assetsApi = useAssetApi() + const appState = useAppState() const imgRef = useRef(null) @@ -146,10 +146,10 @@ export const AvatarWidget: React.FC = ({ avatar, setAvatar }) ctx?.drawImage(img, 0, 0, 400, 400) const resizedBlob = await canvas.convertToBlob() - const asset = await assetsApi.upload(resizedBlob, 'avatar') + const asset = await appState.assetsApi.upload(resizedBlob, 'avatar') setAvatar(asset.id) }, - [assetsApi, setAvatar], + [appState.assetsApi, setAvatar], ) return ( @@ -180,7 +180,10 @@ export const AvatarWidget: React.FC = ({ avatar, setAvatar })
{avatar ? (
- +
) : (
diff --git a/src/Components/Profile/Subcomponents/ContactInfo.tsx b/src/Components/Profile/Subcomponents/ContactInfo.tsx index 70555384..33decfd7 100644 --- a/src/Components/Profile/Subcomponents/ContactInfo.tsx +++ b/src/Components/Profile/Subcomponents/ContactInfo.tsx @@ -1,33 +1,46 @@ import { Link } from 'react-router-dom' -import { useAssetApi } from '../../AppShell/hooks/useAssets' +import { useAppState } from '../../AppShell/hooks/useAppState' +import { Item } from '../../../types' +import { useEffect, useState } from 'react' +import { useItems } from '../../Map/hooks/useItems' -const ContactInfo = ({ - email, - telephone, - name, - avatar, - link, -}: { - email: string - telephone: string - name: string - avatar: string - link?: string -}) => { - const assetsApi = useAssetApi() +const ContactInfo = ({ item }: { item: Item }) => { + const appState = useAppState() + const [profileOwner, setProfileOwner] = useState() + const items = useItems() + + useEffect(() => { + console.log( + 'user:', + items.find( + (i) => + i.user_created?.id === item.user_created?.id && + i.layer?.itemType.name === appState.userType, + ), + ) + + setProfileOwner( + items.find( + (i) => + i.user_created?.id === item.user_created?.id && + i.layer?.itemType.name === appState.userType, + ), + ) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [item, items]) return (

Du hast Fragen?

- {avatar && ( - + {profileOwner?.image && ( +
{name}
@@ -36,11 +49,11 @@ const ContactInfo = ({ )}
-

{name}

- {email && ( +

{profileOwner?.name}

+ {item.contact && (

- {email} + {item.contact}

)} - {telephone && ( + {item.telephone && (

- {telephone} + {item.telephone}

)} diff --git a/src/Components/Profile/Subcomponents/ContactInfoForm.tsx b/src/Components/Profile/Subcomponents/ContactInfoForm.tsx new file mode 100644 index 00000000..dd91b893 --- /dev/null +++ b/src/Components/Profile/Subcomponents/ContactInfoForm.tsx @@ -0,0 +1,53 @@ +import * as React from 'react' +import { TextInput } from '../../Input' +import { FormState } from '../Templates/OnepagerForm' + +export const ContactInfoForm = ({ + state, + setState, +}: { + state: FormState + setState: React.Dispatch> +}) => { + return ( +
+
+ + + setState((prevState) => ({ + ...prevState, + contact: v, + })) + } + /> +
+ +
+ + + setState((prevState) => ({ + ...prevState, + telephone: v, + })) + } + /> +
+
+ ) +} diff --git a/src/Components/Profile/Subcomponents/GroupSubHeaderView.tsx b/src/Components/Profile/Subcomponents/GroupSubHeaderView.tsx new file mode 100644 index 00000000..25fa3170 --- /dev/null +++ b/src/Components/Profile/Subcomponents/GroupSubHeaderView.tsx @@ -0,0 +1,42 @@ +/* eslint-disable camelcase */ +import { Item } from '../../../types' +import SocialShareBar from './SocialShareBar' + +const statusMapping = { + in_planning: 'in Planung', + paused: 'pausiert', + active: 'aktiv', +} + +export const GroupSubHeaderView = ({ + item, + share_base_url, +}: { + item: Item + share_base_url: string +}) => ( +
+
+ {item.status && ( +
+ + + {statusMapping[item.status]} + +
+ )} + {item.group_type && ( +
+ + {item.group_type} + +
+ )} +
+
+ +
+
+) diff --git a/src/Components/Profile/Subcomponents/GroupSubheaderForm.tsx b/src/Components/Profile/Subcomponents/GroupSubheaderForm.tsx new file mode 100644 index 00000000..cb114d43 --- /dev/null +++ b/src/Components/Profile/Subcomponents/GroupSubheaderForm.tsx @@ -0,0 +1,102 @@ +import * as React from 'react' +import ComboBoxInput from '../../Input/ComboBoxInput' +import { Item } from '../../../types' +import { useEffect } from 'react' +import { FormState } from '../Templates/OnepagerForm' + +const typeMapping = [ + { value: 'wuerdekompass', label: 'Regional-Gruppe' }, + { value: 'themenkompass', label: 'Themen-Gruppe' }, + { value: 'liebevoll.jetzt', label: 'liebevoll.jetzt' }, +] +const statusMapping = [ + { value: 'active', label: 'aktiv' }, + { value: 'in_planning', label: 'in Planung' }, + { value: 'paused', label: 'pausiert' }, +] + +export const GroupSubheaderForm = ({ + state, + setState, + item, +}: { + state: FormState + setState: React.Dispatch> + item: Item +}) => { + useEffect(() => { + switch (state.group_type) { + case 'wuerdekompass': + setState((prevState) => ({ + ...prevState, + color: item?.layer?.menuColor || '#1A5FB4', + marker_icon: 'group', + image: '59e6a346-d1ee-4767-9e42-fc720fb535c9', + })) + break + case 'themenkompass': + setState((prevState) => ({ + ...prevState, + color: '#26A269', + marker_icon: 'group', + image: '59e6a346-d1ee-4767-9e42-fc720fb535c9', + })) + break + case 'liebevoll.jetzt': + setState((prevState) => ({ + ...prevState, + color: '#E8B620', + marker_icon: 'liebevoll.jetzt', + image: 'e735b96c-507b-471c-8317-386ece0ca51d', + })) + + break + default: + break + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [state.group_type]) + + return ( +
+
+ + + setState((prevState) => ({ + ...prevState, + group_type: v, + })) + } + /> +
+
+ + + setState((prevState) => ({ + ...prevState, + status: v, + })) + } + /> +
+
+ ) +} diff --git a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx index 213fefad..b4a37a29 100644 --- a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx +++ b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx @@ -1,7 +1,7 @@ import { useEffect } from 'react' import { getValue } from '../../../Utils/GetValue' import { Item } from '../../../types' -import { useAssetApi } from '../../AppShell/hooks/useAssets' +import { useAppState } from '../../AppShell/hooks/useAppState' export function LinkedItemsHeaderView({ item, @@ -20,15 +20,15 @@ export function LinkedItemsHeaderView({ loading?: boolean unlinkPermission: boolean }) { - const assetsApi = useAssetApi() + const appState = useAppState() const avatar = itemAvatarField && getValue(item, itemAvatarField) - ? assetsApi.url + getValue(item, itemAvatarField) + ? appState.assetsApi.url + getValue(item, itemAvatarField) : item.layer?.itemAvatarField && item && getValue(item, item.layer?.itemAvatarField) && - assetsApi.url + getValue(item, item.layer?.itemAvatarField) + appState.assetsApi.url + getValue(item, item.layer?.itemAvatarField) const title = itemNameField ? getValue(item, itemNameField) : item.layer?.itemNameField && item && getValue(item, item.layer?.itemNameField) diff --git a/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx b/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx deleted file mode 100644 index 24ef03db..00000000 --- a/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import SocialShareBar from './SocialShareBar' - -/* const flags = { - de: ( - - - - - - ), - at: ( - - - - - - ) -}; */ - -const statusMapping = { - in_planning: 'in Planung', - paused: 'pausiert', - active: 'aktiv', -} - -// eslint-disable-next-line react/prop-types -const SubHeader = ({ type, status, url, title }) => ( -
-
- {status && ( -
- - - {statusMapping[status]} - -
- )} - {type && ( -
- - {type} - -
- )} -
-
- -
-
-) - -export default SubHeader diff --git a/src/Components/Profile/Subcomponents/ProfileTextForm.tsx b/src/Components/Profile/Subcomponents/ProfileTextForm.tsx new file mode 100644 index 00000000..7079bd37 --- /dev/null +++ b/src/Components/Profile/Subcomponents/ProfileTextForm.tsx @@ -0,0 +1,48 @@ +/* eslint-disable camelcase */ +import * as React from 'react' +import { TextAreaInput } from '../../Input' +import { FormState } from '../Templates/OnepagerForm' +import { getValue } from '../../../Utils/GetValue' +import { useEffect, useState } from 'react' + +export const ProfileTextForm = ({ + state, + setState, + data_field, + section_name, +}: { + state: FormState + setState: React.Dispatch> + data_field?: string + section_name: string +}) => { + const [field, setField] = useState(data_field || 'text') + + useEffect(() => { + if (!data_field) { + setField('text') + } + }, [data_field]) + + return ( +
+ + + setState((prevState) => ({ + ...prevState, + [field]: v, + })) + } + inputStyle='tw-h-24' + /> +
+ ) +} diff --git a/src/Components/Profile/Subcomponents/ProfileTextView.tsx b/src/Components/Profile/Subcomponents/ProfileTextView.tsx new file mode 100644 index 00000000..27e25c4b --- /dev/null +++ b/src/Components/Profile/Subcomponents/ProfileTextView.tsx @@ -0,0 +1,23 @@ +/* eslint-disable camelcase */ +import { Item } from '../../../types' +import { getValue } from '../../../Utils/GetValue' +import { TextView } from '../../Map' + +export const ProfileTextView = ({ + item, + data_field, + section_name, +}: { + item: Item + data_field: string + section_name: string +}) => { + return ( +
+

{section_name}

+
+ +
+
+ ) +} diff --git a/src/Components/Profile/Templates/FlexForm.tsx b/src/Components/Profile/Templates/FlexForm.tsx new file mode 100644 index 00000000..6f916a7e --- /dev/null +++ b/src/Components/Profile/Templates/FlexForm.tsx @@ -0,0 +1,41 @@ +import * as React from 'react' +import { Item } from '../../../types' +import { FormState } from './OnepagerForm' +import { GroupSubheaderForm } from '../Subcomponents/GroupSubheaderForm' +import { ContactInfoForm } from '../Subcomponents/ContactInfoForm' +import { ProfileTextForm } from '../Subcomponents/ProfileTextForm' + +const componentMap = { + group_subheaders: GroupSubheaderForm, + texts: ProfileTextForm, + contact_infos: ContactInfoForm, + // weitere Komponenten hier +} + +export const FlexForm = ({ + item, + state, + setState, +}: { + state: FormState + setState: React.Dispatch> + item: Item +}) => { + return ( +
+ {item.layer?.itemType.profile_template.map((templateItem) => { + const TemplateComponent = componentMap[templateItem.collection] + return TemplateComponent ? ( + + ) : ( +
Component not found
+ ) + })} +
+ ) +} diff --git a/src/Components/Profile/Templates/FlexView.tsx b/src/Components/Profile/Templates/FlexView.tsx new file mode 100644 index 00000000..07afcafb --- /dev/null +++ b/src/Components/Profile/Templates/FlexView.tsx @@ -0,0 +1,27 @@ +import { GroupSubHeaderView } from '../Subcomponents/GroupSubHeaderView' +import ContactInfo from '../Subcomponents/ContactInfo' +import { ProfileTextView } from '../Subcomponents/ProfileTextView' +import { Item } from '../../../types' + +const componentMap = { + group_subheaders: GroupSubHeaderView, + texts: ProfileTextView, + contact_infos: ContactInfo, + // weitere Komponenten hier +} + +export const FlexView = ({ item }: { item: Item }) => { + console.log(item) + return ( +
+ {item.layer?.itemType.profile_template.map((templateItem) => { + const TemplateComponent = componentMap[templateItem.collection] + return TemplateComponent ? ( + + ) : ( +
Component not found
+ ) + })} +
+ ) +} diff --git a/src/Components/Profile/Templates/OnepagerForm.tsx b/src/Components/Profile/Templates/OnepagerForm.tsx index cc8e756b..2663747d 100644 --- a/src/Components/Profile/Templates/OnepagerForm.tsx +++ b/src/Components/Profile/Templates/OnepagerForm.tsx @@ -1,178 +1,40 @@ import * as React from 'react' -import { useEffect } from 'react' import { Item, Tag } from '../../../types' -import { TextAreaInput, TextInput } from '../../Input' -import ComboBoxInput from '../../Input/ComboBoxInput' +import { TextAreaInput } from '../../Input' +import { GroupSubheaderForm } from '../Subcomponents/GroupSubheaderForm' +import { ContactInfoForm } from '../Subcomponents/ContactInfoForm' + +export type FormState = { + color: string + id: string + group_type: string + status: string + name: string + subname: string + text: string + contact: string + telephone: string + next_appointment: string + image: string + marker_icon: string + offers: Tag[] + needs: Tag[] + relations: Item[] +} export const OnepagerForm = ({ item, state, setState, }: { - state: { - color: string - id: string - groupType: string - status: string - name: string - subname: string - text: string - contact: string - telephone: string - nextAppointment: string - image: string - markerIcon: string - offers: Tag[] - needs: Tag[] - relations: Item[] - } + state: FormState setState: React.Dispatch> item: Item }) => { - useEffect(() => { - switch (state.groupType) { - case 'wuerdekompass': - setState((prevState) => ({ - ...prevState, - color: item?.layer?.menuColor || '#1A5FB4', - markerIcon: 'group', - image: '59e6a346-d1ee-4767-9e42-fc720fb535c9', - })) - break - case 'themenkompass': - setState((prevState) => ({ - ...prevState, - color: '#26A269', - markerIcon: 'group', - image: '59e6a346-d1ee-4767-9e42-fc720fb535c9', - })) - break - case 'liebevoll.jetzt': - setState((prevState) => ({ - ...prevState, - color: '#E8B620', - markerIcon: 'liebevoll.jetzt', - image: 'e735b96c-507b-471c-8317-386ece0ca51d', - })) - - break - default: - break - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [state.groupType]) - - const typeMapping = [ - { value: 'wuerdekompass', label: 'Regional-Gruppe' }, - { value: 'themenkompass', label: 'Themen-Gruppe' }, - { value: 'liebevoll.jetzt', label: 'liebevoll.jetzt' }, - ] - const statusMapping = [ - { value: 'active', label: 'aktiv' }, - { value: 'in_planning', label: 'in Planung' }, - { value: 'paused', label: 'pausiert' }, - ] - return (
-
-
- - - setState((prevState) => ({ - ...prevState, - groupType: v, - })) - } - /> -
-
- - - setState((prevState) => ({ - ...prevState, - status: v, - })) - } - /> -
-
- -
- - - setState((prevState) => ({ - ...prevState, - contact: v, - })) - } - /> -
- -
- - - setState((prevState) => ({ - ...prevState, - telephone: v, - })) - } - /> -
- -
- - - setState((prevState) => ({ - ...prevState, - nextAppointment: v, - })) - } - inputStyle='tw-h-24' - /> -
+ +