mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
custom popups are basicly working 🍄
This commit is contained in:
parent
d6e780436f
commit
6bd062c1b3
@ -1,7 +1,7 @@
|
||||
import {useState, useRef} from 'react'
|
||||
import {Link} from 'react-router-dom'
|
||||
import ErrorText from '../Typography/ErrorText'
|
||||
import InputText from '../Input/InputText'
|
||||
import {TextInput} from '../Input/TextInput'
|
||||
import * as React from 'react'
|
||||
|
||||
export function LoginPage(){
|
||||
@ -44,9 +44,9 @@ export function LoginPage(){
|
||||
|
||||
<div className="tw-mb-4">
|
||||
|
||||
<InputText type="email" defaultValue={loginObj.emailId} containerStyle="tw-mt-4" labelTitle="E-Mail" updateFormValue={(v) => updateFormValue(v)}/>
|
||||
<TextInput type="email" defaultValue={loginObj.emailId} containerStyle="tw-mt-4" labelTitle="E-Mail" updateFormValue={(v) => updateFormValue(v)}/>
|
||||
|
||||
<InputText defaultValue={loginObj.password} type="password" containerStyle="tw-mt-4" labelTitle="Password" updateFormValue={(v) => updateFormValue(v)}/>
|
||||
<TextInput defaultValue={loginObj.password} type="password" containerStyle="tw-mt-4" labelTitle="Password" updateFormValue={(v) => updateFormValue(v)}/>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useState, useRef } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import ErrorText from '../Typography/ErrorText'
|
||||
import InputText from '../Input/InputText'
|
||||
import {TextInput} from '../Input/TextInput'
|
||||
import * as React from 'react'
|
||||
|
||||
export function SignupPage() {
|
||||
@ -45,13 +45,9 @@ export function SignupPage() {
|
||||
<form onSubmit={(e) => submitForm(e)}>
|
||||
|
||||
<div className="mb-4">
|
||||
|
||||
<InputText defaultValue={registerObj.name} containerStyle="tw-mt-4" labelTitle="Name" updateFormValue={updateFormValue} />
|
||||
|
||||
<InputText defaultValue={registerObj.emailId} containerStyle="tw-mt-4" labelTitle="E-Mail" updateFormValue={updateFormValue} />
|
||||
|
||||
<InputText defaultValue={registerObj.password} type="password" containerStyle="tw-mt-4" labelTitle="Password" updateFormValue={updateFormValue} />
|
||||
|
||||
<TextInput defaultValue={registerObj.name} containerStyle="tw-mt-4" labelTitle="Name" updateFormValue={updateFormValue} />
|
||||
<TextInput defaultValue={registerObj.emailId} containerStyle="tw-mt-4" labelTitle="E-Mail" updateFormValue={updateFormValue} />
|
||||
<TextInput defaultValue={registerObj.password} type="password" containerStyle="tw-mt-4" labelTitle="Password" updateFormValue={updateFormValue} />
|
||||
</div>
|
||||
|
||||
<ErrorText styleClass="tw-mt-8">{errorMessage}</ErrorText>
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import * as React from "react"
|
||||
|
||||
type InputTextProps = {
|
||||
labelTitle?: string;
|
||||
labelStyle?: string;
|
||||
type?: string;
|
||||
dataField?: string;
|
||||
containerStyle?: string;
|
||||
defaultValue: string;
|
||||
placeholder?: string;
|
||||
updateFormValue?: (value: string ) => void;
|
||||
}
|
||||
|
||||
|
||||
function InputText({labelTitle, labelStyle, type, dataField, containerStyle, defaultValue, placeholder, updateFormValue} : InputTextProps){
|
||||
|
||||
const [value, setValue] = useState<string>(defaultValue)
|
||||
|
||||
useEffect(() => {
|
||||
setValue(defaultValue)
|
||||
}, [defaultValue])
|
||||
|
||||
|
||||
const updateInputValue = (val : string) => {
|
||||
setValue(val)
|
||||
if(updateFormValue)
|
||||
updateFormValue(val)
|
||||
|
||||
}
|
||||
|
||||
return(
|
||||
<div className={`tw-form-control tw-w-full ${containerStyle}`}>
|
||||
{labelTitle ? <label className="tw-label">
|
||||
<span className={"tw-label-text tw-text-base-content " + labelStyle}>{labelTitle}</span>
|
||||
</label>
|
||||
: " "}
|
||||
<input type={type || "text"} name={dataField} value={value} placeholder={placeholder || ""} onChange={(e) => updateInputValue(e.target.value)}className="tw-input tw-input-bordered tw-w-full " />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default InputText
|
||||
@ -15,30 +15,20 @@ type TextAreaProps = {
|
||||
|
||||
|
||||
|
||||
function TextAreaInput({ labelTitle, dataField, labelStyle, containerStyle, inputStyle, defaultValue, placeholder, updateFormValue }: TextAreaProps) {
|
||||
|
||||
const [value, setValue] = useState<string>(defaultValue)
|
||||
|
||||
useEffect(() => {
|
||||
setValue(defaultValue)
|
||||
}, [defaultValue])
|
||||
export function TextAreaInput({ labelTitle, dataField, labelStyle, containerStyle, inputStyle, defaultValue, placeholder, updateFormValue }: TextAreaProps) {
|
||||
|
||||
|
||||
|
||||
|
||||
const updateInputValue = (val: string) => {
|
||||
setValue(val)
|
||||
if (updateFormValue)
|
||||
updateFormValue(val)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`tw-form-control tw-w-full ${containerStyle ? containerStyle : ""}`}>
|
||||
{labelTitle ? <label className="tw-label">
|
||||
<span className={"tw-label-text tw-text-base-content " + labelStyle}>{labelTitle}</span>
|
||||
</label> : ""}
|
||||
<textarea value={value} name={dataField} className={`tw-textarea tw-textarea-bordered tw-w-full tw-leading-5 ${inputStyle ? inputStyle : ""}`} placeholder={placeholder || ""} onChange={(e) => updateInputValue(e.target.value)}></textarea>
|
||||
<textarea defaultValue={defaultValue} name={dataField} className={`tw-textarea tw-textarea-bordered tw-w-full tw-leading-5 ${inputStyle ? inputStyle : ""}`} placeholder={placeholder || ""} onChange={(e) => updateFormValue&& updateFormValue(e.target.value)}></textarea>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default TextAreaInput
|
||||
29
src/Components/Input/TextInput.tsx
Normal file
29
src/Components/Input/TextInput.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { useEffect, useState } from "react"
|
||||
import * as React from "react"
|
||||
|
||||
type InputTextProps = {
|
||||
labelTitle?: string;
|
||||
labelStyle?: string;
|
||||
type?: string;
|
||||
dataField?: string;
|
||||
containerStyle?: string;
|
||||
defaultValue?: string;
|
||||
placeholder?: string;
|
||||
updateFormValue?: (value: string ) => void;
|
||||
}
|
||||
|
||||
|
||||
export function TextInput({labelTitle, labelStyle, type, dataField, containerStyle, defaultValue, placeholder, updateFormValue} : InputTextProps){
|
||||
|
||||
return(
|
||||
<div className={`tw-form-control tw-w-full ${containerStyle}`}>
|
||||
{labelTitle ? <label className="tw-label">
|
||||
<span className={"tw-label-text tw-text-base-content " + labelStyle}>{labelTitle}</span>
|
||||
</label>
|
||||
: " "}
|
||||
<input type={type || "text"} name={dataField} defaultValue={defaultValue} placeholder={placeholder || ""} onChange={(e) => updateFormValue&& updateFormValue(e.target.value)}className="tw-input tw-input-bordered tw-w-full " />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
2
src/Components/Input/index.tsx
Normal file
2
src/Components/Input/index.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
export {TextAreaInput} from "./TextAreaInput"
|
||||
export {TextInput} from "./TextInput"
|
||||
7
src/Components/Map/ItemForm.tsx
Normal file
7
src/Components/Map/ItemForm.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import * as React from 'react'
|
||||
|
||||
export const ItemForm = ({ children }:{children?: React.ReactNode}) => {
|
||||
return (
|
||||
<div>{children}</div>
|
||||
)
|
||||
}
|
||||
7
src/Components/Map/ItemView.tsx
Normal file
7
src/Components/Map/ItemView.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import * as React from 'react'
|
||||
|
||||
export const ItemView = ({ children }:{children?: React.ReactNode}) => {
|
||||
return (
|
||||
<div>{children}</div>
|
||||
)
|
||||
}
|
||||
@ -7,7 +7,7 @@ import { useTags } from './hooks/useTags'
|
||||
import { useAddItem, useItems, useResetItems } from './hooks/useItems'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useAddLayer } from './hooks/useLayers'
|
||||
import ItemFormPopup, { ItemFormPopupProps } from './Subcomponents/ItemFormPopup'
|
||||
import { ItemFormPopupProps, ItemFormPopup } from './Subcomponents/ItemFormPopup'
|
||||
|
||||
export const Layer = (props: LayerProps) => {
|
||||
|
||||
@ -86,14 +86,38 @@ export const Layer = (props: LayerProps) => {
|
||||
}
|
||||
return (
|
||||
<Marker icon={MarkerIconFactory(props.markerShape, color1, color2, props.markerIcon)} key={place.id} position={[place.position.coordinates[1], place.position.coordinates[0]]}>
|
||||
|
||||
|
||||
|
||||
{
|
||||
(props.children && React.Children.toArray(props.children).some(e => React.isValidElement(e) && typeof e.type !== "string" && e.type.name === "ItemForm") ?
|
||||
React.Children.toArray(props.children).map((child) =>
|
||||
React.isValidElement(child) && typeof child.type !== "string" && child.type.name === "ItemView" ?
|
||||
<ItemViewPopup key={place.id} item={place} setItemFormPopup={props.setItemFormPopup} >{child}</ItemViewPopup>
|
||||
: ""
|
||||
)
|
||||
:
|
||||
<>
|
||||
<ItemViewPopup item={place} setItemFormPopup={props.setItemFormPopup} />
|
||||
</>)
|
||||
}
|
||||
|
||||
</Marker>
|
||||
);
|
||||
})
|
||||
}
|
||||
{props.children}
|
||||
{props.itemFormPopup && props.itemFormPopup.layer.name == props.name &&
|
||||
<ItemFormPopup position={props.itemFormPopup.position} layer={props.itemFormPopup.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup.item} api={props.api} />
|
||||
{props.itemFormPopup && props.itemFormPopup.layer!.name == props.name &&
|
||||
(props.children && React.Children.toArray(props.children).some(e => React.isValidElement(e) && typeof e.type !== "string" && e.type.name === "ItemForm") ?
|
||||
React.Children.toArray(props.children).map((child) =>
|
||||
React.isValidElement(child) && typeof child.type !== "string" && child.type.name === "ItemForm" ?
|
||||
<ItemFormPopup key={props.setItemFormPopup?.name} position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} api={props.api} >{child}</ItemFormPopup>
|
||||
: ""
|
||||
)
|
||||
:
|
||||
<>
|
||||
<ItemFormPopup position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} api={props.api} />
|
||||
</>)
|
||||
}
|
||||
</>
|
||||
)
|
||||
|
||||
@ -1,21 +1,25 @@
|
||||
import * as React from 'react'
|
||||
import { LatLng } from 'leaflet'
|
||||
import { Popup as LeafletPopup, useMap } from 'react-leaflet'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useAddItem, useUpdateItem } from '../hooks/useItems'
|
||||
import { Geometry, LayerProps, Item, ItemsApi } from '../../../types'
|
||||
import TextAreaInput from '../../Input/TextAreaInput'
|
||||
import InputText from '../../Input/InputText'
|
||||
import {TextAreaInput} from '../../Input/TextAreaInput'
|
||||
import {TextInput} from '../../Input/TextInput'
|
||||
|
||||
export interface ItemFormPopupProps {
|
||||
position: LatLng,
|
||||
layer: LayerProps,
|
||||
item?: Item,
|
||||
api?: ItemsApi<any>,
|
||||
children?: React.ReactNode,
|
||||
setItemFormPopup: React.Dispatch<React.SetStateAction<any>>
|
||||
}
|
||||
|
||||
export default function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
export function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
|
||||
|
||||
const [spinner, setSpinner] = useState(false);
|
||||
|
||||
@ -25,9 +29,8 @@ export default function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
|
||||
const handleSubmit = async (evt: any) => {
|
||||
const formItem: Item = {} as Item;
|
||||
Array.from(evt.target).forEach((input: HTMLFormElement) => {
|
||||
Array.from(evt.target).forEach((input: HTMLInputElement) => {
|
||||
if (input.name) {
|
||||
console.log(input.name + ": " + input.value);
|
||||
formItem[input.name] = input.value;
|
||||
}
|
||||
});
|
||||
@ -57,17 +60,41 @@ export default function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
}
|
||||
|
||||
|
||||
const resetPopup = () => {
|
||||
if (formRef.current) {
|
||||
formRef.current.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
resetPopup();
|
||||
}, [props.position])
|
||||
|
||||
return (
|
||||
<LeafletPopup minWidth={275} maxWidth={275} autoPanPadding={[20, 5]}
|
||||
eventHandlers={{
|
||||
// remove: resetPopup
|
||||
remove: () => {
|
||||
setTimeout(function() {
|
||||
resetPopup()
|
||||
|
||||
}, 100);
|
||||
}
|
||||
}}
|
||||
position={props.position}>
|
||||
<form onSubmit={e => handleSubmit(e)}>
|
||||
<form ref={formRef} onReset={resetPopup} onSubmit={e => handleSubmit(e)}>
|
||||
<div className='tw-flex tw-justify-center'><b className="tw-text-xl tw-font-bold">New {props.layer.name}</b></div>
|
||||
<InputText type="text" placeholder="Name" dataField="name" defaultValue={props.item? props.item.name : ""} />
|
||||
{props.children ? props.children :
|
||||
<>
|
||||
<TextInput type="text" placeholder="Name" dataField="name" defaultValue={props.item ? props.item.name : ""} />
|
||||
<TextAreaInput placeholder="Text" dataField="text" defaultValue={props.item ? props.item.text : ""} inputStyle='tw-h-40 tw-mt-5' />
|
||||
<div className='tw-flex tw-justify-center'><button className={spinner ? 'tw-btn tw-loading tw-mt-5 tw-place-self-center' : 'tw-btn tw-mt-5 tw-place-self-center'}>Save</button></div>
|
||||
</>
|
||||
}
|
||||
|
||||
<div className='tw-flex tw-justify-center'>
|
||||
<button className={spinner ? 'tw-btn tw-btn-disabled tw-mt-5 tw-place-self-center' : 'tw-btn tw-mt-5 tw-place-self-center'} type='submit'>{spinner ? <span className="tw-loading tw-loading-spinner"></span> : 'Save'}</button>
|
||||
</div>
|
||||
</form>
|
||||
</LeafletPopup>
|
||||
)
|
||||
|
||||
@ -8,6 +8,7 @@ import { TextView } from './TextView'
|
||||
|
||||
export interface ItemViewPopupProps {
|
||||
item: Item,
|
||||
children?: React.ReactNode;
|
||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>
|
||||
}
|
||||
|
||||
@ -20,12 +21,13 @@ export const ItemViewPopup = (props: ItemViewPopupProps) => {
|
||||
<LeafletPopup maxHeight={377} minWidth={275} maxWidth={275} autoPanPadding={[20, 5]}>
|
||||
<div>
|
||||
<HeaderView item={props.item} setItemFormPopup={props.setItemFormPopup} />
|
||||
{props.children ? props.children :
|
||||
<div className='tw-overflow-y-auto tw-max-h-72'>
|
||||
{item.start && item.end &&
|
||||
<StartEndView item={props.item} />
|
||||
}
|
||||
<StartEndView item={props.item} />}
|
||||
<TextView item={props.item} />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</LeafletPopup>
|
||||
)
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
export { UtopiaMap } from './UtopiaMap'
|
||||
export { UtopiaMap } from './UtopiaMap';
|
||||
export { Layer } from './Layer';
|
||||
export { Tags } from "./Tags";
|
||||
export {ItemViewPopup} from './Subcomponents/ItemViewPopup';
|
||||
export {ItemForm} from './ItemForm';
|
||||
export {ItemView} from './ItemView';
|
||||
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import {TitleCard} from '../Templates/TitleCard'
|
||||
import InputText from '../Input/InputText'
|
||||
import TextAreaInput from '../Input/TextAreaInput'
|
||||
import {TextInput} from '../Input/TextInput'
|
||||
import {TextAreaInput} from '../Input/TextAreaInput'
|
||||
import { toast } from 'react-toastify';
|
||||
import {useNavigate} from 'react-router-dom'
|
||||
import * as React from 'react'
|
||||
@ -62,7 +62,7 @@ export function Settings({useAuth}) {
|
||||
|
||||
|
||||
<div className="tw-grid tw-grid-cols-1 tw-md:grid-cols-2 tw-gap-6">
|
||||
<InputText placeholder="Name" defaultValue={user?.first_name ? user.first_name : ""} updateFormValue={(v) => setName(v)} />
|
||||
<TextInput placeholder="Name" defaultValue={user?.first_name ? user.first_name : ""} updateFormValue={(v) => setName(v)} />
|
||||
</div>
|
||||
<div className="tw-grid tw-grid-cols-1 tw-md:grid-cols-1 tw-gap-6 tw-pt-6 tw-pb-6">
|
||||
<TextAreaInput placeholder="About me, Contact, #Tags, ..." defaultValue={user?.description ? user.description : ""} updateFormValue={(v) => setText(v)} inputStyle='tw-h-64'/>
|
||||
@ -71,8 +71,8 @@ export function Settings({useAuth}) {
|
||||
|
||||
|
||||
<div className="tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6">
|
||||
<InputText type='email' placeholder="E-Mail" defaultValue={user?.email ? user.email : ""} updateFormValue={(v) => setEmail(v)} />
|
||||
<InputText type='password' placeholder="new Password" defaultValue={user?.password ? user.password : ""} updateFormValue={(v) => {
|
||||
<TextInput type='email' placeholder="E-Mail" defaultValue={user?.email ? user.email : ""} updateFormValue={(v) => setEmail(v)} />
|
||||
<TextInput type='password' placeholder="new Password" defaultValue={user?.password ? user.password : ""} updateFormValue={(v) => {
|
||||
setPassword(v);
|
||||
setPasswordChanged(true);
|
||||
}} />
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
export { UtopiaMap, Layer, Tags } from './Components/Map/index';
|
||||
export { UtopiaMap, Layer, Tags, ItemViewPopup, ItemForm, ItemView } from './Components/Map/index';
|
||||
export {AppShell, Content, SideBar} from "./Components/AppShell"
|
||||
export {AuthProvider, useAuth, LoginPage, SignupPage} from "./Components/Auth"
|
||||
export {Settings} from './Components/Profile'
|
||||
export {Quests, Modal} from './Components/Gaming'
|
||||
export {TitleCard, CardPage} from './Components/Templates'
|
||||
export {TextInput, TextAreaInput} from './Components/Input'
|
||||
|
||||
import "./index.css"
|
||||
|
||||
|
||||
10
src/types.ts
10
src/types.ts
@ -12,7 +12,7 @@ export interface UtopiaMapProps {
|
||||
|
||||
export interface LayerProps {
|
||||
data?: Item[],
|
||||
children?: React.ReactNode
|
||||
children?: React.ReactNode,
|
||||
name: string,
|
||||
menuIcon: string,
|
||||
menuColor: string,
|
||||
@ -28,16 +28,16 @@ export interface LayerProps {
|
||||
|
||||
export class Item {
|
||||
id: string | number;
|
||||
date_created?: string;
|
||||
date_updated?: string | null;
|
||||
name: string;
|
||||
text: string;
|
||||
position: Geometry;
|
||||
[key: string]: any;
|
||||
date_created?: string;
|
||||
date_updated?: string | null;
|
||||
start?: string;
|
||||
end?: string;
|
||||
tags?: number[];
|
||||
api?: ItemsApi<any>
|
||||
api?: ItemsApi<any>;
|
||||
[key: string]: any;
|
||||
constructor(id:string|number,name:string,text:string,position:Geometry, layer?: LayerProps, api?: ItemsApi<any>){
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user