mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
added page template and basic registration
This commit is contained in:
parent
b7d46473ce
commit
3c276c8fdf
8
package-lock.json
generated
8
package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"leaflet": "^1.9.3",
|
||||
"leaflet": "^1.9.4",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-leaflet-cluster": "^2.1.0",
|
||||
"react-router-dom": "^6.11.2",
|
||||
@ -2523,9 +2523,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/leaflet": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz",
|
||||
"integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ=="
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
|
||||
},
|
||||
"node_modules/leaflet.markercluster": {
|
||||
"version": "1.5.3",
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"leaflet": "^1.9.3",
|
||||
"leaflet": "^1.9.4",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-leaflet-cluster": "^2.1.0",
|
||||
"react-router-dom": "^6.11.2",
|
||||
|
||||
@ -3,7 +3,7 @@ import NavBar from './NavBar'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import { ToastContainer } from 'react-toastify'
|
||||
|
||||
export function AppShell({ name, useAuth, children }) {
|
||||
export function AppShell({ appName, useAuth, children }) {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<ToastContainer position="top-right"
|
||||
@ -16,7 +16,7 @@ export function AppShell({ name, useAuth, children }) {
|
||||
draggable
|
||||
pauseOnHover
|
||||
theme="light" />
|
||||
<NavBar name={name} useAuth={useAuth}></NavBar>
|
||||
<NavBar appName={appName} useAuth={useAuth}></NavBar>
|
||||
<div id="app-content" className="tw-flex tw-!pl-[77px]">
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@ -5,12 +5,28 @@ import { toast } from "react-toastify";
|
||||
import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
|
||||
import * as React from "react";
|
||||
|
||||
export default function NavBar({name, useAuth} : {name: string, useAuth : any}) {
|
||||
export default function NavBar({appName, useAuth} : {appName: string, useAuth : any}) {
|
||||
|
||||
const [email, setEmail] = useState<string>("");
|
||||
const [userName, setUserName] = useState<string>("");
|
||||
const [password, setPassword] = useState<string>("");
|
||||
|
||||
const { isAuthenticated, user, login, loading, logout, token } = useAuth();
|
||||
const { isAuthenticated, user, login, register, loading, logout, token } = useAuth();
|
||||
|
||||
const onRegister = () => {
|
||||
toast.promise(
|
||||
register({ email: email, password: password}, userName),
|
||||
{
|
||||
success: {
|
||||
render({data}){
|
||||
return `Hi ${data?.first_name}`
|
||||
},
|
||||
// other options
|
||||
icon: "✌️",
|
||||
},
|
||||
error: 'Error'
|
||||
});
|
||||
}
|
||||
|
||||
const onLogin = () => {
|
||||
toast.promise(
|
||||
@ -39,7 +55,7 @@ export default function NavBar({name, useAuth} : {name: string, useAuth : any})
|
||||
</button>
|
||||
<div className="tw-flex-1 tw-mr-2">
|
||||
<div className="tw-flex-1 tw-truncate tw-grid tw-grid-flow-col tw-max-w-52">
|
||||
<Link className="tw-btn tw-btn-ghost tw-px-2 tw-normal-case tw-text-xl tw-flex-1 tw-truncate" to={"/"}><p className="tw-truncate">{name}</p></Link>
|
||||
<Link className="tw-btn tw-btn-ghost tw-px-2 tw-normal-case tw-text-xl tw-flex-1 tw-truncate" to={"/"}><p className="tw-truncate">{appName}</p></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>
|
||||
|
||||
</div>
|
||||
@ -49,11 +65,11 @@ export default function NavBar({name, useAuth} : {name: string, useAuth : any})
|
||||
|
||||
{isAuthenticated && token ?
|
||||
<div className="tw-flex-none">
|
||||
<div className="tw-avatar">
|
||||
{user.avatar ? <div className="tw-avatar">
|
||||
<div className="tw-w-10 tw-rounded-full">
|
||||
<img src={"https://map.api.free-planet-earth.org/assets/"+user?.avatar+"?access_token="+token} />
|
||||
</div>
|
||||
</div>
|
||||
</div> : <></>}
|
||||
<div className='tw-ml-2 tw-mr-2'>{user?.first_name}</div>
|
||||
<div className="tw-dropdown tw-dropdown-end">
|
||||
<label tabIndex={0} className="tw-btn tw-btn-ghost tw-btn-square">
|
||||
@ -68,16 +84,33 @@ export default function NavBar({name, useAuth} : {name: string, useAuth : any})
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className="tw-dropdown tw-dropdown-end tw-mr-2">
|
||||
<label tabIndex={0} className="tw-btn tw-btn-ghost">
|
||||
Login
|
||||
</label>
|
||||
<div tabIndex={0} className="tw-mt-3 tw-card tw-card-compact tw-dropdown-content tw-w-72 tw-bg-base-100 tw-shadow !tw-z-[1000]">
|
||||
<div className="tw-card-body">
|
||||
<input type="email" placeholder="E-Mail" value={email} onChange={e => setEmail(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
|
||||
<input type="password" placeholder="Password" onChange={e => setPassword(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
|
||||
<div className="tw-card-actions">
|
||||
<button className={loading ? 'tw-btn tw-loading tw-btn-disabled tw-btn-block tw-btn-primary' : 'tw-btn tw-btn-primary tw-btn-block'} onClick={() => onLogin()}>Login</button>
|
||||
<div>
|
||||
<div className="tw-dropdown tw-dropdown-end tw-mr-2">
|
||||
<label tabIndex={0} className="tw-btn tw-btn-ghost">
|
||||
Login
|
||||
</label>
|
||||
<div tabIndex={0} className="tw-mt-3 tw-card tw-card-compact tw-dropdown-content tw-w-72 tw-bg-base-100 tw-shadow !tw-z-[1000]">
|
||||
<div className="tw-card-body">
|
||||
<input type="email" placeholder="E-Mail" value={email} onChange={e => setEmail(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
|
||||
<input type="password" placeholder="Password" onChange={e => setPassword(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
|
||||
<div className="tw-card-actions">
|
||||
<button className={loading ? 'tw-btn tw-btn-disabled tw-btn-block tw-btn-primary' : 'tw-btn tw-btn-primary tw-btn-block'} onClick={() => onLogin()}>{loading ? <span className="tw-loading tw-loading-spinner"></span> : 'Login'}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tw-dropdown tw-dropdown-end tw-mr-2">
|
||||
<label tabIndex={0} className="tw-btn tw-btn-ghost">
|
||||
Sign Up
|
||||
</label>
|
||||
<div tabIndex={0} className="tw-mt-3 tw-card tw-card-compact tw-dropdown-content tw-w-72 tw-bg-base-100 tw-shadow !tw-z-[1000]">
|
||||
<div className="tw-card-body">
|
||||
<input type="text" placeholder="Name" value={userName} onChange={e => setUserName(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
|
||||
<input type="email" placeholder="E-Mail" value={email} onChange={e => setEmail(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
|
||||
<input type="password" placeholder="Password" onChange={e => setPassword(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
|
||||
<div className="tw-card-actions">
|
||||
<button className={loading ? 'tw-btn tw-btn-disabled tw-btn-block tw-btn-primary' : 'tw-btn tw-btn-primary tw-btn-block'} onClick={() => onRegister()}>{loading ? <span className="tw-loading tw-loading-spinner"></span> : 'Sign Up'}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -28,6 +28,7 @@ type AuthContextProps = {
|
||||
isAuthenticated: Boolean,
|
||||
user: MyUserItem | null;
|
||||
login: (credentials: AuthCredentials) => Promise<MyUserItem | undefined>,
|
||||
register: (credentials: AuthCredentials, userName: string) => Promise<MyUserItem | undefined>,
|
||||
loading: Boolean,
|
||||
logout: () => void,
|
||||
updateUser: (user: MyUserItem) => any,
|
||||
@ -38,6 +39,7 @@ const AuthContext = createContext<AuthContextProps>({
|
||||
isAuthenticated: false,
|
||||
user: null,
|
||||
login: () => Promise.reject(),
|
||||
register: () => Promise.reject(),
|
||||
loading: false,
|
||||
logout: () => { },
|
||||
updateUser: () => Promise.reject(),
|
||||
@ -87,6 +89,18 @@ export const AuthProviderDirectus = ({ directus, children }: AuthProviderProps)
|
||||
};
|
||||
}
|
||||
|
||||
const register = async (credentials: AuthCredentials, userName): Promise<MyUserItem | undefined> => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await directus.users.createOne({email: credentials.email, password: credentials.password, first_name: userName});
|
||||
return (await login(credentials));
|
||||
} catch (error: any) {
|
||||
setLoading(false);
|
||||
console.log(error);
|
||||
|
||||
return error.response.data.error[0];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const logout = async () => {
|
||||
@ -96,9 +110,10 @@ export const AuthProviderDirectus = ({ directus, children }: AuthProviderProps)
|
||||
|
||||
const updateUser = async (user: MyUserItem) => {
|
||||
setLoading(true);
|
||||
const { id, ...userRest } = user;
|
||||
|
||||
try {
|
||||
const res = await directus.users.updateOne(user.id!, user)
|
||||
const res = await directus.users.updateOne(user.id!, userRest)
|
||||
setUser(res as any);
|
||||
setLoading(false);
|
||||
return res as any;
|
||||
@ -115,7 +130,7 @@ export const AuthProviderDirectus = ({ directus, children }: AuthProviderProps)
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{ isAuthenticated, user, login, loading, logout, updateUser, token }}
|
||||
value={{ isAuthenticated, user, login, register, loading, logout, updateUser, token }}
|
||||
>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
|
||||
@ -39,7 +39,6 @@ function MapEventListener(props: MapEventListenerProps) {
|
||||
// for refreshing map on resize (needs to be implemented)
|
||||
const mapDivRef = React.createRef();
|
||||
|
||||
/** This is a description of the foo function. */
|
||||
function UtopiaMap({
|
||||
height = "500px",
|
||||
width = "100%",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import TitleCard from '../TitleCard'
|
||||
import {TitleCard} from '../Templates/TitleCard'
|
||||
import InputText from '../Input/InputText'
|
||||
import TextAreaInput from '../Input/TextAreaInput'
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
27
src/Components/Templates/CardPage.tsx
Normal file
27
src/Components/Templates/CardPage.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { Link } from "react-router-dom"
|
||||
import * as React from "react"
|
||||
import {TitleCard} from "./TitleCard"
|
||||
|
||||
|
||||
export function CardPage({title,children} : {
|
||||
title: string,
|
||||
children?: React.ReactNode,
|
||||
}) {
|
||||
|
||||
|
||||
return (
|
||||
<main className="tw-flex-1 tw-overflow-y-auto tw-overflow-x-hidden tw-pt-2 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-text-sm tw-breadcrumbs">
|
||||
<ul>
|
||||
<li><Link to={'/'} >Home</Link></li>
|
||||
<li>FAQ</li>
|
||||
</ul>
|
||||
</div>
|
||||
<TitleCard title={title} topMargin="mt-2">
|
||||
{children}
|
||||
</TitleCard>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import Subtitle from "./Typography/Subtitle"
|
||||
import Subtitle from "../Typography/Subtitle"
|
||||
import * as React from "react"
|
||||
|
||||
interface TitleCardProps {
|
||||
@ -9,7 +9,7 @@ interface TitleCardProps {
|
||||
TopSideButtons?: any
|
||||
}
|
||||
|
||||
function TitleCard({title, children, topMargin, TopSideButtons} : TitleCardProps){
|
||||
export function TitleCard({title, children, topMargin, TopSideButtons} : TitleCardProps){
|
||||
return(
|
||||
<div className={"tw-card tw-w-full tw-p-6 tw-mb-16 tw-bg-base-100 tw-shadow-xl tw-h-fit " + (topMargin || "tw-mt-6")}>
|
||||
|
||||
@ -33,6 +33,3 @@ interface TitleCardProps {
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export default TitleCard
|
||||
2
src/Components/Templates/index.tsx
Normal file
2
src/Components/Templates/index.tsx
Normal file
@ -0,0 +1,2 @@
|
||||
export {CardPage} from './CardPage'
|
||||
export {TitleCard} from './TitleCard'
|
||||
@ -3,6 +3,8 @@ export {AppShell, Content, SideBar} from "./Components/AppShell"
|
||||
export {AuthProviderDirectus, useAuthDirectus} from "./Components/Auth"
|
||||
export {Settings} from './Components/Profile'
|
||||
export {Quests, Modal} from './Components/Gaming'
|
||||
export {TitleCard, CardPage} from './Components/Templates'
|
||||
|
||||
import "./index.css"
|
||||
|
||||
declare global {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user