mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
split Settings in UserSettings and ProfileSettings
This commit is contained in:
parent
74a8892b4e
commit
0267a2f91f
@ -90,7 +90,7 @@ export default function NavBar({ appName, nameWidth = 200}: { appName: string, n
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="tw-navbar tw-bg-base-100 tw-z-1000 tw-shadow-xl tw-relative">
|
<div className="tw-navbar tw-bg-base-100 tw-z-[10000] tw-shadow-xl tw-relative">
|
||||||
<button className="tw-btn tw-btn-square tw-btn-ghost"
|
<button className="tw-btn tw-btn-square tw-btn-ghost"
|
||||||
data-te-sidenav-toggle-ref
|
data-te-sidenav-toggle-ref
|
||||||
data-te-target="#sidenav"
|
data-te-target="#sidenav"
|
||||||
@ -99,7 +99,7 @@ export default function NavBar({ appName, nameWidth = 200}: { appName: string, n
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" className="tw-inline-block tw-w-5 tw-h-5 tw-stroke-current"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" className="tw-inline-block tw-w-5 tw-h-5 tw-stroke-current"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
|
||||||
</button>
|
</button>
|
||||||
<div className="tw-flex-1 tw-mr-2">
|
<div className="tw-flex-1 tw-mr-2">
|
||||||
<div className={`tw-flex-1 tw-truncate tw-grid tw-grid-flow-col`} style={{maxWidth: nameWidth}}>
|
<div className={`tw-flex-1 tw-truncate tw-grid tw-grid-flow-col`} style={{maxWidth: nameWidth}}>
|
||||||
<Link className="tw-btn tw-btn-ghost tw-px-2 tw-normal-case tw-text-xl tw-flex-1 tw-truncate" to={"/"}><h1 className="tw-truncate">{appName}</h1></Link>
|
<Link className="tw-btn tw-btn-ghost tw-px-2 tw-normal-case tw-text-xl tw-flex-1 tw-truncate" to={"/"}><h1 className="tw-truncate">{appName}</h1></Link>
|
||||||
<button className="tw-btn tw-px-2 tw-btn-ghost" onClick={() => window.my_modal_3.showModal()}><QuestionMarkIcon className="tw-h-5 tw-w-5" /></button>
|
<button className="tw-btn tw-px-2 tw-btn-ghost" onClick={() => window.my_modal_3.showModal()}><QuestionMarkIcon className="tw-h-5 tw-w-5" /></button>
|
||||||
|
|
||||||
@ -123,6 +123,7 @@ export default function NavBar({ appName, nameWidth = 200}: { appName: string, n
|
|||||||
</svg>
|
</svg>
|
||||||
</label>
|
</label>
|
||||||
<ul tabIndex={0} className="tw-menu tw-menu-compact tw-dropdown-content tw-mt-3 tw-p-2 tw-shadow tw-bg-base-100 tw-rounded-box tw-w-52 !tw-z-[10000]">
|
<ul tabIndex={0} className="tw-menu tw-menu-compact tw-dropdown-content tw-mt-3 tw-p-2 tw-shadow tw-bg-base-100 tw-rounded-box tw-w-52 !tw-z-[10000]">
|
||||||
|
<li><Link to={"/profile"}>Profile</Link></li>
|
||||||
<li><Link to={"/settings"}>Settings</Link></li>
|
<li><Link to={"/settings"}>Settings</Link></li>
|
||||||
<li><a onClick={() => { onLogout() }}>Logout</a></li>
|
<li><a onClick={() => { onLogout() }}>Logout</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -14,20 +14,16 @@ import DialogModal from '../Templates/DialogModal';
|
|||||||
import { useAssetApi } from '../AppShell/hooks/useAssets';
|
import { useAssetApi } from '../AppShell/hooks/useAssets';
|
||||||
import { ColorPicker } from './ColorPicker';
|
import { ColorPicker } from './ColorPicker';
|
||||||
|
|
||||||
export function Settings() {
|
export function ProfileSettings() {
|
||||||
const { user, updateUser, loading, token } = useAuth();
|
const { user, updateUser, loading, token } = useAuth();
|
||||||
|
|
||||||
const [id, setId] = useState<string>("");
|
const [id, setId] = useState<string>("");
|
||||||
const [name, setName] = useState<string>("");
|
const [name, setName] = useState<string>("");
|
||||||
const [text, setText] = useState<string>("");
|
const [text, setText] = useState<string>("");
|
||||||
const [email, setEmail] = useState<string>("");
|
|
||||||
const [password, setPassword] = useState<string>("");
|
|
||||||
const [avatar, setAvatar] = useState<string>("");
|
const [avatar, setAvatar] = useState<string>("");
|
||||||
const [color, setColor] = useState<string>("");
|
const [color, setColor] = useState<string>("");
|
||||||
|
|
||||||
|
|
||||||
const [passwordChanged, setPasswordChanged] = useState<boolean>(false);
|
|
||||||
|
|
||||||
const [crop, setCrop] = useState<Crop>();
|
const [crop, setCrop] = useState<Crop>();
|
||||||
const [image, setImage] = useState<string>("");
|
const [image, setImage] = useState<string>("");
|
||||||
const [cropModalOpen, setCropModalOpen] = useState<boolean>(false);
|
const [cropModalOpen, setCropModalOpen] = useState<boolean>(false);
|
||||||
@ -40,8 +36,6 @@ export function Settings() {
|
|||||||
setId(user?.id ? user.id : "");
|
setId(user?.id ? user.id : "");
|
||||||
setName(user?.first_name ? user.first_name : "");
|
setName(user?.first_name ? user.first_name : "");
|
||||||
setText(user?.description ? user.description : "");
|
setText(user?.description ? user.description : "");
|
||||||
setEmail(user?.email ? user.email : "");
|
|
||||||
setPassword(user?.password ? user.password : "");
|
|
||||||
setAvatar(user?.avatar ? user?.avatar : ""),
|
setAvatar(user?.avatar ? user?.avatar : ""),
|
||||||
setColor(user?.color? user.color : "#aabbcc")
|
setColor(user?.color? user.color : "#aabbcc")
|
||||||
}, [user])
|
}, [user])
|
||||||
@ -144,7 +138,7 @@ export function Settings() {
|
|||||||
const onUpdateUser = () => {
|
const onUpdateUser = () => {
|
||||||
let changedUser = {} as UserItem;
|
let changedUser = {} as UserItem;
|
||||||
|
|
||||||
changedUser = { id: id, first_name: name, description: text, email: email, color: color, ...passwordChanged && { password: password }, ...avatar.length > 10 && { avatar: avatar } };
|
changedUser = { id: id, first_name: name, description: text, color: color, ...avatar.length > 10 && { avatar: avatar } };
|
||||||
|
|
||||||
|
|
||||||
toast.promise(
|
toast.promise(
|
||||||
@ -167,7 +161,7 @@ export function Settings() {
|
|||||||
<>
|
<>
|
||||||
<main className="tw-flex-1 tw-overflow-y-auto tw-overflow-x-hidden tw-pt-8 tw-px-6 tw-bg-base-200 tw-min-w-80 tw-flex tw-justify-center" >
|
<main className="tw-flex-1 tw-overflow-y-auto tw-overflow-x-hidden tw-pt-8 tw-px-6 tw-bg-base-200 tw-min-w-80 tw-flex tw-justify-center" >
|
||||||
<div className='tw-w-full xl:tw-max-w-6xl'>
|
<div className='tw-w-full xl:tw-max-w-6xl'>
|
||||||
<TitleCard title="Profile Settings" topMargin="tw-mt-2" className='tw-mb-6'>
|
<TitleCard title="Profile" topMargin="tw-mt-2" className='tw-mb-6'>
|
||||||
<div className="tw-flex">
|
<div className="tw-flex">
|
||||||
{!cropping ?
|
{!cropping ?
|
||||||
<label className="custom-file-upload">
|
<label className="custom-file-upload">
|
||||||
@ -203,17 +197,6 @@ export function Settings() {
|
|||||||
<div className="tw-grid tw-grid-cols-1 tw-md:grid-cols-1 tw-gap-6 tw-pt-6 tw-pb-6">
|
<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' />
|
<TextAreaInput placeholder="About me, Contact, #Tags, ..." defaultValue={user?.description ? user.description : ""} updateFormValue={(v) => setText(v)} inputStyle='tw-h-64' />
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-divider" ></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div className="tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6">
|
|
||||||
<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);
|
|
||||||
}} />
|
|
||||||
{/* <ToogleInput updateType="syncData" labelTitle="Sync Data" defaultValue={true} updateFormValue={updateFormValue}/> */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="tw-mt-8"><button className={loading ? " tw-loading tw-btn-disabled tw-btn tw-btn-primary tw-float-right" : "tw-btn tw-btn-primary tw-float-right"} onClick={() => onUpdateUser()}>Update</button></div>
|
<div className="tw-mt-8"><button className={loading ? " tw-loading tw-btn-disabled tw-btn tw-btn-primary tw-float-right" : "tw-btn tw-btn-primary tw-float-right"} onClick={() => onUpdateUser()}>Update</button></div>
|
||||||
|
|
||||||
88
src/Components/Profile/UserSettings.tsx
Normal file
88
src/Components/Profile/UserSettings.tsx
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
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<string>("");
|
||||||
|
const [email, setEmail] = useState<string>("");
|
||||||
|
const [password, setPassword] = useState<string>("");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const [passwordChanged, setPasswordChanged] = useState<boolean>(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 (
|
||||||
|
<>
|
||||||
|
<main className="tw-flex-1 tw-overflow-y-auto tw-overflow-x-hidden tw-pt-8 tw-px-6 tw-bg-base-200 tw-min-w-80 tw-flex tw-justify-center" >
|
||||||
|
<div className='tw-w-full xl:tw-max-w-6xl'>
|
||||||
|
<TitleCard title="Settings" topMargin="tw-mt-2" className='tw-mb-6'>
|
||||||
|
|
||||||
|
|
||||||
|
<div className="tw-grid tw-grid-cols-1 md:tw-grid-cols-2 tw-gap-6">
|
||||||
|
<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);
|
||||||
|
}} />
|
||||||
|
{/* <ToogleInput updateType="syncData" labelTitle="Sync Data" defaultValue={true} updateFormValue={updateFormValue}/> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="tw-mt-8"><button className={loading ? " tw-loading tw-btn-disabled tw-btn tw-btn-primary tw-float-right" : "tw-btn tw-btn-primary tw-float-right"} onClick={() => onUpdateUser()}>Update</button></div>
|
||||||
|
|
||||||
|
</TitleCard>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1 +1,2 @@
|
|||||||
export {Settings} from './Settings'
|
export {UserSettings} from './UserSettings'
|
||||||
|
export {ProfileSettings} from './ProfileSettings'
|
||||||
@ -1,7 +1,7 @@
|
|||||||
export { UtopiaMap, Layer, Tags, Permissions, ItemForm, ItemView, PopupTextAreaInput, PopupStartEndInput, PopupTextInput, TextView, StartEndView } from './Components/Map';
|
export { UtopiaMap, Layer, Tags, Permissions, ItemForm, ItemView, PopupTextAreaInput, PopupStartEndInput, PopupTextInput, TextView, StartEndView } from './Components/Map';
|
||||||
export {AppShell, Content, SideBar} from "./Components/AppShell"
|
export {AppShell, Content, SideBar} from "./Components/AppShell"
|
||||||
export {AuthProvider, useAuth, LoginPage, SignupPage} from "./Components/Auth"
|
export {AuthProvider, useAuth, LoginPage, SignupPage} from "./Components/Auth"
|
||||||
export {Settings} from './Components/Profile'
|
export {UserSettings, ProfileSettings} from './Components/Profile'
|
||||||
export {Quests, Modal} from './Components/Gaming'
|
export {Quests, Modal} from './Components/Gaming'
|
||||||
export {TitleCard, CardPage} from './Components/Templates'
|
export {TitleCard, CardPage} from './Components/Templates'
|
||||||
export {TextInput, TextAreaInput, SelectBox} from './Components/Input'
|
export {TextInput, TextAreaInput, SelectBox} from './Components/Input'
|
||||||
|
|||||||
17
src/types.ts
17
src/types.ts
@ -90,13 +90,20 @@ export interface UserApi {
|
|||||||
|
|
||||||
export type UserItem = {
|
export type UserItem = {
|
||||||
id?: string;
|
id?: string;
|
||||||
avatar?: string;
|
|
||||||
role?: string;
|
role?: string;
|
||||||
color?: string;
|
email?: string;
|
||||||
first_name: string;
|
|
||||||
description: string;
|
|
||||||
email: string;
|
|
||||||
password?: string;
|
password?: string;
|
||||||
|
profile?: Profile;
|
||||||
|
[key: string]: any;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Profile = {
|
||||||
|
id?: string;
|
||||||
|
avatar?: string;
|
||||||
|
color?: string;
|
||||||
|
name: string;
|
||||||
|
text: string;
|
||||||
geoposition?: Geometry
|
geoposition?: Geometry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user