support for tab urls and several fixes

This commit is contained in:
Anton Tranelis 2024-03-23 11:46:44 +01:00
parent 4cd5b8b0fc
commit 7005f492dd
10 changed files with 152 additions and 107 deletions

View File

@ -9,6 +9,10 @@ import { AssetsApi } from '../../types'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { PermissionsProvider } from '../Map/hooks/usePermissions'
import { TagsProvider } from '../Map/hooks/useTags'
import { FilterProvider } from '../Map/hooks/useFilter'
import { ItemsProvider } from '../Map/hooks/useItems'
import { LayersProvider } from '../Map/hooks/useLayers'
import { LeafletRefsProvider } from '../Map/hooks/useLeafletRefs'
export function AppShell({ appName, nameWidth, children, assetsApi }: { appName: string, nameWidth?: number, children: React.ReactNode, assetsApi: AssetsApi }) {
@ -19,29 +23,37 @@ export function AppShell({ appName, nameWidth, children, assetsApi }: { appName:
return (
<PermissionsProvider initialPermissions={[]}>
<TagsProvider initialTags={[]}>
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<AssetsProvider>
<SetAssetsApi assetsApi={assetsApi}></SetAssetsApi>
<QuestsProvider initialOpen={true}>
<ToastContainer position="top-right"
autoClose={2000}
hideProgressBar
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light" />
<NavBar appName={appName} nameWidth={nameWidth}></NavBar>
<div id="app-content" className="tw-flex tw-!pl-[77px]">
{children}
</div>
</QuestsProvider>
</AssetsProvider>
</BrowserRouter>
</QueryClientProvider>
<LayersProvider initialLayers={[]}>
<FilterProvider initialTags={[]}>
<ItemsProvider initialItems={[]}>
<LeafletRefsProvider initialLeafletRefs={{}}>
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<AssetsProvider>
<SetAssetsApi assetsApi={assetsApi}></SetAssetsApi>
<QuestsProvider initialOpen={true}>
<ToastContainer position="top-right"
autoClose={2000}
hideProgressBar
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light" />
<NavBar appName={appName} nameWidth={nameWidth}></NavBar>
<div id="app-content" className="tw-flex tw-!pl-[77px]">
{children}
</div>
</QuestsProvider>
</AssetsProvider>
</BrowserRouter>
</QueryClientProvider>
</LeafletRefsProvider>
</ItemsProvider>
</FilterProvider>
</LayersProvider>
</TagsProvider>
</PermissionsProvider>

View File

@ -95,7 +95,6 @@ export const Layer = ({
}
else {
if (window.location.pathname.split("/")[1] == name) {
if (window.location.pathname.split("/")[2]) {
const id = window.location.pathname.split("/")[2]
const marker = leafletRefs[id]?.marker;

View File

@ -3,7 +3,7 @@ import { useEffect } from 'react';
import { ItemsApi, Tag } from '../../types';
import { useSetTagData, useSetTagApi, useTags } from './hooks/useTags'
import { useLocation } from 'react-router-dom';
import { useAddFilterTag } from './hooks/useFilter';
import { useAddFilterTag, useResetFilterTags } from './hooks/useFilter';
export function Tags({data, api} : {data?: Tag[], api?: ItemsApi<Tag>}) {
const setTagData = useSetTagData();
@ -17,12 +17,14 @@ useEffect(() => {
const location = useLocation();
const addFilterTag = useAddFilterTag();
const resetFilterTags = useResetFilterTags();
const tags = useTags();
useEffect(() => {
let params = new URLSearchParams(location.search);
let urlTags = params.get("tags");
resetFilterTags()
urlTags?.split(",").map(urlTag => {
const tag = tags.find(t => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase())
tag && addFilterTag(tag)

View File

@ -8,11 +8,7 @@ import MarkerClusterGroup from 'react-leaflet-cluster'
import AddButton from "./Subcomponents/AddButton";
import { useEffect, useState } from "react";
import { ItemFormPopupProps } from "./Subcomponents/ItemFormPopup";
import { ItemsProvider } from "./hooks/useItems";
import { LayersProvider } from "./hooks/useLayers";
import { FilterProvider } from "./hooks/useFilter";
import { SearchControl } from "./Subcomponents/Controls/SearchControl";
import { LeafletRefsProvider } from "./hooks/useLeafletRefs";
import { LayerControl } from "./Subcomponents/Controls/LayerControl";
import { QuestControl } from "./Subcomponents/Controls/QuestControl";
import { Control } from "./Subcomponents/Controls/Control";
@ -42,7 +38,7 @@ function UtopiaMap({
useMapEvents({
click: (e) => {
let params = new URLSearchParams(window.location.search);
window.history.pushState({}, "", `/`+ `${params.toString() !== "" ? `?${params}` : ""}`)
window.history.pushState({}, "", `/` + `${params.toString() !== "" ? `?${params}` : ""}`)
document.title = document.title.split("-")[0];
document.querySelector('meta[property="og:title"]')?.setAttribute("content", document.title);
document.querySelector('meta[property="og:description"]')?.setAttribute("content", `${document.querySelector('meta[name="description"]')?.getAttribute("content")}`);
@ -56,8 +52,8 @@ function UtopiaMap({
moveend: (e) => {
console.log(e);
}
})
return null
}
@ -79,51 +75,45 @@ function UtopiaMap({
return (
<>
<LayersProvider initialLayers={[]}>
<FilterProvider initialTags={[]}>
<ItemsProvider initialItems={[]}>
<LeafletRefsProvider initialLeafletRefs={{}}>
<div className={(selectNewItemPosition != null ? "crosshair-cursor-enabled" : undefined)}>
<MapContainer ref={mapDivRef} style={{ height: height, width: width }} center={new LatLng(center[0], center[1])} zoom={zoom} zoomControl={false} maxZoom={19}>
<Outlet></Outlet>
<Control position='topLeft' zIndex="1000">
<SearchControl clusterRef={clusterRef} />
<TagsControl />
</Control>
<Control position='bottomLeft' zIndex="999">
<QuestControl></QuestControl>
<LayerControl></LayerControl>
</Control>
<TileLayer
maxZoom={19}
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://tile.osmand.net/hd/{z}/{x}/{y}.png" />
<MarkerClusterGroup ref={clusterRef} showCoverageOnHover chunkedLoading maxClusterRadius={50} removeOutsideVisibleBounds={false}>
{
React.Children.toArray(children).map((child) =>
React.isValidElement<{ setItemFormPopup: React.Dispatch<React.SetStateAction<ItemFormPopupProps>>, itemFormPopup: ItemFormPopupProps | null, clusterRef: React.MutableRefObject<undefined> }>(child) ?
React.cloneElement(child, { setItemFormPopup: setItemFormPopup, itemFormPopup: itemFormPopup, clusterRef: clusterRef }) : child
)
}
</MarkerClusterGroup>
<MapEventListener setSelectNewItemPosition={setSelectNewItemPosition} selectNewItemPosition={selectNewItemPosition} setItemFormPopup={setItemFormPopup} />
</MapContainer>
<AddButton triggerAction={setSelectNewItemPosition}></AddButton>
{selectNewItemPosition != null &&
<div className="tw-button tw-z-1000 tw-absolute tw-right-5 tw-top-4 tw-drop-shadow-md">
<div className="tw-alert tw-bg-base-100 tw-text-base-content">
<div>
<span>Select {selectNewItemPosition.name} position!</span>
</div>
</div>
</div>
}
</div>
</LeafletRefsProvider>
</ItemsProvider>
</FilterProvider>
</LayersProvider>
<div className={(selectNewItemPosition != null ? "crosshair-cursor-enabled" : undefined)}>
<MapContainer ref={mapDivRef} style={{ height: height, width: width }} center={new LatLng(center[0], center[1])} zoom={zoom} zoomControl={false} maxZoom={19}>
<Outlet></Outlet>
<Control position='topLeft' zIndex="1000">
<SearchControl clusterRef={clusterRef} />
<TagsControl />
</Control>
<Control position='bottomLeft' zIndex="999">
<QuestControl></QuestControl>
<LayerControl></LayerControl>
</Control>
<TileLayer
maxZoom={19}
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://tile.osmand.net/hd/{z}/{x}/{y}.png" />
<MarkerClusterGroup ref={clusterRef} showCoverageOnHover chunkedLoading maxClusterRadius={50} removeOutsideVisibleBounds={false}>
{
React.Children.toArray(children).map((child) =>
React.isValidElement<{ setItemFormPopup: React.Dispatch<React.SetStateAction<ItemFormPopupProps>>, itemFormPopup: ItemFormPopupProps | null, clusterRef: React.MutableRefObject<undefined> }>(child) ?
React.cloneElement(child, { setItemFormPopup: setItemFormPopup, itemFormPopup: itemFormPopup, clusterRef: clusterRef }) : child
)
}
</MarkerClusterGroup>
<MapEventListener setSelectNewItemPosition={setSelectNewItemPosition} selectNewItemPosition={selectNewItemPosition} setItemFormPopup={setItemFormPopup} />
</MapContainer>
<AddButton triggerAction={setSelectNewItemPosition}></AddButton>
{selectNewItemPosition != null &&
<div className="tw-button tw-z-1000 tw-absolute tw-right-5 tw-top-4 tw-drop-shadow-md">
<div className="tw-alert tw-bg-base-100 tw-text-base-content">
<div>
<span>Select {selectNewItemPosition.name} position!</span>
</div>
</div>
</div>
}
</div>
</>
);
}

View File

@ -6,11 +6,11 @@ import { TextView } from "../Map";
import { HeaderView } from "../Map/Subcomponents/ItemPopupComponents/HeaderView";
import { Item } from "../../types";
export function ActionButton({ item, triggerAddButton, triggerItemSelected, existingRelations, itemType, color="#3D3846", collection = "items" }: {
export function ActionButton({ item, triggerAddButton, triggerItemSelected, existingRelations, itemType, color = "#3D3846", collection = "items" }: {
triggerAddButton: any,
triggerItemSelected: any,
existingRelations: Item[],
itemType:string;
itemType: string;
color: string,
collection?: string,
item: Item
@ -20,15 +20,15 @@ export function ActionButton({ item, triggerAddButton, triggerItemSelected, exis
const items = useItems();
const filterdItems = items.filter(i => i.type == itemType).filter(i => !existingRelations.some(s => s.id == i.id)).filter(i => i.id != item.id)
const filterdItems = items.filter(i => i.type == itemType).filter(i => !existingRelations.some(s => s.id == i.id)).filter(i => i.id != item.id)
return (
<>{hasUserPermission(collection, "create") &&
<>{hasUserPermission(collection, "update", item) &&
<>
<div className="tw-absolute tw-right-4 tw-bottom-4 tw-flex tw-flex-col" >
<button tabIndex={0} className="tw-z-500 tw-btn tw-btn-circle tw-shadow" onClick={() => { setModalOpen(true) }} style={{ backgroundColor: color, color: "#fff" }}>
<svg className="tw-h-5 tw-w-5" stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"></path></svg>
<svg className="tw-h-5 tw-w-5" stroke="currentColor" fill="currentColor" strokeWidth="0" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"></path></svg>
</button>
<button tabIndex={0} className="tw-z-500 tw-btn tw-btn-circle tw-shadow tw-mt-2" onClick={() => { triggerAddButton() }} style={{ backgroundColor: color, color: "#fff" }}>
@ -38,9 +38,11 @@ export function ActionButton({ item, triggerAddButton, triggerItemSelected, exis
</button>
</div>
<DialogModal title={"Select"} isOpened={modalOpen} onClose={() => (setModalOpen(false))}>
{filterdItems.map(i => <div key={i.id} className='tw-cursor-pointer tw-card tw-border-[1px] tw-border-base-300 tw-card-body tw-shadow-xl tw-bg-base-100 tw-text-base-content tw-mx-4 tw-p-4 tw-mb-4 tw-h-fit' onClick={()=>{triggerItemSelected(i.id);setModalOpen(false)}}>
<HeaderView item={i} hideMenu></HeaderView>
</div>)}
<div className='tw-grid tw-grid-cols-1 sm:tw-grid-cols-2 md:tw-grid-cols-2 lg:tw-grid-cols-2 xl:tw-grid-cols-2'>
{filterdItems.map(i => <div key={i.id} className='tw-cursor-pointer tw-card tw-border-[1px] tw-border-base-300 tw-card-body tw-shadow-xl tw-bg-base-100 tw-text-base-content tw-mx-4 tw-p-4 tw-mb-4 tw-h-fit' onClick={() => { triggerItemSelected(i.id); setModalOpen(false) }}>
<HeaderView item={i} hideMenu></HeaderView>
</div>)}
</div>
</DialogModal>
</>
}

View File

@ -23,7 +23,7 @@ export function LinkedItemsHeaderView({ item, unlinkCallback, itemNameField, ite
const hasUserPermission = useHasUserPermission();
return (
<>
@ -42,7 +42,7 @@ export function LinkedItemsHeaderView({ item, unlinkCallback, itemNameField, ite
</div>
</div>
<div className='tw-col-span-1' onClick={(e) => e.stopPropagation()}>
{
{ hasUserPermission("items", "update", item) &&
<div className="tw-dropdown tw-dropdown-bottom">
<label tabIndex={0} className="tw-bg-base-100 tw-btn tw-m-1 tw-leading-3 tw-border-none tw-min-h-0 tw-h-6">
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">

View File

@ -70,6 +70,16 @@ export function OverlayItemProfile() {
}, [addItemPopupType])
const updateActiveTab = (id: number) => {
setActiveTab(id);
let params = new URLSearchParams(window.location.search);
let urlTab = params.get("tab");
if (!urlTab?.includes(id.toString()))
params.set("tab", `${id ? id : ""}`)
window.history.pushState('', '', "?" + params.toString());
}
useEffect(() => {
const itemId = location.pathname.split("/")[2];
@ -80,12 +90,19 @@ export function OverlayItemProfile() {
if (windowDimension.width > 768)
if (item?.position && item?.position.coordinates[0])
map.setView(new LatLng(item?.position.coordinates[1]!, item?.position.coordinates[0]! + x / 4))
}, [location, items, activeTab])
useEffect(() => {
setActiveTab(1);
useEffect(() => {
let params = new URLSearchParams(location.search);
let urlTab = params.get("tab");
urlTab ? setActiveTab(Number(urlTab)) : setActiveTab(1);
}, [location])
useEffect(() => {
setRelations([]);
@ -142,8 +159,18 @@ export function OverlayItemProfile() {
let new_relations = item.relations || [];
new_relations?.push({ items_id: item.id, related_items_id: id })
const updatedItem = { id: item.id, relations: new_relations }
await item?.layer?.api?.updateItem!(updatedItem)
updateItem({ ...item, relations: new_relations })
let success = false;
try {
await item?.layer?.api?.updateItem!(updatedItem)
success = true;
} catch (error) {
toast.error(error.toString());
}
if (success) {
updateItem({ ...item, relations: new_relations })
toast.success("Item linked");
}
}
const unlinkItem = async (id: string) => {
@ -153,8 +180,20 @@ export function OverlayItemProfile() {
console.log(new_relations);
const updatedItem = { id: item.id, relations: new_relations }
await item?.layer?.api?.updateItem!(updatedItem)
updateItem({ ...item, relations: new_relations })
let success = false;
try {
await item?.layer?.api?.updateItem!(updatedItem)
success = true;
} catch (error) {
toast.error(error.toString());
}
if (success) {
updateItem({ ...item, relations: new_relations })
toast.success("Item unlinked");
}
}
return (
@ -180,13 +219,13 @@ export function OverlayItemProfile() {
<div className='tw-h-full'>
<div role="tablist" className="tw-tabs tw-tabs-lifted tw-mt-2 tw-mb-2">
<input type="radio" name="my_tabs_2" role="tab" className={`tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`} aria-label="Info" checked={activeTab == 1 && true} onChange={() => setActiveTab(1)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4">
<input type="radio" name="my_tabs_2" role="tab" className={`tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`} aria-label="Info" checked={activeTab == 1 && true} onChange={() => updateActiveTab(1)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
<TextView item={item} />
</div>
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Projects" checked={activeTab == 2 && true} onChange={() => setActiveTab(2)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mx-4" >
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Projects" checked={activeTab == 2 && true} onChange={() => updateActiveTab(2)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mx-4 tw-overflow-x-hidden" >
<div className='tw-h-full'>
<div className='tw-grid tw-grid-cols-1 sm:tw-grid-cols-2 md:tw-grid-cols-1 lg:tw-grid-cols-1 xl:tw-grid-cols-2 tw-pb-5'>
{relations && relations.map(i => {
@ -219,14 +258,14 @@ export function OverlayItemProfile() {
</div>
</form> : <></>
}
{addButton && <ActionButton item={item} existingRelations={relations} itemType={"project"} triggerItemSelected={linkItem} triggerAddButton={() => { setAddItemPopupType("project"); scroll() }} color={item.color}></ActionButton>}
{addButton && <ActionButton collection="items" item={item} existingRelations={relations} itemType={"project"} triggerItemSelected={linkItem} triggerAddButton={() => { setAddItemPopupType("project"); scroll() }} color={item.color}></ActionButton>}
</div>
</div>
</div>
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Events" checked={activeTab == 3 && true} onChange={() => setActiveTab(3)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mx-4">
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Events" checked={activeTab == 3 && true} onChange={() => updateActiveTab(3)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mx-4 tw-overflow-x-hidden">
<div className='tw-h-full'>
<div className='tw-grid tw-grid-cols-1 sm:tw-grid-cols-2 md:tw-grid-cols-1 lg:tw-grid-cols-1 xl:tw-grid-cols-2'>
{relations && relations.map(i => {
@ -260,13 +299,13 @@ export function OverlayItemProfile() {
</div>
</form> : <></>
}
{addButton && <ActionButton item={item} existingRelations={relations} itemType={"event"} triggerItemSelected={linkItem} triggerAddButton={() => { setAddItemPopupType("event"); scroll() }} color={item.color}></ActionButton>}
{addButton && <ActionButton collection="items" item={item} existingRelations={relations} itemType={"event"} triggerItemSelected={linkItem} triggerAddButton={() => { setAddItemPopupType("event"); scroll() }} color={item.color}></ActionButton>}
</div>
</div>
</div>
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Friends" checked={activeTab == 4 && true} onChange={() => setActiveTab(4)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-1">
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Friends" checked={activeTab == 4 && true} onChange={() => updateActiveTab(4)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-1 tw-overflow-x-hidden">
</div>
</div>
</div>

View File

@ -107,7 +107,7 @@ export function OverlayItemProfileSettings() {
<div className='tw-flex tw-flex-col tw-h-full'>
<div className="tw-flex">
<AvatarWidget avatar={image} setAvatar={setImage}/>
<ColorPicker color={color} onChange={setColor} className={"-tw-left-6 tw-top-14 -tw-mr-6"} />
<ColorPicker color={color? color : "#3D3846"} onChange={setColor} className={"-tw-left-6 tw-top-14 -tw-mr-6"} />
<TextInput placeholder="Name" defaultValue={item?.name ? item.name : ""} updateFormValue={(v) => setName(v)} containerStyle='tw-grow tw-ml-6 tw-my-auto ' />
</div>

View File

@ -107,7 +107,8 @@ export function OverlayProfile() {
<h3 className='-tw-mb-2'>Offers</h3>
< div className='tw-flex tw-flex-wrap tw-mb-4'>
{
offers.map(o => <TagView key={o?.id} tag={o} onClick={() => addFilterTag(o)} />)
offers.map(o => <TagView key={o?.id} tag={o} onClick={() => {console.log(o);
addFilterTag(o)}} />)
}
</div>
</div> : ""

View File

@ -36,7 +36,7 @@
}
.Toastify__toast-container {
z-index: 1999 !important;
z-index: 2001 !important;
}
.Toastify__toast-container--top-right {