mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-04-06 01:25:33 +00:00
Compare commits
8 Commits
a39e0cfdab
...
6684364ab5
| Author | SHA1 | Date | |
|---|---|---|---|
| 6684364ab5 | |||
| 560b612d90 | |||
| 08dfbe40ab | |||
| ce1f0a7f92 | |||
|
|
4fc9516715 | ||
| f7928f5cad | |||
| 99f11a054d | |||
|
|
8b7cff2b32 |
24
package-lock.json
generated
24
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "utopia-ui",
|
||||
"version": "3.0.76",
|
||||
"version": "3.0.78",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "utopia-ui",
|
||||
"version": "3.0.76",
|
||||
"version": "3.0.78",
|
||||
"license": "GPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
@ -18,6 +18,7 @@
|
||||
"radash": "^12.1.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-image-crop": "^10.1.8",
|
||||
"react-inlinesvg": "^4.2.0",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-leaflet-cluster": "^2.1.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
@ -10203,6 +10204,14 @@
|
||||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-from-dom": {
|
||||
"version": "0.7.5",
|
||||
"resolved": "https://registry.npmjs.org/react-from-dom/-/react-from-dom-0.7.5.tgz",
|
||||
"integrity": "sha512-CO92PmMKo/23uYPm6OFvh5CtZbMgHs/Xn+o095Lz/TZj9t8DSDhGdSOMLxBxwWI4sr0MF17KUn9yJWc5Q00R/w==",
|
||||
"peerDependencies": {
|
||||
"react": "16.8 - 19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-image-crop": {
|
||||
"version": "10.1.8",
|
||||
"resolved": "https://registry.npmjs.org/react-image-crop/-/react-image-crop-10.1.8.tgz",
|
||||
@ -10212,6 +10221,17 @@
|
||||
"react": ">=16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-inlinesvg": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-inlinesvg/-/react-inlinesvg-4.2.0.tgz",
|
||||
"integrity": "sha512-V59P6sFU7NACIbvoay9ikYKVFWyIIZFGd7w6YT1m+H7Ues0fOI6B6IftE6NPSYXXv7RHVmrncIyJeYurs3OJcA==",
|
||||
"dependencies": {
|
||||
"react-from-dom": "^0.7.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "16.8 - 19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "utopia-ui",
|
||||
"version": "3.0.76",
|
||||
"version": "3.0.78",
|
||||
"description": "Reuseable React Components to build mapping apps for real life communities and networks",
|
||||
"repository": "https://github.com/utopia-os/utopia-ui",
|
||||
"homepage": "https://utopia-os.org/",
|
||||
@ -99,6 +99,7 @@
|
||||
"radash": "^12.1.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-image-crop": "^10.1.8",
|
||||
"react-inlinesvg": "^4.2.0",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-leaflet-cluster": "^2.1.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
|
||||
@ -76,6 +76,7 @@ export default [
|
||||
'leaflet.locatecontrol/dist/L.Control.Locate.css',
|
||||
'yet-another-react-lightbox',
|
||||
'react-photo-album',
|
||||
'react-inlinesvg',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@ -15,9 +15,20 @@ import { TagsProvider } from '#components/Map/hooks/useTags'
|
||||
|
||||
import { AppStateProvider } from './hooks/useAppState'
|
||||
|
||||
import type { CloseButtonProps } from 'react-toastify'
|
||||
|
||||
// Helper context to determine if the ContextWrapper is already present.
|
||||
const ContextCheckContext = createContext(false)
|
||||
|
||||
const CloseButton = ({ closeToast }: CloseButtonProps) => (
|
||||
<button
|
||||
className='tw-btn tw-btn-sm tw-btn-circle tw-btn-ghost tw-absolute tw-right-2 tw-top-2 focus:tw-outline-none'
|
||||
onClick={closeToast}
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
)
|
||||
|
||||
export const ContextWrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
const isWrapped = useContext(ContextCheckContext)
|
||||
|
||||
@ -67,6 +78,7 @@ export const Wrappers = ({ children }) => {
|
||||
draggable
|
||||
pauseOnHover
|
||||
theme='light'
|
||||
closeButton={CloseButton}
|
||||
/>
|
||||
{children}
|
||||
</QuestsProvider>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
export * from './AppShell'
|
||||
export { SideBar } from './SideBar'
|
||||
export { Content } from './Content'
|
||||
export { default as SVG } from 'react-inlinesvg'
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import SVG from 'react-inlinesvg'
|
||||
|
||||
import PlusSVG from '#assets/plus.svg'
|
||||
import { useLayers } from '#components/Map/hooks/useLayers'
|
||||
import { useHasUserPermission } from '#components/Map/hooks/usePermissions'
|
||||
@ -31,7 +33,7 @@ export default function AddButton({
|
||||
{canAddItems() ? (
|
||||
<div className='tw-dropdown tw-dropdown-top tw-dropdown-end tw-dropdown-hover tw-z-500 tw-absolute tw-right-4 tw-bottom-4'>
|
||||
<label tabIndex={0} className='tw-z-500 tw-btn tw-btn-circle tw-shadow tw-bg-base-100'>
|
||||
<img src={PlusSVG} alt='Layers' className='tw-h-5 tw-w-5' />
|
||||
<SVG src={PlusSVG} className='tw-h-5 tw-w-5' />
|
||||
</label>
|
||||
<ul tabIndex={0} className='tw-dropdown-content tw-pr-1 tw-list-none'>
|
||||
{layers.map(
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import SVG from 'react-inlinesvg'
|
||||
|
||||
import LayerSVG from '#assets/layer.svg'
|
||||
import { useIsLayerVisible, useToggleVisibleLayer } from '#components/Map/hooks/useFilter'
|
||||
@ -56,7 +57,7 @@ export function LayerControl() {
|
||||
setOpen(true)
|
||||
}}
|
||||
>
|
||||
<img src={LayerSVG} alt='Layers' />
|
||||
<SVG src={LayerSVG} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
import { control } from 'leaflet'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import SVG from 'react-inlinesvg'
|
||||
import { useMap, useMapEvents } from 'react-leaflet'
|
||||
|
||||
import TargetSVG from '#assets/target.svg'
|
||||
@ -58,9 +59,8 @@ export const LocateControl = () => {
|
||||
{loading ? (
|
||||
<span className='tw-loading tw-loading-spinner tw-loading-md tw-mt-1'></span>
|
||||
) : (
|
||||
<img
|
||||
<SVG
|
||||
src={TargetSVG}
|
||||
alt='x'
|
||||
className='tw-mt-1 tw-p-[1px]'
|
||||
style={{ fill: `${active ? '#fc8702' : 'currentColor'}` }}
|
||||
/>
|
||||
|
||||
@ -15,6 +15,7 @@ import MagnifyingGlassIcon from '@heroicons/react/24/outline/MagnifyingGlassIcon
|
||||
import axios from 'axios'
|
||||
import { LatLng, LatLngBounds, marker } from 'leaflet'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import SVG from 'react-inlinesvg'
|
||||
import { useMap, useMapEvents } from 'react-leaflet'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
|
||||
@ -169,7 +170,7 @@ export const SearchControl = () => {
|
||||
{itemsResults.slice(0, 5).map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className='tw-cursor-pointer hover:tw-font-bold'
|
||||
className='tw-cursor-pointer hover:tw-font-bold tw-flex tw-flex-row'
|
||||
onClick={() => {
|
||||
const marker = Object.entries(leafletRefs).find((r) => r[1].item === item)?.[1]
|
||||
.marker
|
||||
@ -182,18 +183,25 @@ export const SearchControl = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className='tw-flex tw-flex-row'>
|
||||
<img
|
||||
src={item.layer?.menuIcon}
|
||||
className='tw-text-current tw-w-5 tw-mr-2 tw-mt-0'
|
||||
{item.layer?.menuIcon ? (
|
||||
<SVG
|
||||
src={item.layer.menuIcon}
|
||||
className='tw-text-current tw-mr-2 tw-mt-0 tw-w-5'
|
||||
preProcessor={(code: string): string => {
|
||||
code = code.replace(/fill=".*?"/g, 'fill="currentColor"')
|
||||
code = code.replace(/stroke=".*?"/g, 'stroke="currentColor"')
|
||||
return code
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<div className='tw-text-sm tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>
|
||||
{item.name}
|
||||
</div>
|
||||
<div className='tw-text-xs tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>
|
||||
{item.text}
|
||||
</div>
|
||||
) : (
|
||||
<div className='tw-w-5' />
|
||||
)}
|
||||
<div>
|
||||
<div className='tw-text-sm tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>
|
||||
{item.name}
|
||||
</div>
|
||||
<div className='tw-text-xs tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>
|
||||
{item.text}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -236,7 +244,7 @@ export const SearchControl = () => {
|
||||
hide()
|
||||
}}
|
||||
>
|
||||
<MagnifyingGlassIcon className='tw-text-current tw-mr-2 tw-mt-0 tw-w-4' />
|
||||
<MagnifyingGlassIcon className='tw-text-current tw-mr-2 tw-mt-0 tw-w-5' />
|
||||
<div>
|
||||
<div className='tw-text-sm tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>
|
||||
{geo?.properties.name ? geo?.properties.name : value}
|
||||
|
||||
@ -83,18 +83,13 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
toast.error(error.toString())
|
||||
}
|
||||
if (success) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(props.item)
|
||||
|
||||
updateItem({ ...props.item, ...formItem })
|
||||
toast.success('Item updated')
|
||||
}
|
||||
setSpinner(false)
|
||||
map.closePopup()
|
||||
} else {
|
||||
const item = items.find(
|
||||
(i) => i.user_created?.id === user?.id && i.layer?.id === props.layer.id,
|
||||
)
|
||||
const item = items.find((i) => i.user_created?.id === user?.id && i.layer === props.layer)
|
||||
|
||||
const uuid = crypto.randomUUID()
|
||||
let success = false
|
||||
|
||||
@ -13,6 +13,7 @@ import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon
|
||||
import PencilIcon from '@heroicons/react/24/solid/PencilIcon'
|
||||
import TrashIcon from '@heroicons/react/24/solid/TrashIcon'
|
||||
import { useState } from 'react'
|
||||
import SVG from 'react-inlinesvg'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import TargetDotSVG from '#assets/targetDot.svg'
|
||||
@ -159,7 +160,7 @@ export function HeaderView({
|
||||
className='!tw-text-base-content tw-cursor-pointer'
|
||||
onClick={setPositionCallback}
|
||||
>
|
||||
<img src={TargetDotSVG} alt='Position' className='tw-w-5 tw-h-5' />
|
||||
<SVG src={TargetDotSVG} className='tw-w-5 tw-h-5' />
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
|
||||
@ -75,10 +75,12 @@ export function UtopiaMapInner({
|
||||
<div>
|
||||
<TextView
|
||||
itemId=''
|
||||
rawText={'Support us building free opensource maps and help us grow 🌱☀️'}
|
||||
rawText={
|
||||
'Support us building free opensource maps for communities and help us grow 🌱☀️'
|
||||
}
|
||||
/>
|
||||
<a href='https://opencollective.com/utopia-project'>
|
||||
<div className='tw-btn tw-btn-sm tw-float-right'>Donate</div>
|
||||
<div className='tw-btn tw-btn-sm tw-float-right tw-btn-primary'>Donate</div>
|
||||
</a>
|
||||
</div>
|
||||
</>,
|
||||
|
||||
@ -45,6 +45,7 @@ export function ProfileForm() {
|
||||
relations: [] as Item[],
|
||||
start: '',
|
||||
end: '',
|
||||
openCollectiveSlug: '',
|
||||
})
|
||||
|
||||
const [updatePermission, setUpdatePermission] = useState<boolean>(false)
|
||||
@ -137,6 +138,7 @@ export function ProfileForm() {
|
||||
relations,
|
||||
start: item.start ?? '',
|
||||
end: item.end ?? '',
|
||||
openCollectiveSlug: item.openCollectiveSlug ?? '',
|
||||
})
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item, tags, items])
|
||||
|
||||
38
src/Components/Profile/Subcomponents/CrowdfundingForm.tsx
Normal file
38
src/Components/Profile/Subcomponents/CrowdfundingForm.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
import { TextInput } from '#components/Input'
|
||||
|
||||
import type { FormState } from '#types/FormState'
|
||||
|
||||
export const CrowdfundingForm = ({
|
||||
state,
|
||||
setState,
|
||||
}: {
|
||||
state: FormState
|
||||
setState: React.Dispatch<React.SetStateAction<any>>
|
||||
}) => {
|
||||
return (
|
||||
<div className='tw-mt-4 tw-space-y-4'>
|
||||
<div>
|
||||
<label
|
||||
htmlFor='OpenCollectiveSlug'
|
||||
className='tw-block tw-text-sm tw-font-medium tw-text-gray-500 tw-mb-1'
|
||||
>
|
||||
Open Collective Slug:
|
||||
</label>
|
||||
<TextInput
|
||||
placeholder='Open Collective Slug'
|
||||
type='text'
|
||||
required={false}
|
||||
defaultValue={state.openCollectiveSlug}
|
||||
updateFormValue={(v) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
openCollectiveSlug: v,
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -1,20 +1,185 @@
|
||||
import axios from 'axios'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
import type { Item } from '#types/Item'
|
||||
|
||||
interface AccountData {
|
||||
account: {
|
||||
name: string
|
||||
type: string
|
||||
stats: {
|
||||
balance: {
|
||||
valueInCents: number
|
||||
currency: string
|
||||
} | null
|
||||
totalAmountReceived: {
|
||||
valueInCents: number
|
||||
currency: string
|
||||
}
|
||||
totalAmountSpent: {
|
||||
valueInCents: number
|
||||
currency: string
|
||||
}
|
||||
contributionsCount: number
|
||||
contributorsCount: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface GraphQLResponse<T> {
|
||||
data?: T
|
||||
errors?: { message: string }[]
|
||||
}
|
||||
|
||||
const GET_TRANSACTIONS = `
|
||||
query GetAccountStats($slug: String!) {
|
||||
account(slug: $slug) {
|
||||
name
|
||||
type
|
||||
stats {
|
||||
balance {
|
||||
valueInCents
|
||||
currency
|
||||
}
|
||||
totalAmountReceived(net: true) {
|
||||
valueInCents
|
||||
currency
|
||||
}
|
||||
totalAmountSpent {
|
||||
valueInCents
|
||||
currency
|
||||
}
|
||||
contributionsCount
|
||||
contributorsCount
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const token = '9350b1eecb4c70f2b15d85e32df4d4cf3ea80a1f'
|
||||
|
||||
const graphqlClient = axios.create({
|
||||
baseURL: 'https://api.opencollective.com/graphql/v2',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
const formatCurrency = (valueInCents: number, currency: string) => {
|
||||
const value = valueInCents / 100
|
||||
const options: Intl.NumberFormatOptions = {
|
||||
style: 'currency',
|
||||
currency,
|
||||
...(Math.abs(value) >= 1000 ? { minimumFractionDigits: 0, maximumFractionDigits: 0 } : {}),
|
||||
}
|
||||
return new Intl.NumberFormat('de-DE', options).format(value)
|
||||
}
|
||||
|
||||
export const CrowdfundingView = ({ item }: { item: Item }) => {
|
||||
// Hier wird slug aus dem Item extrahiert.
|
||||
const slug = item.openCollectiveSlug
|
||||
|
||||
const [data, setData] = useState<AccountData | null>(null)
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
try {
|
||||
const response = await graphqlClient.post<GraphQLResponse<AccountData>>('', {
|
||||
query: GET_TRANSACTIONS,
|
||||
variables: { slug },
|
||||
})
|
||||
if (response.data.errors?.length) {
|
||||
setError(response.data.errors[0].message)
|
||||
} else {
|
||||
setData(response.data.data ?? null)
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Error) {
|
||||
setError(err.message)
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
if (slug) {
|
||||
void fetchData()
|
||||
}
|
||||
}, [slug])
|
||||
|
||||
if (!slug) return null
|
||||
|
||||
if (loading)
|
||||
return (
|
||||
<div className='tw-flex tw-justify-center'>
|
||||
<span className='tw-loading tw-loading-spinner tw-loading-lg tw-text-neutral-content'></span>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (error) {
|
||||
return <p className='tw-text-center tw-text-lg tw-text-red-500'>Error: {error}</p>
|
||||
}
|
||||
|
||||
if (!data?.account) {
|
||||
return (
|
||||
<p className='tw-text-center tw-text-lg tw-text-red-500'>
|
||||
No data available for this account.
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
const { stats } = data.account
|
||||
const balanceValueInCents = stats.balance?.valueInCents ?? 0
|
||||
const currency = stats.balance?.currency ?? 'USD'
|
||||
const currentBalance = balanceValueInCents
|
||||
|
||||
return (
|
||||
<div className='tw-mx-6 tw-mb-6'>
|
||||
<div className='tw-card tw-bg-base-200 tw-w-fit tw-shadow-xl'>
|
||||
<div className='tw-stats tw-bg-base-300'>
|
||||
<div className='tw-stat'>
|
||||
<div className='tw-stat-title'>Received</div>
|
||||
<div className='tw-stat-value'>$89,400</div>
|
||||
<div className='tw-stat-desc'>from 12 patrons</div>
|
||||
<div className='tw-card tw-bg-base-200 tw-w-fit tw-max-w-full tw-shadow'>
|
||||
<div className='tw-stats tw-bg-base-200 tw-stats-horizontal tw-rounded-b-none'>
|
||||
<div className='tw-stat tw-p-3'>
|
||||
<div className='tw-stat-title'>Current Balance</div>
|
||||
<div className='tw-stat-value tw-text-xl lg:tw-text-3xl'>
|
||||
{formatCurrency(currentBalance, currency)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='tw-stat'>
|
||||
<button className='tw-btn tw-btn-primary tw-place-self-center tw-text-white'>
|
||||
Support {item.name}
|
||||
<div className='tw-stat tw-p-3'>
|
||||
<div className='tw-stat-title'>Received</div>
|
||||
<div className='tw-stat-value tw-text-green-500 tw-text-xl lg:tw-text-3xl'>
|
||||
{formatCurrency(stats.totalAmountReceived.valueInCents, currency)}
|
||||
</div>
|
||||
</div>
|
||||
<div className='tw-stat tw-p-3'>
|
||||
<div className='tw-stat-title'>Spent</div>
|
||||
<div className='tw-stat-value tw-text-red-500 tw-text-xl lg:tw-text-3xl'>
|
||||
{formatCurrency(stats.totalAmountReceived.valueInCents - currentBalance, currency)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr></hr>
|
||||
<div className='tw-m-4 tw-items-center'>
|
||||
<a href={`https://opencollective.com/${slug}/donate`} target='_blank' rel='noreferrer'>
|
||||
<button className='tw-btn tw-btn-sm tw-btn-primary tw-float-right tw-ml-4'>
|
||||
Donate
|
||||
</button>
|
||||
</a>
|
||||
<div className='tw-flex-1 tw-mr-4'>
|
||||
Support{' '}
|
||||
<a
|
||||
className='tw-font-bold'
|
||||
href={`https://opencollective.com/${slug}`}
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
{data.account.name}
|
||||
</a>{' '}
|
||||
on <span className='tw-font-bold'>Open Collective</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
|
||||
import { ContactInfoForm } from '#components/Profile/Subcomponents/ContactInfoForm'
|
||||
import { CrowdfundingForm } from '#components/Profile/Subcomponents/CrowdfundingForm'
|
||||
import { GroupSubheaderForm } from '#components/Profile/Subcomponents/GroupSubheaderForm'
|
||||
import { ProfileStartEndForm } from '#components/Profile/Subcomponents/ProfileStartEndForm'
|
||||
import { ProfileTextForm } from '#components/Profile/Subcomponents/ProfileTextForm'
|
||||
@ -14,6 +15,7 @@ const componentMap = {
|
||||
texts: ProfileTextForm,
|
||||
contactInfos: ContactInfoForm,
|
||||
startEnd: ProfileStartEndForm,
|
||||
crowdfundings: CrowdfundingForm,
|
||||
// weitere Komponenten hier
|
||||
}
|
||||
|
||||
|
||||
@ -196,6 +196,7 @@ export const onUpdateItem = async (
|
||||
...(state.image.length > 10 && { image: state.image }),
|
||||
...(state.offers.length > 0 && { offers: offerUpdates }),
|
||||
...(state.needs.length > 0 && { needs: needsUpdates }),
|
||||
...(state.openCollectiveSlug && { openCollectiveSlug: state.openCollectiveSlug }),
|
||||
}
|
||||
|
||||
const offersState: any[] = []
|
||||
|
||||
@ -5,4 +5,4 @@
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path d='M30 14.75h-2.824c-0.608-5.219-4.707-9.318-9.874-9.921l-0.053-0.005v-2.824c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.824c-5.219 0.608-9.318 4.707-9.921 9.874l-0.005 0.053h-2.824c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.824c0.608 5.219 4.707 9.318 9.874 9.921l0.053 0.005v2.824c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.824c5.219-0.608 9.318-4.707 9.921-9.874l0.005-0.053h2.824c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0zM17.25 24.624v-2.624c0-0.69-0.56-1.25-1.25-1.25s-1.25 0.56-1.25 1.25v0 2.624c-3.821-0.57-6.803-3.553-7.368-7.326l-0.006-0.048h2.624c0.69 0 1.25-0.56 1.25-1.25s-0.56-1.25-1.25-1.25v0h-2.624c0.57-3.821 3.553-6.804 7.326-7.368l0.048-0.006v2.624c0 0.69 0.56 1.25 1.25 1.25s1.25-0.56 1.25-1.25v0-2.624c3.821 0.57 6.803 3.553 7.368 7.326l0.006 0.048h-2.624c-0.69 0-1.25 0.56-1.25 1.25s0.56 1.25 1.25 1.25v0h2.624c-0.571 3.821-3.553 6.803-7.326 7.368l-0.048 0.006z'></path>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
1
src/types/FormState.d.ts
vendored
1
src/types/FormState.d.ts
vendored
@ -19,4 +19,5 @@ export interface FormState {
|
||||
relations: Item[]
|
||||
start: string
|
||||
end: string
|
||||
openCollectiveSlug: string
|
||||
}
|
||||
|
||||
1
src/types/Item.d.ts
vendored
1
src/types/Item.d.ts
vendored
@ -50,6 +50,7 @@ export interface Item {
|
||||
telephone?: string
|
||||
next_appointment?: string
|
||||
gallery?: GalleryItem[]
|
||||
openCollectiveSlug?: string
|
||||
|
||||
// {
|
||||
// coordinates: [number, number]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user