mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
enhanced offers & needs
This commit is contained in:
parent
1583e55e7e
commit
b3b5bbb9ea
@ -1,4 +1,3 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "../Auth"
|
||||
import { Link } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
@ -8,9 +7,6 @@ import * as React from "react";
|
||||
|
||||
export default function NavBar({ appName, nameWidth = 200}: { appName: string, nameWidth?: number }) {
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
||||
|
||||
const { isAuthenticated, user, logout, token } = useAuth();
|
||||
|
||||
|
||||
@ -69,9 +69,9 @@ export const Autocomplete = ({ inputProps, suggestions, onSelected, pushFiltered
|
||||
return (
|
||||
<div>
|
||||
<input ref={inputRef} {...inputProps} type="text" onChange={(e) => handleChange(e)} onKeyDown={handleKeyDown}/>
|
||||
<ul className='tw-absolute tw-z-[4000]'>
|
||||
<ul className={`tw-absolute tw-z-[4000] ${filteredSuggestions.length>0 && 'tw-bg-base-100 tw-rounded-xl tw-p-2'}`}>
|
||||
{filteredSuggestions.map((suggestion, index) => (
|
||||
<li key={index} onClick={() => handleSuggestionClick(suggestion)}><TagView tag={suggestion}></TagView>{index == heighlightedSuggestion && "+"}</li>
|
||||
<li key={index} onClick={() => handleSuggestionClick(suggestion)}><TagView heighlight={index == heighlightedSuggestion} tag={suggestion}></TagView></li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -10,6 +10,7 @@ import { useAuth } from "../../../Auth";
|
||||
import { getValue } from "../../../../Utils/GetValue";
|
||||
import { useAssetApi } from '../../../AppShell/hooks/useAssets'
|
||||
import DialogModal from "../../../Templates/DialogModal";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
|
||||
|
||||
@ -31,6 +32,7 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
const { user } = useAuth();
|
||||
|
||||
const assetsApi = useAssetApi();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const avatar = item.layer?.itemAvatarField && item && getValue(item, item.layer?.itemAvatarField)? assetsApi.url + getValue(item, item.layer?.itemAvatarField ) : undefined;
|
||||
const title = item.layer?.itemNameField && item ? getValue(item, item.layer?.itemNameField) : undefined;
|
||||
@ -98,8 +100,11 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
</svg>
|
||||
</label>
|
||||
<ul tabIndex={0} className="tw-dropdown-content tw-menu tw-p-2 tw-shadow tw-bg-base-100 tw-rounded-box tw-z-1000">
|
||||
{item.layer.api.updateItem && hasUserPermission(item.layer.api?.collectionName!, "update") && <li>
|
||||
<a className="!tw-text-base-content" onClick={openEditPopup}>
|
||||
{((item.layer.api.updateItem && hasUserPermission(item.layer.api?.collectionName!, "update")) || item.layer.customEditLink) && <li>
|
||||
<a className="!tw-text-base-content tw-cursor-pointer" onClick={(e) => {
|
||||
item.layer?.customEditLink && navigate(item.layer.customEditLink);
|
||||
!item.layer?.customEditLink && openEditPopup(e);
|
||||
}}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
|
||||
</svg>
|
||||
@ -107,7 +112,7 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
</li>}
|
||||
|
||||
{item.layer.api.deleteItem && hasUserPermission(item.layer.api?.collectionName!, "delete") && <li>
|
||||
<a className=' !tw-text-error' onClick={openDeleteModal}>
|
||||
<a className='tw-cursor-pointer !tw-text-error' onClick={openDeleteModal}>
|
||||
{loading ? <span className="tw-loading tw-loading-spinner tw-loading-sm"></span>
|
||||
:
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
|
||||
@ -97,6 +97,15 @@ function useTagsManager(initialTags: Tag[]): {
|
||||
itemTags.push(tags.find(t => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())!)
|
||||
}
|
||||
})
|
||||
item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField).map(o => {
|
||||
const offer = tags.find(t=> t.id === o.tags_id)
|
||||
offer && itemTags.push(offer)
|
||||
});
|
||||
item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField).map(n => {
|
||||
const need = tags.find(t=>t.id === n.tags_id);
|
||||
need && itemTags.push(need);
|
||||
});
|
||||
|
||||
return itemTags
|
||||
}, [tags]);
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import * as React from 'react'
|
||||
import { CardPage, MapOverlayPage } from '../Templates'
|
||||
import { MapOverlayPage } from '../Templates'
|
||||
import { useItems } from '../Map/hooks/useItems'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { useState } from 'react';
|
||||
import { Item } from '../../types';
|
||||
import { Item, UserItem } from '../../types';
|
||||
import { getValue } from '../../Utils/GetValue';
|
||||
import { useMap } from 'react-leaflet';
|
||||
import { LatLng } from 'leaflet';
|
||||
@ -11,6 +11,8 @@ import { TextView } from '../Map';
|
||||
import useWindowDimensions from '../Map/hooks/useWindowDimension';
|
||||
import { TagView } from '../Templates/TagView';
|
||||
import { useTags } from '../Map/hooks/useTags';
|
||||
import { useAuth } from '../Auth';
|
||||
import { useAddFilterTag } from '../Map/hooks/useFilter';
|
||||
|
||||
export function OverlayProfile() {
|
||||
|
||||
@ -21,8 +23,13 @@ export function OverlayProfile() {
|
||||
const windowDimension = useWindowDimensions();
|
||||
|
||||
const tags = useTags();
|
||||
const { user } = useAuth();
|
||||
|
||||
console.log(item);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [owner, setOwner] = useState<UserItem>();
|
||||
|
||||
const addFilterTag = useAddFilterTag();
|
||||
|
||||
|
||||
|
||||
@ -30,6 +37,10 @@ export function OverlayProfile() {
|
||||
const itemId = location.pathname.split("/")[2];
|
||||
const item = items.find(i => i.id === itemId);
|
||||
item && setItem(item);
|
||||
console.log(item);
|
||||
console.log(user);
|
||||
|
||||
item?.layer?.itemOwnerField && setOwner(getValue(item, item.layer?.itemOwnerField));
|
||||
const bounds = map.getBounds();
|
||||
const x = bounds.getEast() - bounds.getWest()
|
||||
if (windowDimension.width > 768)
|
||||
@ -39,41 +50,53 @@ export function OverlayProfile() {
|
||||
|
||||
|
||||
return (
|
||||
<MapOverlayPage className='tw-mx-4 tw-mt-4 tw-max-h-[calc(100dvh-96px)] tw-h-[calc(100dvh-96px)] md:tw-w-[calc(50%-32px)] tw-w-[calc(100%-32px)] tw-max-w-2xl !tw-left-auto tw-top-0 tw-bottom-0'>
|
||||
<MapOverlayPage className='tw-mx-4 tw-mt-4 tw-max-h-[calc(100dvh-96px)] tw-h-[calc(100dvh-96px)] md:tw-w-[calc(50%-32px)] tw-w-[calc(100%-32px)] tw-max-w-3xl !tw-left-auto tw-top-0 tw-bottom-0'>
|
||||
{item &&
|
||||
<>
|
||||
<div className="flex flex-row tw-w-full">
|
||||
<p className="text-4xl">{item.layer?.itemAvatarField && getValue(item, item.layer.itemAvatarField) && <img className='h-20 rounded-full inline' src={`https://api.utopia-lab.org/assets/${getValue(item, item.layer.itemAvatarField)}?width=160&heigth=160`}></img>} {item.layer?.itemNameField && getValue(item, item.layer.itemNameField)}</p>
|
||||
<div className='tw-flex tw-flex-row'>
|
||||
<div className="tw-grow">
|
||||
<p className="text-4xl">{item.layer?.itemAvatarField && getValue(item, item.layer.itemAvatarField) && <img className='h-20 rounded-full inline' src={`https://api.utopia-lab.org/assets/${getValue(item, item.layer.itemAvatarField)}?width=160&heigth=160`}></img>} {item.layer?.itemNameField && getValue(item, item.layer.itemNameField)}</p>
|
||||
</div>
|
||||
{owner?.id === user?.id ?
|
||||
<a className='tw-self-center tw-btn tw-btn-sm tw-mr-4 tw-cursor-pointer' onClick={() => navigate("/profile-settings")}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
|
||||
</svg>
|
||||
</a> : ""
|
||||
}
|
||||
</div>
|
||||
<div className='tw-overflow-y-auto tw-h-full tw-pt-4 fade tw-pb-4'>
|
||||
{
|
||||
item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField).length > 0 ?
|
||||
<>
|
||||
<h3 className='-tw-mb-2'>Offers</h3>
|
||||
< div className='tw-flex tw-flex-wrap tw-mb-2'>
|
||||
{
|
||||
item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField).map(o => {
|
||||
const tag = tags.find(t => t.id === o.tags_id);
|
||||
return (tag ? <TagView key={tag?.id} tag={tag} /> : "")
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</> : ""
|
||||
}
|
||||
{
|
||||
item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField).length > 0 ?
|
||||
<>
|
||||
<h3 className='-tw-mb-2'>Needs</h3>
|
||||
< div className='tw-flex tw-flex-wrap tw-mb-4'>
|
||||
{
|
||||
item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField).map(o => {
|
||||
const tag = tags.find(t => t.id === o.tags_id);
|
||||
return (tag ? <TagView key={tag?.id} tag={tag} /> : "")
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</> : ""
|
||||
}
|
||||
|
||||
<div className='tw-overflow-y-auto tw-h-full tw-pt-4 fade'>
|
||||
<div className='tw-grid tw-grid-cols-1 xl:tw-grid-cols-2'>
|
||||
{
|
||||
item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField).length > 0 ?
|
||||
<div className='tw-col-span-1'>
|
||||
<h3 className='-tw-mb-2'>Offers</h3>
|
||||
< div className='tw-flex tw-flex-wrap tw-mb-2'>
|
||||
{
|
||||
item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField).map(o => {
|
||||
const tag = tags.find(t => t.id === o.tags_id);
|
||||
return (tag ? <TagView key={tag?.id} tag={tag} onClick={() => addFilterTag(tag)}/> : "")
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div> : ""
|
||||
}
|
||||
{
|
||||
item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField).length > 0 ?
|
||||
<div className='tw-col-span-1'>
|
||||
<h3 className='-tw-mb-2 tw-col-span-1'>Needs</h3>
|
||||
< div className='tw-flex tw-flex-wrap tw-mb-4'>
|
||||
{
|
||||
item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField).map(o => {
|
||||
const tag = tags.find(t => t.id === o.tags_id);
|
||||
return (tag ? <TagView key={tag?.id} tag={tag} onClick={() => addFilterTag(tag)}/> : "")
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div> : ""
|
||||
}
|
||||
</div>
|
||||
<TextView item={item} />
|
||||
</div>
|
||||
</>
|
||||
|
||||
@ -223,7 +223,7 @@ export function OverlayProfileSettings() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<MapOverlayPage backdrop className='tw-mx-4 tw-mt-4 tw-mb-12 tw-overflow-x-hidden tw-max-h-[calc(100dvh-96px)] !tw-h-[calc(100dvh-96px)] tw-w-[calc(100%-32px)] md:tw-w-[calc(50%-32px)] tw-max-w-2xl !tw-left-auto tw-top-0 tw-bottom-0'>
|
||||
<MapOverlayPage backdrop className='tw-mx-4 tw-mt-4 tw-mb-12 tw-overflow-x-hidden tw-max-h-[calc(100dvh-96px)] !tw-h-[calc(100dvh-96px)] tw-w-[calc(100%-32px)] md:tw-w-[calc(50%-32px)] tw-max-w-3xl !tw-left-auto tw-top-0 tw-bottom-0'>
|
||||
<div className='tw-flex tw-flex-col tw-h-full'>
|
||||
<div className="tw-flex">
|
||||
{!cropping ?
|
||||
|
||||
@ -2,11 +2,11 @@ import * as React from 'react'
|
||||
import { decodeTag } from '../../Utils/FormatTags'
|
||||
import { Tag } from '../../types'
|
||||
|
||||
export const TagView = ({tag} : {tag: Tag}) => {
|
||||
export const TagView = ({tag, heighlight, onClick} : {tag: Tag, heighlight?: boolean, onClick?: (e)=> void}) => {
|
||||
return (
|
||||
// Use your imagination to render suggestions.
|
||||
|
||||
<div key={tag.name} className='tw-rounded-2xl tw-text-white tw-p-2 tw-px-4 tw-shadow-xl tw-card tw-h-[2.75em] tw-mt-3 tw-mr-4 tw-cursor-pointer tw-w-fit' style={{ backgroundColor: tag.color ? tag.color : "#666" }}>
|
||||
<div key={tag.name} onClick={onClick} className={`tw-rounded-2xl tw-text-white tw-p-2 tw-px-4 tw-shadow-xl tw-card tw-h-[2.75em] tw-mt-3 tw-mr-4 tw-cursor-pointer tw-w-fit ${heighlight && 'tw-border-primary tw-shadow-te-primary'}`} style={{ backgroundColor: tag.color ? tag.color : "#666" }}>
|
||||
<div className="tw-card-actions tw-justify-end">
|
||||
</div><b>#{decodeTag(tag.name)}</b>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user