diff --git a/src/Components/AppShell/AppShell.tsx b/src/Components/AppShell/AppShell.tsx index ee6e7c20..034c989b 100644 --- a/src/Components/AppShell/AppShell.tsx +++ b/src/Components/AppShell/AppShell.tsx @@ -15,6 +15,8 @@ import { LayersProvider } from '../Map/hooks/useLayers' import { LeafletRefsProvider } from '../Map/hooks/useLeafletRefs' import { SelectPositionProvider } from '../Map/hooks/useSelectPosition' import { ClusterRefProvider } from '../Map/hooks/useClusterRef' +import 'react-toastify/dist/ReactToastify.css'; + export function AppShell({ appName, children, assetsApi, userType }: { appName: string, children: React.ReactNode, assetsApi: AssetsApi, userType: string }) { diff --git a/src/Components/Profile/Editor.tsx b/src/Components/Profile/Editor.tsx deleted file mode 100644 index a3ce1733..00000000 --- a/src/Components/Profile/Editor.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from "react"; - -export function TextEditor({ value, updateFormValue }: { value: string, updateFormValue: (string) => void }) { - - console.log(value); - console.log(updateFormValue); - - - - return ( -
-
- ); -} diff --git a/src/Components/Profile/ItemForm.tsx b/src/Components/Profile/ItemForm.tsx deleted file mode 100644 index 1cf0dff3..00000000 --- a/src/Components/Profile/ItemForm.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { useState, useEffect } from "react"; -import { Item } from "../../types"; -import { useItems } from "../Map/hooks/useItems"; -import { useLocation } from "react-router-dom"; - - -export const OverlayItemProfileSettings = () => { - - const items = useItems(); - const [item, setItem] = useState({} as Item) - const location = useLocation(); - - - useEffect(() => { - const itemId = location.pathname.split("/")[2]; - const item = items.find(i => i.id === itemId); - item && setItem(item); - - }, [location, items]) - - return ( -
- -
- ) -} diff --git a/src/Components/Profile/OverlayProfile.tsx b/src/Components/Profile/OverlayProfile.tsx deleted file mode 100644 index 02746417..00000000 --- a/src/Components/Profile/OverlayProfile.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import * as React from 'react' -import { MapOverlayPage } from '../Templates' -import { useItems } from '../Map/hooks/useItems' -import { useLocation, useNavigate } from 'react-router-dom' -import { useEffect, useState } from 'react'; -import { Item, Tag, UserItem } from '../../types'; -import { getValue } from '../../Utils/GetValue'; -import { useMap } from 'react-leaflet'; -import { LatLng } from 'leaflet'; -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() { - - const location = useLocation(); - const items = useItems(); - const [item, setItem] = useState({} as Item) - const map = useMap(); - const windowDimension = useWindowDimensions(); - - const tags = useTags(); - const { user } = useAuth(); - - const navigate = useNavigate(); - - const [owner, setOwner] = useState(); - const [offers, setOffers] = useState>([]); - const [needs, setNeeds] = useState>([]); - - const [activeTab, setActiveTab] = useState(1); - - - const addFilterTag = useAddFilterTag(); - - - - useEffect(() => { - const itemId = location.pathname.split("/")[2]; - const item = items.find(i => i.id === itemId); - item && setItem(item); - - const bounds = map.getBounds(); - const x = bounds.getEast() - bounds.getWest() - if (windowDimension.width > 768) - if (item?.position?.coordinates[0]) - map.setView(new LatLng(item?.position.coordinates[1]!, item?.position.coordinates[0]! + x / 4)) - }, [location, items, activeTab]) - - - useEffect(() => { - setOffers([]); - setNeeds([]); - setOwner(undefined); - item?.layer?.itemOwnerField && setOwner(getValue(item, item.layer?.itemOwnerField)); - item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField).map(o => { - const tag = tags.find(t => t.id === o.tags_id); - tag && setOffers(current => [...current, tag]) - }) - item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField).map(n => { - const tag = tags.find(t => t.id === n.tags_id); - tag && setNeeds(current => [...current, tag]) - }) - }, [item]) - - - - - return ( - - {item && - <> -
-
-

{item.layer?.itemAvatarField && getValue(item, item.layer.itemAvatarField) && } {item.layer?.itemNameField && getValue(item, item.layer.itemNameField)}

-
- {owner?.id === user?.id && owner?.id ? - navigate("/profile-settings")}> - - - - : "" - } -
- - - - -
- -
- setActiveTab(1)} /> -
- -
- - setActiveTab(2)} /> -
-
-
- { - offers.length > 0 ? -
-

Offers

- < div className='tw-flex tw-flex-wrap tw-mb-4'> - { - offers.map(o => {console.log(o); - addFilterTag(o)}} />) - } -
-
: "" - } - { - needs.length > 0 ? -
-

Needs

- < div className='tw-flex tw-flex-wrap tw-mb-4'> - { - needs.map(n => addFilterTag(n)} />) - } -
-
: "" - } -
-
-
- - setActiveTab(3)} /> -
- -
- - - - - - - - } -
- ) -} - - diff --git a/src/Components/Profile/OverlayProfileSettings.tsx b/src/Components/Profile/OverlayProfileSettings.tsx deleted file mode 100644 index 68d8732b..00000000 --- a/src/Components/Profile/OverlayProfileSettings.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { useItems, useUpdateItem } from '../Map/hooks/useItems' -import { useEffect, useState } from 'react'; -import { getValue } from '../../Utils/GetValue'; -import { toast } from 'react-toastify'; -import { useAuth } from '../Auth'; -import { TextInput, TextAreaInput } from '../Input'; -import { ColorPicker } from './ColorPicker'; -import { hashTagRegex } from '../../Utils/HashTagRegex'; -import { useAddTag, useTags } from '../Map/hooks/useTags'; -import { randomColor } from '../../Utils/RandomColor'; -import { useNavigate } from 'react-router-dom'; -import { Tag, UserItem } from '../../types'; -import { MapOverlayPage } from '../Templates'; -import { TagsWidget } from './TagsWidget'; -import { encodeTag } from '../../Utils/FormatTags'; -import { AvatarWidget } from './AvatarWidget'; - - -export function OverlayProfileSettings() { - - const { user, updateUser, loading } = useAuth(); - - const [id, setId] = useState(""); - const [name, setName] = useState(""); - const [text, setText] = useState(""); - const [avatar, setAvatar] = useState(""); - const [color, setColor] = useState(""); - const [offers, setOffers] = useState>([]); - const [needs, setNeeds] = useState>([]); - const [contact, setContact] = useState(""); - - const [activeTab, setActiveTab] = useState(1); - - - - const items = useItems(); - const updateItem = useUpdateItem(); - - const tags = useTags(); - const addTag = useAddTag(); - const navigate = useNavigate(); - - useEffect(() => { - setId(user?.id ? user.id : ""); - setName(user?.first_name ? user.first_name : ""); - setText(user?.description ? user.description : ""); - setAvatar(user?.avatar ? user?.avatar : ""); - setColor(user?.color ? user.color : "#3D3846"); - setOffers([]); - setNeeds([]); - user?.offers.map(o=> { - const offer = tags.find(t => t.id === o.tags_id); - offer && setOffers(current => [...current,offer]) - }) - user?.needs.map(o=> { - const need = tags.find(t => t.id === o.tags_id); - need && setNeeds(current => [...current,need]) - }) - setContact(user?.contact ? user.contact : ""); - }, [user]) - - - const onUpdateUser = async () => { - let changedUser = {} as UserItem; - - let offer_updates : Array = []; - //check for new offers - offers.map(o => { - const existingOffer = user?.offers.find(t => t.tags_id === o.id) - existingOffer && offer_updates.push(existingOffer.id) - if(!existingOffer && !tags.some(t => t.id === o.id)) addTag({...o,offer_or_need: true}) - !existingOffer && offer_updates.push({directus_user_id: user?.id, tags_id: o.id}) - }); - - let needs_updates : Array = []; - - needs.map(n => { - const existingNeed = user?.needs.find(t => t.tags_id === n.id) - existingNeed && needs_updates.push(existingNeed.id) - !existingNeed && needs_updates.push({directus_user_id: user?.id, tags_id: n.id}) - !existingNeed && !tags.some(t => t.id === n.id) && addTag({...n,offer_or_need: true}) - }); - - - changedUser = { id: id, first_name: name, description: text, contact: contact, color: color, ...avatar.length > 10 && { avatar: avatar }, ... offers.length > 0 && {offers: offer_updates}, ... needs.length > 0 && {needs: needs_updates} }; - // update profile item in current state - const item = items.find(i => i.layer?.itemOwnerField && getValue(i, i.layer?.itemOwnerField).id === id); - - let offer_state : Array = []; - let needs_state : Array = []; - - await offers.map(o => { - offer_state.push({directus_user_id: user?.id, tags_id: o.id}) - }); - - await needs.map(n => { - needs_state.push({directus_user_id: user?.id, tags_id: n.id}) - }); - - - if (item && item.layer && item.layer.itemOwnerField) item[item.layer.itemOwnerField] = {... changedUser, offers: offer_state, needs: needs_state}; - // add new hashtags from profile text - text.toLocaleLowerCase().match(hashTagRegex)?.map(tag => { - if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) { - addTag({ id: crypto.randomUUID(), name: encodeTag(tag.slice(1).toLocaleLowerCase()), color: randomColor()}) - } - }); - - - toast.promise( - updateUser(changedUser), - { - pending: 'updating Profile ...', - success: 'Profile updated', - error: { - render({ data }) { - return `${data}` - }, - }, - }) - .then(() => item && updateItem(item)) - .then(() => navigate("/")); - } - - - return ( - <> - -
-
- - - setName(v)} containerStyle='tw-grow tw-ml-6 tw-my-auto ' /> -
- - -
- setActiveTab(1)} /> -
- setText(v)} containerStyle='tw-h-full' inputStyle='tw-h-full tw-border-t-0 tw-rounded-tl-none' /> -
- - setActiveTab(2)} /> -
-
-
- setOffers(v)} placeholder="enter your offers" containerStyle='tw-bg-transparent tw-w-full tw-h-full tw-mt-3 tw-text-xs tw-h-[calc(100%-1rem)] tw-min-h-[5em] tw-pb-2 tw-overflow-auto'/> -
-
- setNeeds(v)} placeholder="enter your needs" containerStyle='tw-bg-transparent tw-w-full tw-h-full tw-mt-3 tw-text-xs tw-h-[calc(100%-1rem)] tw-min-h-[5em] tw-pb-2 tw-overflow-auto'/> -
-
-
- - setActiveTab(3)} /> -
- setContact(v)} containerStyle='tw-h-full' inputStyle='tw-h-full tw-border-t-0 ' /> -
-
- -
- -
- -
- - ) -} - - diff --git a/src/Components/Profile/OverlayItemProfileSettings.tsx b/src/Components/Profile/ProfileForm.tsx similarity index 98% rename from src/Components/Profile/OverlayItemProfileSettings.tsx rename to src/Components/Profile/ProfileForm.tsx index f1157c26..a867e4ff 100644 --- a/src/Components/Profile/OverlayItemProfileSettings.tsx +++ b/src/Components/Profile/ProfileForm.tsx @@ -5,25 +5,25 @@ import { toast } from 'react-toastify'; import { useAuth } from '../Auth'; import { TextInput, TextAreaInput } from '../Input'; import ComboBoxInput from '../Input/ComboBoxInput'; -import { ColorPicker } from './ColorPicker'; +import { ColorPicker } from './Subcomponents/ColorPicker'; import { hashTagRegex } from '../../Utils/HashTagRegex'; import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags'; import { randomColor } from '../../Utils/RandomColor'; import { useLocation, useNavigate } from 'react-router-dom'; import { Item, Tag } from '../../types'; import { MapOverlayPage } from '../Templates'; -import { AvatarWidget } from './AvatarWidget'; +import { AvatarWidget } from './Subcomponents/AvatarWidget'; import { encodeTag } from '../../Utils/FormatTags'; import { useLayers } from '../Map/hooks/useLayers'; -import { TagsWidget } from './TagsWidget'; -import { LinkedItemsHeaderView } from './LinkedItemsHeaderView'; +import { TagsWidget } from './Subcomponents/TagsWidget'; +import { LinkedItemsHeaderView } from './Subcomponents/LinkedItemsHeaderView'; import { TextView } from '../Map'; -import { ActionButton } from './ActionsButton'; +import { ActionButton } from './Subcomponents/ActionsButton'; import { useHasUserPermission } from '../Map/hooks/usePermissions'; -export function OverlayItemProfileSettings({ userType }: { userType: string }) { +export function ProfileForm({ userType }: { userType: string }) { const typeMapping = [ { value: 'wuerdekompass', label: 'Regional-Gruppe' }, diff --git a/src/Components/Profile/ProfileSettings.tsx b/src/Components/Profile/ProfileSettings.tsx deleted file mode 100644 index 7f299f7e..00000000 --- a/src/Components/Profile/ProfileSettings.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import { useEffect, useRef, useState } from 'react' -import { TitleCard } from '../Templates/TitleCard' -import { TextInput } from '../Input/TextInput' -import { TextAreaInput } from '../Input/TextAreaInput' -import { toast } from 'react-toastify'; -import { useNavigate } from 'react-router-dom' -import { useAuth } from '../Auth'; -import * as React from 'react' -import ReactCrop, { Crop, centerCrop, makeAspectCrop } from 'react-image-crop' -import 'react-image-crop/dist/ReactCrop.css' -import 'react-toastify/dist/ReactToastify.css'; -import { UserItem } from '../../types'; -import DialogModal from '../Templates/DialogModal'; -import { useAssetApi } from '../AppShell/hooks/useAssets'; -import { ColorPicker } from './ColorPicker'; - -export function ProfileSettings() { - const { user, updateUser, loading, token } = useAuth(); - - const [id, setId] = useState(""); - const [name, setName] = useState(""); - const [text, setText] = useState(""); - const [avatar, setAvatar] = useState(""); - const [color, setColor] = useState(""); - - - const [crop, setCrop] = useState(); - const [image, setImage] = useState(""); - const [cropModalOpen, setCropModalOpen] = useState(false); - const [cropping, setCropping] = useState(false); - - const assetsApi = useAssetApi(); - const navigate = useNavigate(); - - useEffect(() => { - setId(user?.id ? user.id : ""); - setName(user?.first_name ? user.first_name : ""); - setText(user?.description ? user.description : ""); - setAvatar(user?.avatar ? user?.avatar : ""), - setColor(user?.color? user.color : "#aabbcc") - }, [user]) - - const imgRef = useRef(null) - - const onImageChange = (event) => { - if (event.target.files && event.target.files[0]) { - setImage(URL.createObjectURL(event.target.files[0])); - } - setCropModalOpen(true); - } - - function onImageLoad(e: React.SyntheticEvent) { - const { width, height } = e.currentTarget - - setCrop(centerAspectCrop(width, height, 1)) - } - - - // This is to demonstate how to make and center a % aspect crop - // which is a bit trickier so we use some helper functions. - function centerAspectCrop( - mediaWidth: number, - mediaHeight: number, - aspect: number, - ) { - return centerCrop( - makeAspectCrop( - { - unit: 'px', - width: mediaWidth / 2, - }, - aspect, - mediaWidth, - mediaHeight, - ), - mediaWidth, - mediaHeight, - ) - } - - async function renderCrop() { - // get the image element - const image = imgRef.current; - if (crop && image) { - - const scaleX = image.naturalWidth / image.width - const scaleY = image.naturalHeight / image.height - - // create a canvas element to draw the cropped image - const canvas = new OffscreenCanvas( - crop.width * scaleX, - crop.height * scaleY, - ) - const ctx = canvas.getContext("2d"); - const pixelRatio = window.devicePixelRatio; - canvas.width = crop.width * pixelRatio * scaleX; - canvas.height = crop.height * pixelRatio * scaleY; - - if (ctx) { - ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); - - ctx.drawImage( - image, - crop.x * scaleX, - crop.y * scaleY, - crop.width * scaleX, - crop.height * scaleY, - 0, - 0, - crop.width * scaleX, - crop.height * scaleY - ); - } - const blob = await canvas.convertToBlob(); - await resizeBlob(blob); - setCropping(false); - setImage(""); - } - } - - async function resizeBlob(blob) { - var img = new Image(); - img.src = URL.createObjectURL(blob); - await img.decode(); - const canvas = new OffscreenCanvas( - 400, - 400 - ) - var ctx = canvas.getContext("2d"); - ctx?.drawImage(img, 0, 0, 400, 400); - const resizedBlob = await canvas.convertToBlob() - const asset = await assetsApi.upload(resizedBlob, "test"); - setAvatar(asset.id) - } - - - const onUpdateUser = () => { - let changedUser = {} as UserItem; - - changedUser = { id: id, first_name: name, description: text, color: color, ...avatar.length > 10 && { avatar: avatar } }; - - - toast.promise( - - updateUser(changedUser), - { - pending: 'updating Profile ...', - success: 'Profile updated', - error: { - render({ data }) { - return `${data}` - }, - }, - }) - .then(() => navigate("/")); - } - - - return ( -
-
-
- -
- {!cropping ? - - - :
- -
- - } - - setName(v)} containerStyle='tw-grow tw-ml-6 tw-my-auto ' /> -
- -
- setText(v)} inputStyle='tw-h-64' /> -
- -
- -
-
-
- { - setCropModalOpen(false); - setImage(""); - }}> - setCrop(c)} aspect={1} > - - - - -
- ) -} diff --git a/src/Components/Profile/OverlayItemProfile.tsx b/src/Components/Profile/ProfileView.tsx similarity index 98% rename from src/Components/Profile/OverlayItemProfile.tsx rename to src/Components/Profile/ProfileView.tsx index 20181ba4..8462bb47 100644 --- a/src/Components/Profile/OverlayItemProfile.tsx +++ b/src/Components/Profile/ProfileView.tsx @@ -14,19 +14,19 @@ import { randomColor } from '../../Utils/RandomColor'; import { toast } from 'react-toastify'; import { useAuth } from '../Auth'; import { useLayers } from '../Map/hooks/useLayers'; -import { ActionButton } from './ActionsButton'; -import { LinkedItemsHeaderView } from './LinkedItemsHeaderView'; +import { ActionButton } from './Subcomponents/ActionsButton'; +import { LinkedItemsHeaderView } from './Subcomponents/LinkedItemsHeaderView'; import { HeaderView } from '../Map/Subcomponents/ItemPopupComponents/HeaderView'; import { useSelectPosition, useSetSelectPosition } from '../Map/hooks/useSelectPosition'; import { useClusterRef } from '../Map/hooks/useClusterRef'; import { useLeafletRefs } from '../Map/hooks/useLeafletRefs'; import { getValue } from '../../Utils/GetValue'; import { TagView } from '../Templates/TagView'; -import RelationCard from "./RelationCard"; -import ContactInfo from "./ContactInfo"; -import ProfileSubHeader from "./ProfileSubHeader"; +import RelationCard from "./Subcomponents/RelationCard"; +import ContactInfo from "./Subcomponents/ContactInfo"; +import ProfileSubHeader from "./Subcomponents/ProfileSubHeader"; -export function OverlayItemProfile({ userType }: { userType: string }) { +export function ProfileView({ userType }: { userType: string }) { const [updatePermission, setUpdatePermission] = useState(false); const [relations, setRelations] = useState>([]); diff --git a/src/Components/Profile/ActionsButton.tsx b/src/Components/Profile/Subcomponents/ActionsButton.tsx similarity index 91% rename from src/Components/Profile/ActionsButton.tsx rename to src/Components/Profile/Subcomponents/ActionsButton.tsx index 3d566d87..e2465841 100644 --- a/src/Components/Profile/ActionsButton.tsx +++ b/src/Components/Profile/Subcomponents/ActionsButton.tsx @@ -1,12 +1,12 @@ import { useState } from "react"; -import { useHasUserPermission, usePermissions } from "../Map/hooks/usePermissions"; -import DialogModal from "../Templates/DialogModal"; -import { useItems } from "../Map/hooks/useItems"; -import { HeaderView } from "../Map/Subcomponents/ItemPopupComponents/HeaderView"; -import { Item } from "../../types"; -import { TextInput } from "../Input"; -import { getValue } from "../../Utils/GetValue"; -import { useGetItemTags } from "../Map/hooks/useTags"; +import { useHasUserPermission, usePermissions } from "../../Map/hooks/usePermissions"; +import DialogModal from "../../Templates/DialogModal"; +import { useItems } from "../../Map/hooks/useItems"; +import { HeaderView } from "../../Map/Subcomponents/ItemPopupComponents/HeaderView"; +import { Item } from "../../../types"; +import { TextInput } from "../../Input"; +import { getValue } from "../../../Utils/GetValue"; +import { useGetItemTags } from "../../Map/hooks/useTags"; export function ActionButton({ item, triggerAddButton, triggerItemSelected, existingRelations, itemType, colorField, collection = "items", customStyle }: { triggerAddButton?: any, diff --git a/src/Components/Profile/AvatarWidget.tsx b/src/Components/Profile/Subcomponents/AvatarWidget.tsx similarity index 97% rename from src/Components/Profile/AvatarWidget.tsx rename to src/Components/Profile/Subcomponents/AvatarWidget.tsx index c892dce9..82e52142 100644 --- a/src/Components/Profile/AvatarWidget.tsx +++ b/src/Components/Profile/Subcomponents/AvatarWidget.tsx @@ -1,8 +1,9 @@ import * as React from "react"; import { useState } from "react"; import ReactCrop, { Crop, centerCrop, makeAspectCrop } from 'react-image-crop'; -import { useAssetApi } from '../AppShell/hooks/useAssets'; -import DialogModal from "../Templates/DialogModal"; +import { useAssetApi } from '../../AppShell/hooks/useAssets'; +import DialogModal from "../../Templates/DialogModal"; +import 'react-image-crop/dist/ReactCrop.css' export const AvatarWidget = ({avatar, setAvatar}:{avatar:string, setAvatar : React.Dispatch>}) => { diff --git a/src/Components/Profile/ColorPicker.css b/src/Components/Profile/Subcomponents/ColorPicker.css similarity index 100% rename from src/Components/Profile/ColorPicker.css rename to src/Components/Profile/Subcomponents/ColorPicker.css diff --git a/src/Components/Profile/ColorPicker.tsx b/src/Components/Profile/Subcomponents/ColorPicker.tsx similarity index 96% rename from src/Components/Profile/ColorPicker.tsx rename to src/Components/Profile/Subcomponents/ColorPicker.tsx index a35c07ee..775a7e23 100644 --- a/src/Components/Profile/ColorPicker.tsx +++ b/src/Components/Profile/Subcomponents/ColorPicker.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import * as React from "react"; import { HexColorPicker } from "react-colorful"; import "./ColorPicker.css" -import useClickOutside from "./useClickOutside"; +import useClickOutside from "../hooks/useClickOutside"; export const ColorPicker = ({ color, onChange, className }) => { const popover = useRef(null); diff --git a/src/Components/Profile/ContactInfo.tsx b/src/Components/Profile/Subcomponents/ContactInfo.tsx similarity index 98% rename from src/Components/Profile/ContactInfo.tsx rename to src/Components/Profile/Subcomponents/ContactInfo.tsx index 15149079..0ba74f1c 100644 --- a/src/Components/Profile/ContactInfo.tsx +++ b/src/Components/Profile/Subcomponents/ContactInfo.tsx @@ -1,5 +1,5 @@ import { Link } from "react-router-dom"; -import { useAssetApi } from "../AppShell/hooks/useAssets"; +import { useAssetApi } from "../../AppShell/hooks/useAssets"; const ContactInfo = ({ email, telephone, name, avatar, link }: { email: string, telephone: string, name: string, avatar: string, link?: string }) => { const assetsApi = useAssetApi(); diff --git a/src/Components/Profile/LinkedItemsHeaderView.tsx b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx similarity index 96% rename from src/Components/Profile/LinkedItemsHeaderView.tsx rename to src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx index a6a462aa..aba10388 100644 --- a/src/Components/Profile/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 { getValue } from "../../../Utils/GetValue"; +import { Item } from "../../../types"; +import { useAssetApi } from "../../AppShell/hooks/useAssets"; diff --git a/src/Components/Profile/PlusButton.tsx b/src/Components/Profile/Subcomponents/PlusButton.tsx similarity index 89% rename from src/Components/Profile/PlusButton.tsx rename to src/Components/Profile/Subcomponents/PlusButton.tsx index 5a6f0e37..99e75c5d 100644 --- a/src/Components/Profile/PlusButton.tsx +++ b/src/Components/Profile/Subcomponents/PlusButton.tsx @@ -1,5 +1,5 @@ -import { LayerProps } from "../../types"; -import { useHasUserPermission } from "../Map/hooks/usePermissions"; +import { LayerProps } from "../../../types"; +import { useHasUserPermission } from "../../Map/hooks/usePermissions"; export function PlusButton({ layer, triggerAction, color, collection="items" }: { layer?: LayerProps ,triggerAction: any, color: string, collection?:string }) { const hasUserPermission = useHasUserPermission(); diff --git a/src/Components/Profile/ProfileSubHeader.tsx b/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx similarity index 100% rename from src/Components/Profile/ProfileSubHeader.tsx rename to src/Components/Profile/Subcomponents/ProfileSubHeader.tsx diff --git a/src/Components/Profile/RelationCard.tsx b/src/Components/Profile/Subcomponents/RelationCard.tsx similarity index 100% rename from src/Components/Profile/RelationCard.tsx rename to src/Components/Profile/Subcomponents/RelationCard.tsx diff --git a/src/Components/Profile/SocialShareBar.tsx b/src/Components/Profile/Subcomponents/SocialShareBar.tsx similarity index 100% rename from src/Components/Profile/SocialShareBar.tsx rename to src/Components/Profile/Subcomponents/SocialShareBar.tsx diff --git a/src/Components/Profile/SocialShareButton.tsx b/src/Components/Profile/Subcomponents/SocialShareButton.tsx similarity index 100% rename from src/Components/Profile/SocialShareButton.tsx rename to src/Components/Profile/Subcomponents/SocialShareButton.tsx diff --git a/src/Components/Profile/TagsWidget.tsx b/src/Components/Profile/Subcomponents/TagsWidget.tsx similarity index 92% rename from src/Components/Profile/TagsWidget.tsx rename to src/Components/Profile/Subcomponents/TagsWidget.tsx index 49173ed5..511d7266 100644 --- a/src/Components/Profile/TagsWidget.tsx +++ b/src/Components/Profile/Subcomponents/TagsWidget.tsx @@ -1,10 +1,10 @@ import * as React from 'react' import { useState } from 'react'; -import { useTags } from '../Map/hooks/useTags'; -import { Tag } from '../../types'; -import { Autocomplete } from '../Input/Autocomplete'; -import { randomColor } from '../../Utils/RandomColor'; -import { decodeTag, encodeTag } from '../../Utils/FormatTags'; +import { useTags } from '../../Map/hooks/useTags'; +import { Tag } from '../../../types'; +import { Autocomplete } from '../../Input/Autocomplete'; +import { randomColor } from '../../../Utils/RandomColor'; +import { decodeTag, encodeTag } from '../../../Utils/FormatTags'; export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate}) => { diff --git a/src/Components/Profile/Templates/Onepager.tsx b/src/Components/Profile/Templates/Onepager.tsx new file mode 100644 index 00000000..720a2adf --- /dev/null +++ b/src/Components/Profile/Templates/Onepager.tsx @@ -0,0 +1,7 @@ +import * as React from 'react' + +export const Onepager = () => { + return ( +
Onepager
+ ) +} diff --git a/src/Components/Profile/Templates/Simple.tsx b/src/Components/Profile/Templates/Simple.tsx new file mode 100644 index 00000000..f6fa8701 --- /dev/null +++ b/src/Components/Profile/Templates/Simple.tsx @@ -0,0 +1,7 @@ +import * as React from 'react' + +export const Simple = () => { + return ( +
Simple
+ ) +} diff --git a/src/Components/Profile/Templates/Tabs.tsx b/src/Components/Profile/Templates/Tabs.tsx new file mode 100644 index 00000000..dd09cb9c --- /dev/null +++ b/src/Components/Profile/Templates/Tabs.tsx @@ -0,0 +1,7 @@ +import * as React from 'react' + +export const Tabs = () => { + return ( +
Tabs
+ ) +} diff --git a/src/Components/Profile/UserSettings.tsx b/src/Components/Profile/UserSettings.tsx deleted file mode 100644 index f01d6f60..00000000 --- a/src/Components/Profile/UserSettings.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { useEffect, useRef, useState } from 'react' -import { TitleCard } from '../Templates/TitleCard' -import { TextInput } from '../Input/TextInput' -import { TextAreaInput } from '../Input/TextAreaInput' -import { toast } from 'react-toastify'; -import { useNavigate } from 'react-router-dom' -import { useAuth } from '../Auth'; -import * as React from 'react' -import ReactCrop, { Crop, centerCrop, makeAspectCrop } from 'react-image-crop' -import 'react-image-crop/dist/ReactCrop.css' -import 'react-toastify/dist/ReactToastify.css'; -import { UserItem } from '../../types'; -import DialogModal from '../Templates/DialogModal'; -import { useAssetApi } from '../AppShell/hooks/useAssets'; -import { ColorPicker } from './ColorPicker'; - -export function UserSettings() { - const { user, updateUser, loading, token } = useAuth(); - - const [id, setId] = useState(""); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - - - - const [passwordChanged, setPasswordChanged] = useState(false); - - - - const navigate = useNavigate(); - - useEffect(() => { - setId(user?.id ? user.id : ""); - setEmail(user?.email ? user.email : ""); - setPassword(user?.password ? user.password : ""); - }, [user]) - - - - - - - const onUpdateUser = () => { - let changedUser = {} as UserItem; - - changedUser = { id: id, email: email, ...passwordChanged && { password: password }}; - - - toast.promise( - - updateUser(changedUser), - { - pending: 'updating Profile ...', - success: 'Profile updated', - error: { - render({ data }) { - return `${data}` - }, - }, - }) - .then(() => navigate("/")); - } - - - return ( - <> -
-
- - - -
- setEmail(v)} /> - { - setPassword(v); - setPasswordChanged(true); - }} /> - {/* */} -
- -
- -
-
-
- - ) -} diff --git a/src/Components/Profile/useClickOutside.tsx b/src/Components/Profile/hooks/useClickOutside.tsx similarity index 100% rename from src/Components/Profile/useClickOutside.tsx rename to src/Components/Profile/hooks/useClickOutside.tsx diff --git a/src/Components/Profile/index.tsx b/src/Components/Profile/index.tsx index bbc41f89..db977614 100644 --- a/src/Components/Profile/index.tsx +++ b/src/Components/Profile/index.tsx @@ -1,8 +1,4 @@ -export {UserSettings} from './UserSettings' -export {ProfileSettings} from './ProfileSettings' -export {OverlayProfile} from './OverlayProfile' -export {OverlayProfileSettings} from './OverlayProfileSettings' export {OverlayUserSettings} from './OverlayUserSettings' -export {OverlayItemProfile} from './OverlayItemProfile' -export {OverlayItemProfileSettings} from './OverlayItemProfileSettings' -export {PlusButton} from "./PlusButton" \ No newline at end of file +export {PlusButton} from "./Subcomponents/PlusButton" +export {ProfileView} from "./ProfileView" +export {ProfileForm} from "./ProfileForm" \ No newline at end of file diff --git a/src/Components/Templates/ItemsIndexPage.tsx b/src/Components/Templates/ItemsIndexPage.tsx deleted file mode 100644 index 8146492f..00000000 --- a/src/Components/Templates/ItemsIndexPage.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import { ReactNode, useEffect, useRef, useState } from 'react' -import { Link, useNavigate } from 'react-router-dom'; -import { Item, ItemsApi } from '../../types'; -import { getValue } from '../../Utils/GetValue'; -import { TextView } from '../Map'; -import { useAssetApi } from '../AppShell/hooks/useAssets'; -import { PlusButton } from '../Profile/PlusButton'; -import { TextInput, TextAreaInput } from '../Input'; -import { useAddTag, useTags } from '../Map/hooks/useTags'; -import { useAddItem } from '../Map/hooks/useItems'; -import { useResetFilterTags } from '../Map/hooks/useFilter'; -import { toast } from 'react-toastify'; -import { hashTagRegex } from '../../Utils/HashTagRegex'; -import { randomColor } from '../../Utils/RandomColor'; -import { useAuth } from '../Auth'; -import { useLayers } from '../Map/hooks/useLayers'; -import { HeaderView } from '../Map/Subcomponents/ItemPopupComponents/HeaderView'; - - -type breadcrumb = { - name: string, - path: string -} - - -export const ItemsIndexPage = ({ api, url, parameterField, breadcrumbs, itemNameField, itemTextField, itemImageField, itemSymbolField, itemSubnameField, children }: { api: ItemsApi, url: string, parameterField: string, breadcrumbs: Array, itemNameField: string, itemTextField: string, itemImageField: string, itemSymbolField: string, itemSubnameField: string, children?: ReactNode }) => { - - console.log(itemSymbolField); - - const [loading, setLoading] = useState(false); - const [addItemPopupType, setAddItemPopupType] = useState(""); - - const tabRef = useRef(null); - - function scroll() { - tabRef.current?.scrollIntoView(); - } - - useEffect(() => { - scroll(); - }, [addItemPopupType]) - - const [items, setItems] = useState([]); - - const loadProjects = async () => { - const items = await api?.getItems(); - setItems(items as any); - } - - const navigate = useNavigate(); - - const tags = useTags(); - const addTag = useAddTag(); - const { user } = useAuth(); - - - useEffect(() => { - loadProjects(); - }, [api]) - - const layers = useLayers(); - - const submitNewItem = async (evt: any, type: string) => { - evt.preventDefault(); - const formItem: Item = {} as Item; - Array.from(evt.target).forEach((input: HTMLInputElement) => { - if (input.name) { - formItem[input.name] = input.value; - } - }); - setLoading(true); - formItem.text && formItem.text.toLocaleLowerCase().match(hashTagRegex)?.map(tag => { - if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) { - addTag({ id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() }) - } - }); - const uuid = crypto.randomUUID(); - let success = false; - try { - await api?.createItem!({ ...formItem, id: uuid, type: type }); - success = true; - } catch (error) { - toast.error(error.toString()); - } - if (success) { - toast.success("New item created"); - } - setLoading(false); - setAddItemPopupType(""); - setItems(current => [...current, { ...formItem, id: uuid, type: type, layer: layers.find(l => l.name == addItemPopupType), user_created: user }]) - } - - const deleteItem = async (item) => { - setLoading(true); - let success = false; - try { - await api?.deleteItem!(item.id) - success = true; - } catch (error) { - toast.error(error.toString()); - } - if (success) { - toast.success("Item deleted"); - } - setLoading(false); - setItems(items.filter(i=>i.id !=item.id)) - console.log("chaka"); - } - - - - return ( - -
-
- {breadcrumbs && -
-
    - {breadcrumbs.map((b, i) =>
  • {b.name}
  • )} -
-
} - {/** -
- { setSearch(val) }}> - { }} placeholder="Type" containerStyle=' hidden md:grid' defaultValue='PLACEHOLDER' options={[{ name: "local", value: "local" }, { name: "project", value: "project" }]} /> -
-
- - */} - - - -
- { - items?.map((i, k) => { - return ( -
navigate(url + getValue(i, parameterField))}> - navigate("/edit-item/"+i.id)} deleteCallback={()=>deleteItem(i)}> -
- -
-
- - ) - - }) - } - {addItemPopupType == "project" ? - -
submitNewItem(e, addItemPopupType)} > - -
- - - -
- -
-
-
: <> - } -
-
- { setAddItemPopupType("project"); scroll(); }} color={'#777'} collection='items' /> - {children} -
- - - ) -} diff --git a/src/Components/Templates/OverlayItemsIndexPage.tsx b/src/Components/Templates/OverlayItemsIndexPage.tsx index 2ce1ce38..12ae18b7 100644 --- a/src/Components/Templates/OverlayItemsIndexPage.tsx +++ b/src/Components/Templates/OverlayItemsIndexPage.tsx @@ -3,7 +3,7 @@ import { Link, useNavigate } from 'react-router-dom'; import { Item, ItemsApi, LayerProps } from '../../types'; import { getValue } from '../../Utils/GetValue'; import { PopupStartEndInput, StartEndView, TextView } from '../Map'; -import { PlusButton } from '../Profile/PlusButton'; +import { PlusButton } from '../Profile/Subcomponents/PlusButton'; import { TextInput, TextAreaInput } from '../Input'; import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags'; import { toast } from 'react-toastify'; diff --git a/src/Components/Templates/index.tsx b/src/Components/Templates/index.tsx index 97537a89..0538960d 100644 --- a/src/Components/Templates/index.tsx +++ b/src/Components/Templates/index.tsx @@ -3,6 +3,5 @@ export {TitleCard} from './TitleCard' export {MapOverlayPage} from './MapOverlayPage' export {CircleLayout} from './CircleLayout' export {MoonCalendar} from './MoonCalendar' -export {ItemsIndexPage} from "./ItemsIndexPage" export {ItemViewPage} from "./ItemViewPage" export {OverlayItemsIndexPage} from "./OverlayItemsIndexPage" \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index d66fb17e..6f376d56 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,9 @@ export { UtopiaMap, Layer, Tags, Permissions, ItemForm, ItemView, PopupTextAreaInput, PopupStartEndInput, PopupTextInput, PopupButton, TextView, StartEndView, PopupCheckboxInput } from './Components/Map'; export {AppShell, Content, SideBar, Sitemap } from "./Components/AppShell" export {AuthProvider, useAuth, LoginPage, SignupPage, RequestPasswordPage, SetNewPasswordPage} from "./Components/Auth" -export {UserSettings, ProfileSettings, OverlayProfile, OverlayProfileSettings, OverlayUserSettings, OverlayItemProfile, OverlayItemProfileSettings} from './Components/Profile' +export {OverlayUserSettings, ProfileView, ProfileForm} from './Components/Profile' export {Quests, Modal} from './Components/Gaming' -export {TitleCard, CardPage, MapOverlayPage, OverlayItemsIndexPage, CircleLayout, MoonCalendar, ItemsIndexPage, ItemViewPage} from './Components/Templates' +export {TitleCard, CardPage, MapOverlayPage, OverlayItemsIndexPage, CircleLayout, MoonCalendar, ItemViewPage} from './Components/Templates' export {TextInput, TextAreaInput, SelectBox} from './Components/Input' import "./index.css"