mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
Merge branch 'wuerdekompass-anton' of github.com:utopia-os/utopia-ui into wuerdekompass-anton
This commit is contained in:
commit
6396df8983
34
src/Components/Input/ComboBoxInput.tsx
Normal file
34
src/Components/Input/ComboBoxInput.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import { useState } from "react"
|
||||
import * as React from "react"
|
||||
|
||||
interface ComboBoxProps {
|
||||
id?: string;
|
||||
options: { value: string, label: string }[];
|
||||
value: string;
|
||||
onValueChange: (newValue: string) => void;
|
||||
}
|
||||
|
||||
const ComboBoxInput = ({ id, options, value, onValueChange }: ComboBoxProps) => {
|
||||
|
||||
const [selectedValue, setSelectedValue] = useState(value);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const value = e.target.value;
|
||||
setSelectedValue(value);
|
||||
onValueChange(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<select
|
||||
id={id}
|
||||
className="tw-form-select tw-block tw-w-full tw-py-2 tw-px-4 tw-border tw-border-gray-300 rounded-md tw-shadow-sm tw-text-sm focus:tw-outline-none focus:tw-ring-indigo-500 focus:tw-border-indigo-500 sm:tw-text-sm"
|
||||
onChange={handleChange}
|
||||
>
|
||||
{options.map((o) =>
|
||||
<option value={o.value} key={o.value} selected={o.value == value}>{o.label}</option>
|
||||
)}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
||||
export default ComboBoxInput;
|
||||
94
src/Components/Map/Subcomponents/Controls/FilterControl.tsx
Normal file
94
src/Components/Map/Subcomponents/Controls/FilterControl.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
const typeMapping = [
|
||||
{value: null, label: 'Kein Filter'},
|
||||
{value: 'kompass', label: 'Würdekompass'},
|
||||
{value: 'themenkompass', label: 'Themenkompass-Gruppe'},
|
||||
{value: 'liebevoll.jetzt', label: 'liebevoll.jetzt'}
|
||||
];
|
||||
|
||||
const CustomFilterIcon = ({ size = 20 }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor" // Changed from 'none' to 'currentColor'
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const CheckmarkIcon = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<polyline points="20 6 9 17 4 12" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const FilterControl = ({ activeFilter, setActiveFilter }) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const toggleFilter = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
const applyFilter = (filterValue) => {
|
||||
setActiveFilter(filterValue);
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="tw-relative">
|
||||
<div className="tw-indicator">
|
||||
{activeFilter !== null && (
|
||||
<span className="tw-indicator-item tw-badge tw-badge-secondary tw-bg-red-500 tw-border-red-500"></span>
|
||||
)}
|
||||
<button
|
||||
className="tw-w-12 tw-h-12 tw-rounded-full tw-bg-base-100 tw-flex tw-items-center tw-justify-center tw-border tw-border-gray-300 hover:tw-bg-gray-200 focus:tw-bg-gray-200 focus:tw-outline-none"
|
||||
onClick={toggleFilter}
|
||||
>
|
||||
<CustomFilterIcon size={24} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{isOpen && (
|
||||
<div className="tw-absolute tw-bottom-12 tw-left-0 tw-bg-base-100 tw-shadow-xl tw-rounded-lg tw-overflow-hidden tw-border tw-border-gray-200 tw-min-w-[250px]">
|
||||
<ul className="tw-py-1">
|
||||
{typeMapping.map((type) => (
|
||||
<li key={type.value}>
|
||||
<button
|
||||
onClick={() => applyFilter(type.value)}
|
||||
className={`tw-w-full tw-text-left tw-text-sm tw-px-4 tw-py-2 tw-flex tw-items-center tw-space-x-2
|
||||
hover:tw-bg-gray-300 focus:tw-bg-gray-300 focus:tw-outline-none
|
||||
${activeFilter === type.value ? 'tw-bg-gray-200' : ''}`}
|
||||
>
|
||||
<span className="tw-w-4">
|
||||
{activeFilter === type.value && <CheckmarkIcon />}
|
||||
</span>
|
||||
<span>{type.label}</span>
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FilterControl;
|
||||
@ -9,8 +9,7 @@ import AddButton from "./Subcomponents/AddButton";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ItemFormPopupProps } from "./Subcomponents/ItemFormPopup";
|
||||
import { SearchControl } from "./Subcomponents/Controls/SearchControl";
|
||||
import { LayerControl } from "./Subcomponents/Controls/LayerControl";
|
||||
import { QuestControl } from "./Subcomponents/Controls/QuestControl";
|
||||
// import { QuestControl } from "./Subcomponents/Controls/QuestControl";
|
||||
import { Control } from "./Subcomponents/Controls/Control";
|
||||
import { Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||
import { TagsControl } from "./Subcomponents/Controls/TagsControl";
|
||||
@ -18,6 +17,8 @@ import { useSelectPosition, useSetMapClicked,useSetSelectPosition } from "./hook
|
||||
import { useClusterRef, useSetClusterRef } from "./hooks/useClusterRef";
|
||||
import { Feature, Geometry as GeoJSONGeometry } from 'geojson';
|
||||
import {useAuth} from "../Auth";
|
||||
import FilterControl from "./Subcomponents/Controls/FilterControl";
|
||||
import {LayerControl} from "./Subcomponents/Controls/LayerControl";
|
||||
|
||||
// for refreshing map on resize (needs to be implemented)
|
||||
const mapDivRef = React.createRef();
|
||||
@ -61,6 +62,8 @@ function UtopiaMap({
|
||||
const clusterRef = useClusterRef();
|
||||
const setMapClicked = useSetMapClicked();
|
||||
|
||||
const [activeFilter, setActiveFilter] = useState(null);
|
||||
|
||||
const [itemFormPopup, setItemFormPopup] = useState<ItemFormPopupProps | null>(null);
|
||||
|
||||
const [embedded, setEmbedded] = useState<boolean>(true)
|
||||
@ -92,9 +95,11 @@ function UtopiaMap({
|
||||
<TagsControl />
|
||||
</Control>
|
||||
<Control position='bottomLeft' zIndex="999" absolute>
|
||||
{!embedded && (
|
||||
<QuestControl></QuestControl>
|
||||
)}
|
||||
{/*{!embedded && (*/}
|
||||
{/* <QuestControl></QuestControl>*/}
|
||||
{/*)}*/}
|
||||
<FilterControl activeFilter={activeFilter} setActiveFilter={setActiveFilter} />
|
||||
{/*todo: needed layer handling is located LayerControl*/}
|
||||
<LayerControl></LayerControl>
|
||||
</Control>
|
||||
<TileLayer
|
||||
|
||||
@ -1,48 +1,56 @@
|
||||
import { useAssetApi } from "../AppShell/hooks/useAssets";
|
||||
|
||||
const ContactInfo = ({ email, name, avatar } : {email: string, name: string, avatar: string}) => {
|
||||
const ContactInfo = ({ email, telephone, name, avatar } : {email: string, telephone: string, name: string, avatar: string}) => {
|
||||
const assetsApi = useAssetApi();
|
||||
|
||||
|
||||
return(
|
||||
<div className="tw-bg-gray-100 tw-my-10 tw-p-6">
|
||||
<h2 className="tw-text-lg tw-font-semibold">Du hast Fragen?</h2>
|
||||
<div className="tw-mt-4 tw-flex tw-items-center">
|
||||
<div className="tw-mr-5 tw-flex tw-items-center tw-justify-center">
|
||||
<div className="tw-avatar">
|
||||
<div
|
||||
className="tw-w-20 tw-h-20 tw-bg-gray-200 rounded-full tw-flex tw-items-center tw-justify-center overflow-hidden">
|
||||
{avatar ? (
|
||||
<img src={assetsApi.url + avatar} alt={name}
|
||||
className="tw-w-full tw-h-full tw-object-cover"/>
|
||||
) : (
|
||||
<div className="tw-flex tw-items-center tw-justify-center tw-w-full tw-h-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" className="tw-w-12 tw-h-12"
|
||||
fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"
|
||||
strokeLinejoin="round">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
<div className="tw-bg-gray-100 tw-my-10 tw-p-6">
|
||||
<h2 className="tw-text-lg tw-font-semibold">Du hast Fragen?</h2>
|
||||
<div className="tw-mt-4 tw-flex tw-items-center">
|
||||
{avatar && (
|
||||
<div className="tw-mr-5 tw-flex tw-items-center tw-justify-center">
|
||||
<div className="tw-avatar">
|
||||
<div className="tw-w-20 tw-h-20 tw-bg-gray-200 rounded-full tw-flex tw-items-center tw-justify-center overflow-hidden">
|
||||
<img src={assetsApi.url + avatar} alt={name}
|
||||
className="tw-w-full tw-h-full tw-object-cover"/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="tw-text-sm tw-flex-grow">
|
||||
<p className="tw-font-semibold">{name}</p>
|
||||
{email && (
|
||||
<p>
|
||||
<a href={`mailto:${email}`}
|
||||
className="tw-mt-2 tw-text-green-500 tw-inline-flex tw-items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
|
||||
className="tw-w-4 tw-h-4 tw-mr-1">
|
||||
<path
|
||||
d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
|
||||
<polyline points="22,6 12,13 2,6"></polyline>
|
||||
</svg>
|
||||
{email}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
{telephone && (
|
||||
<p>
|
||||
<a href={`tel:${telephone}`}
|
||||
className="tw-mt-2 tw-text-green-500 tw-inline-flex tw-items-center tw-whitespace-nowrap">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
|
||||
className="tw-w-4 tw-h-4 tw-mr-1">
|
||||
<path
|
||||
d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z"/>
|
||||
</svg>
|
||||
{telephone}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="tw-text-sm">
|
||||
<p className="tw-font-semibold">{name}</p>
|
||||
<a href={`mailto:${email}`} className="tw-mt-2 tw-text-green-500 tw-flex tw-items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
|
||||
className="tw-w-4 tw-h-4 tw-mr-1">
|
||||
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
|
||||
<polyline points="22,6 12,13 2,6"></polyline>
|
||||
</svg>
|
||||
|
||||
{email}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -273,30 +273,14 @@ export function OverlayItemProfile() {
|
||||
navigate("/");
|
||||
}
|
||||
|
||||
const d = {
|
||||
groupName: "Gruppe Berlin-Britz",
|
||||
location: "🇩🇪 12347 Berlin",
|
||||
country: "Berlin, Deutschland",
|
||||
countryCode: "de",
|
||||
contact: {
|
||||
name: "Lisa Mustermann",
|
||||
email: "lisa.mustermann@gmx.de",
|
||||
avatarSrc: "https://cdn.prod.website-files.com/65c0d5530322d3f6f5f86099/65c0d5530322d3f6f5f86781_Andr%C3%A9.jpg" // optional
|
||||
},
|
||||
description: "Unsere KulturArche, ein historischer Frachtsegler...",
|
||||
relations: [
|
||||
{
|
||||
title: "KulturArche EALA",
|
||||
description: "Durchaus beeindruckt von der Ethik und der Arbeit...",
|
||||
imageSrc: "https://cdn.prod.website-files.com/65c0d5530322d3f6f5f86099/65c0d5530322d3f6f5f86767_IMG_20190302_173147.jpg"
|
||||
},
|
||||
// Add more projects as needed
|
||||
],
|
||||
url: window.location.href,
|
||||
title: "Gruppe Berlin-Britz"
|
||||
const typeMapping = {
|
||||
'default': 'Würdekompass',
|
||||
'themenkompass': 'Themenkompass-Gruppe',
|
||||
'liebevoll.jetzt': 'liebevoll.jetzt',
|
||||
};
|
||||
|
||||
|
||||
let groupType = item.group_type ? item.group_type : 'default';
|
||||
let groupTypeText = typeMapping[groupType];
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -308,10 +292,10 @@ export function OverlayItemProfile() {
|
||||
<div className="tw-px-6 tw-pt-6">
|
||||
<HeaderView api={item.layer?.api} item={item} deleteCallback={handleDelete} editCallback={() => navigate("/edit-item/" + item.id)} setPositionCallback={() => { map.closePopup(); setSelectPosition(item); navigate("/") }} big truncateSubname={false} />
|
||||
<ProfileSubHeader
|
||||
location={d.location}
|
||||
type={"Regionalgruppe"}
|
||||
url={d.url}
|
||||
title={d.title}
|
||||
type={groupTypeText}
|
||||
status={item.status}
|
||||
url={window.location.href}
|
||||
title={item.name}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -320,31 +304,38 @@ export function OverlayItemProfile() {
|
||||
{item.layer?.itemType.onepager &&
|
||||
<>
|
||||
{item.user_created.first_name && (
|
||||
<ContactInfo name={item.user_created.first_name} avatar={item.user_created.avatar} email={item.contact} />
|
||||
<ContactInfo name={item.user_created.first_name} avatar={item.user_created.avatar} email={item.contact} telephone={item.telephone} />
|
||||
)}
|
||||
|
||||
{/* Description Section */}
|
||||
<div className="tw-my-10 tw-px-6">
|
||||
<h2 className="tw-text-lg tw-font-semibold">Beschreibung</h2>
|
||||
<div className="tw-mt-2 tw-text-sm tw-text-gray-600">
|
||||
<TextView rawText={item.text ?? 'Keine Beschreibung vorhanden'}/>
|
||||
</div>
|
||||
<div className="tw-my-10 tw-mt-2 tw-px-6 tw-text-sm tw-text-gray-600">
|
||||
<TextView rawText={item.text || 'Keine Beschreibung vorhanden'}/>
|
||||
</div>
|
||||
|
||||
{/* Relations Section */}
|
||||
{d.relations && (
|
||||
{/* Next Appointment Section */}
|
||||
{item.next_appointment && (
|
||||
<div className="tw-my-10 tw-px-6">
|
||||
<h2 className="tw-text-lg tw-font-semibold tw-mb-4">Projekte</h2>
|
||||
{d.relations.map((project, index) => (
|
||||
<RelationCard
|
||||
key={index}
|
||||
title={project.title}
|
||||
description={project.description}
|
||||
imageSrc={project.imageSrc}
|
||||
/>
|
||||
))}
|
||||
<h2 className="tw-text-lg tw-font-semibold">Nächste Termine</h2>
|
||||
<div className="tw-mt-2 tw-text-sm tw-text-gray-600">
|
||||
<TextView rawText={item.next_appointment}/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)};
|
||||
|
||||
{/* Relations Section */}
|
||||
{/*{d.relations && (*/}
|
||||
{/* <div className="tw-my-10 tw-px-6">*/}
|
||||
{/* <h2 className="tw-text-lg tw-font-semibold tw-mb-4">Projekte</h2>*/}
|
||||
{/* {d.relations.map((project, index) => (*/}
|
||||
{/* <RelationCard*/}
|
||||
{/* key={index}*/}
|
||||
{/* title={project.title}*/}
|
||||
{/* description={project.description}*/}
|
||||
{/* imageSrc={project.imageSrc}*/}
|
||||
{/* />*/}
|
||||
{/* ))}*/}
|
||||
{/* </div>*/}
|
||||
{/*)}*/}
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import { getValue } from '../../Utils/GetValue';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useAuth } from '../Auth';
|
||||
import { TextInput, TextAreaInput } from '../Input';
|
||||
import ComboBoxInput from '../Input/ComboBoxInput';
|
||||
import { ColorPicker } from './ColorPicker';
|
||||
import { hashTagRegex } from '../../Utils/HashTagRegex';
|
||||
import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags';
|
||||
@ -24,10 +25,26 @@ import { useHasUserPermission } from '../Map/hooks/usePermissions';
|
||||
|
||||
export function OverlayItemProfileSettings() {
|
||||
|
||||
const typeMapping = [
|
||||
{value: 'kompass', label: 'Würdekompass'},
|
||||
{value: 'themenkompass', label: 'Themenkompass-Gruppe'},
|
||||
{value: 'liebevoll.jetzt', label: 'liebevoll.jetzt'}
|
||||
];
|
||||
const statusMapping = [
|
||||
{value: 'active', label: 'aktiv'},
|
||||
{value: 'in_planning', label: 'in Planung'},
|
||||
{value: 'paused', label: 'pausiert'}
|
||||
];
|
||||
|
||||
const [id, setId] = useState<string>("");
|
||||
const [groupType, setGroupType] = useState<string>("");
|
||||
const [status, setStatus] = useState<string>("");
|
||||
const [name, setName] = useState<string>("");
|
||||
const [subname, setSubname] = useState<string>("");
|
||||
const [text, setText] = useState<string>("");
|
||||
const [contact, setContact] = useState<string>("");
|
||||
const [telephone, setTelephone] = useState<string>("");
|
||||
const [nextAppointment, setNextAppointment] = useState<string>("");
|
||||
const [image, setImage] = useState<string>("");
|
||||
const [color, setColor] = useState<string>("");
|
||||
const [offers, setOffers] = useState<Array<Tag>>([]);
|
||||
@ -96,9 +113,14 @@ export function OverlayItemProfileSettings() {
|
||||
setColor(item.layer?.itemColorField && getValue(item, item.layer?.itemColorField) ? getValue(item, item.layer?.itemColorField) : (getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item?.layer?.markerDefaultColor))
|
||||
|
||||
setId(item?.id ? item.id : "");
|
||||
setGroupType(item?.group_type || "kompass");
|
||||
setStatus(item?.status || "active");
|
||||
setName(item?.name ? item.name : "");
|
||||
setSubname(item?.subname ? item.subname : "");
|
||||
setText(item?.text ? item.text : "");
|
||||
setContact(item?.contact || "");
|
||||
setTelephone(item?.telephone || "");
|
||||
setNextAppointment(item?.next_appointment || "");
|
||||
setImage(item?.image ? item?.image : "");
|
||||
setOffers([]);
|
||||
setNeeds([]);
|
||||
@ -141,13 +163,23 @@ export function OverlayItemProfileSettings() {
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
changedItem = { id: id, name: name, subname: subname, text: text, color: color, position: item.position, ...image.length > 10 && { image: image }, ...offers.length > 0 && { offers: offer_updates }, ...needs.length > 0 && { needs: needs_updates } };
|
||||
// update profile item in current state
|
||||
changedItem = {
|
||||
id: id,
|
||||
group_type: groupType,
|
||||
status: status,
|
||||
name: name,
|
||||
subname: subname,
|
||||
text: text,
|
||||
color: color,
|
||||
position: item.position,
|
||||
contact: contact,
|
||||
telephone: telephone,
|
||||
next_appointment: nextAppointment,
|
||||
...image.length > 10 && { image: image },
|
||||
...offers.length > 0 && { offers: offer_updates },
|
||||
...needs.length > 0 && { needs: needs_updates }
|
||||
};
|
||||
|
||||
let offers_state: Array<any> = [];
|
||||
let needs_state: Array<any> = [];
|
||||
@ -274,12 +306,80 @@ export function OverlayItemProfileSettings() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{item.layer?.itemType.onepager &&
|
||||
{item.layer?.itemType.onepager && (
|
||||
<div className="tw-space-y-6 tw-mt-6">
|
||||
<div className="tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6">
|
||||
<div>
|
||||
<label htmlFor="groupType" className="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
||||
Gruppenart:
|
||||
</label>
|
||||
<ComboBoxInput
|
||||
id="groupType"
|
||||
options={typeMapping}
|
||||
value={groupType}
|
||||
onValueChange={(v) => setGroupType(v)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="status" className="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
||||
Gruppenstatus:
|
||||
</label>
|
||||
<ComboBoxInput
|
||||
id="status"
|
||||
options={statusMapping}
|
||||
value={status}
|
||||
onValueChange={(v) => setStatus(v)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TextAreaInput placeholder="My Visino..." defaultValue={item?.text ? item.text : ""} updateFormValue={(v) => { console.log(v); setText(v) }} containerStyle='tw-h-full' inputStyle='tw-h-full tw-border-t-0 tw-rounded-tl-none' />
|
||||
<div>
|
||||
<label htmlFor="email" className="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
||||
Email-Adresse (Kontakt):
|
||||
</label>
|
||||
<TextInput
|
||||
placeholder="Email"
|
||||
defaultValue={contact}
|
||||
updateFormValue={(v) => setContact(v)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="telephone" className="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
||||
Telefonnummer (Kontakt):
|
||||
</label>
|
||||
<TextInput
|
||||
placeholder="Telefonnummer"
|
||||
defaultValue={telephone}
|
||||
updateFormValue={(v) => setTelephone(v)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
}
|
||||
<div>
|
||||
<label htmlFor="nextAppointment" className="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
||||
Nächste Termine:
|
||||
</label>
|
||||
<TextAreaInput
|
||||
placeholder="Nächste Termine"
|
||||
defaultValue={nextAppointment}
|
||||
updateFormValue={(v) => setNextAppointment(v)}
|
||||
inputStyle="tw-h-24"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="description" className="tw-block tw-text-sm tw-font-medium tw-text-gray-700 tw-mb-1">
|
||||
Gruppenbeschreibung:
|
||||
</label>
|
||||
<TextAreaInput
|
||||
placeholder="Beschreibung"
|
||||
defaultValue={item?.text ?? ""}
|
||||
updateFormValue={(v) => setText(v)}
|
||||
inputStyle="tw-h-48"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!item.layer?.itemType.onepager &&
|
||||
|
||||
|
||||
@ -18,11 +18,15 @@ const flags = {
|
||||
)
|
||||
};
|
||||
|
||||
const SubHeader = ({ location, type, url, title }) => (
|
||||
const statusMapping = {
|
||||
'in_planning': 'in Planung',
|
||||
'paused': 'pausiert',
|
||||
};
|
||||
|
||||
const SubHeader = ({ type, status, url, title }) => (
|
||||
<div>
|
||||
<div className="tw-flex tw-items-center tw-mt-6">
|
||||
<span className="tw-text-sm tw-text-gray-600">{type}</span>
|
||||
<span className="tw-text-sm tw-text-gray-600 tw-ml-6">{location}</span>
|
||||
<span className="tw-text-sm tw-text-gray-600">{type}{(status && status !== 'active') ? ` (${statusMapping[status]})` : ''}</span>
|
||||
</div>
|
||||
<div className="tw-mt-4">
|
||||
<SocialShareBar url={url} title={title} />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user