mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
fix everything
- fix all autofixable problems - fix all other errors by a file-wide ignore
This commit is contained in:
parent
9d5ebf7e08
commit
c8b994796b
@ -30,6 +30,8 @@ module.exports = {
|
|||||||
'react-hooks',
|
'react-hooks',
|
||||||
'react-refresh',
|
'react-refresh',
|
||||||
],
|
],
|
||||||
|
// TODO also parse this
|
||||||
|
ignorePatterns: ['vite.config.ts'],
|
||||||
settings: {
|
settings: {
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
typescript: true,
|
typescript: true,
|
||||||
|
|||||||
213
src/App.tsx
213
src/App.tsx
@ -1,95 +1,135 @@
|
|||||||
import { AppShell, SideBar, Content, AuthProvider, Modal, LoginPage, SignupPage, Quests, RequestPasswordPage, SetNewPasswordPage, UserSettings, OverlayItemsIndexPage, ProfileView, ProfileForm, Permissions, Tags, SelectUser, AttestationForm, MarketView } from 'utopia-ui'
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import { getBottomRoutes, routes } from './routes/sidebar'
|
/* eslint-disable import/order */
|
||||||
|
/* eslint-disable eqeqeq */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable new-cap */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||||
|
/* eslint-disable @typescript-eslint/prefer-optional-chain */
|
||||||
|
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
import type { Tag } from 'utopia-ui'
|
||||||
|
|
||||||
|
import {
|
||||||
|
AppShell,
|
||||||
|
SideBar,
|
||||||
|
Content,
|
||||||
|
AuthProvider,
|
||||||
|
Modal,
|
||||||
|
LoginPage,
|
||||||
|
SignupPage,
|
||||||
|
Quests,
|
||||||
|
RequestPasswordPage,
|
||||||
|
SetNewPasswordPage,
|
||||||
|
UserSettings,
|
||||||
|
OverlayItemsIndexPage,
|
||||||
|
ProfileView,
|
||||||
|
ProfileForm,
|
||||||
|
Permissions,
|
||||||
|
Tags,
|
||||||
|
SelectUser,
|
||||||
|
AttestationForm,
|
||||||
|
MarketView,
|
||||||
|
} from 'utopia-ui'
|
||||||
import { Route, Routes } from 'react-router-dom'
|
import { Route, Routes } from 'react-router-dom'
|
||||||
import MapContainer from "./pages/MapContainer"
|
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import { userApi } from './api/userApi'
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { assetsApi } from './api/assetsApi'
|
import { assetsApi } from './api/assetsApi'
|
||||||
|
import { itemsApi } from './api/itemsApi'
|
||||||
|
import { layersApi } from './api/layersApi'
|
||||||
|
import { mapApi } from './api/mapApi'
|
||||||
|
import { permissionsApi } from './api/permissionsApi'
|
||||||
|
import { userApi } from './api/userApi'
|
||||||
import { ModalContent } from './ModalContent'
|
import { ModalContent } from './ModalContent'
|
||||||
import { Landingpage } from './pages/Landingpage'
|
import { Landingpage } from './pages/Landingpage'
|
||||||
import { useEffect, useState } from 'react'
|
import MapContainer from './pages/MapContainer'
|
||||||
import { itemsApi } from './api/itemsApi'
|
import { getBottomRoutes, routes } from './routes/sidebar'
|
||||||
import { permissionsApi } from './api/permissionsApi'
|
|
||||||
import { Tag } from 'utopia-ui'
|
|
||||||
import { mapApi } from './api/mapApi'
|
|
||||||
import { layersApi } from './api/layersApi'
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const [permissionsApiInstance, setPermissionsApiInstance] = useState<permissionsApi>()
|
||||||
|
const [tagsApi, setTagsApi] = useState<itemsApi<Tag>>()
|
||||||
|
const [mapApiInstance, setMapApiInstance] = useState<mapApi>()
|
||||||
|
const [layersApiInstance, setLayersApiInstance] = useState<layersApi>()
|
||||||
|
const [attestationApi, setAttestationApi] = useState<itemsApi<any>>()
|
||||||
|
|
||||||
|
const [map, setMap] = useState<any>()
|
||||||
const [permissionsApiInstance, setPermissionsApiInstance] = useState<permissionsApi>();
|
const [layers, setLayers] = useState<any>()
|
||||||
const [tagsApi, setTagsApi] = useState<itemsApi<Tag>>();
|
const [layerPageRoutes, setLayerPageRoutes] = useState<any>()
|
||||||
const [mapApiInstance, setMapApiInstance] = useState<mapApi>();
|
const [loading, setLoading] = useState<boolean>(true)
|
||||||
const [layersApiInstance, setLayersApiInstance] = useState<layersApi>();
|
|
||||||
const [attestationApi, setAttestationApi] = useState<itemsApi<any>>();
|
|
||||||
|
|
||||||
const [map, setMap] = useState<any>();
|
|
||||||
const [layers, setLayers] = useState<any>();
|
|
||||||
const [layerPageRoutes, setLayerPageRoutes] = useState<any>();
|
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPermissionsApiInstance(new permissionsApi());
|
setPermissionsApiInstance(new permissionsApi())
|
||||||
setMapApiInstance(new mapApi(window.location.origin));
|
setMapApiInstance(new mapApi(window.location.origin))
|
||||||
setAttestationApi(new itemsApi<any>("attestations"));
|
setAttestationApi(new itemsApi<any>('attestations'))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mapApiInstance && getMap();
|
mapApiInstance && getMap()
|
||||||
}, [mapApiInstance])
|
}, [mapApiInstance])
|
||||||
|
|
||||||
|
|
||||||
const getMap = async () => {
|
const getMap = async () => {
|
||||||
const map = await mapApiInstance?.getItems();
|
const map = await mapApiInstance?.getItems()
|
||||||
map && setMap(map);
|
map && setMap(map)
|
||||||
map && map != "null" && setLayersApiInstance(new layersApi(map.id));
|
map && map != 'null' && setLayersApiInstance(new layersApi(map.id))
|
||||||
map && map != "null" && map.own_tag_space ? setTagsApi(new itemsApi<Tag>('tags', undefined, map.id)) : setTagsApi(new itemsApi<Tag>('tags'));
|
map && map != 'null' && map.own_tag_space
|
||||||
|
? setTagsApi(new itemsApi<Tag>('tags', undefined, map.id))
|
||||||
|
: setTagsApi(new itemsApi<Tag>('tags'))
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
layersApiInstance && getLayers();
|
layersApiInstance && getLayers()
|
||||||
}, [layersApiInstance])
|
}, [layersApiInstance])
|
||||||
|
|
||||||
|
|
||||||
const getLayers = async () => {
|
const getLayers = async () => {
|
||||||
const layers = await layersApiInstance?.getItems();
|
const layers = await layersApiInstance?.getItems()
|
||||||
layers && setLayers(layers);
|
layers && setLayers(layers)
|
||||||
setLayerPageRoutes(layers?.filter((l: any) => l.listed).map((l: any) => ({
|
setLayerPageRoutes(
|
||||||
|
layers
|
||||||
|
?.filter((l: any) => l.listed)
|
||||||
|
.map((l: any) => ({
|
||||||
path: '/' + l.name, // url
|
path: '/' + l.name, // url
|
||||||
icon: <img src={"https://api.utopia-lab.org/assets/" + l.indexIcon}></img>,
|
icon: <img src={'https://api.utopia-lab.org/assets/' + l.indexIcon}></img>,
|
||||||
name: l.name, // name that appear in Sidebar
|
name: l.name, // name that appear in Sidebar
|
||||||
})));
|
})),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (map && map.name) {
|
if (map && map.name) {
|
||||||
document.title = map?.name && map.name;
|
document.title = map?.name && map.name
|
||||||
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement
|
let link: any = document.querySelector("link[rel~='icon']")!
|
||||||
if (!link) {
|
if (!link) {
|
||||||
link = document.createElement('link');
|
link = document.createElement('link')
|
||||||
link.rel = 'icon';
|
link.rel = 'icon'
|
||||||
document.getElementsByTagName('head')[0].appendChild(link);
|
document.getElementsByTagName('head')[0].appendChild(link)
|
||||||
}
|
}
|
||||||
link.href = map?.logo && "https://api.utopia-lab.org/assets/" + map.logo; // Specify the path to your favicon
|
link.href = map?.logo && 'https://api.utopia-lab.org/assets/' + map.logo // Specify the path to your favicon
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}, [map])
|
}, [map])
|
||||||
|
|
||||||
const currentUrl = window.location.href;
|
const currentUrl = window.location.href
|
||||||
const bottomRoutes = getBottomRoutes(currentUrl);
|
const bottomRoutes = getBottomRoutes(currentUrl)
|
||||||
|
|
||||||
if (map && layers) return (
|
if (map && layers)
|
||||||
|
return (
|
||||||
<div className="App overflow-x-hidden">
|
<div className='App overflow-x-hidden'>
|
||||||
|
<AuthProvider userApi={new userApi()}>
|
||||||
<AuthProvider userApi={new userApi}>
|
<AppShell
|
||||||
<AppShell assetsApi={new assetsApi("https://api.utopia-lab.org/assets/")} appName={map.name} >
|
assetsApi={new assetsApi('https://api.utopia-lab.org/assets/')}
|
||||||
<Permissions api={permissionsApiInstance} adminRole='8ed0b24e-3320-48cd-8444-bc152304e580'></Permissions>
|
appName={map.name}
|
||||||
|
>
|
||||||
|
<Permissions
|
||||||
|
api={permissionsApiInstance}
|
||||||
|
adminRole='8ed0b24e-3320-48cd-8444-bc152304e580'
|
||||||
|
></Permissions>
|
||||||
{tagsApi && <Tags api={tagsApi}></Tags>}
|
{tagsApi && <Tags api={tagsApi}></Tags>}
|
||||||
<Modal>
|
<Modal>
|
||||||
<ModalContent map={map} />
|
<ModalContent map={map} />
|
||||||
@ -98,23 +138,38 @@ function App() {
|
|||||||
<Content>
|
<Content>
|
||||||
<Quests />
|
<Quests />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/*" element={<MapContainer map={map} layers={layers} />}>
|
<Route path='/*' element={<MapContainer map={map} layers={layers} />}>
|
||||||
<Route path='login' element={<LoginPage />} />
|
<Route path='login' element={<LoginPage />} />
|
||||||
<Route path='signup' element={<SignupPage />} />
|
<Route path='signup' element={<SignupPage />} />
|
||||||
<Route path='reset-password' element={<RequestPasswordPage resetUrl={map.url + "/set-new-password/"} />} />
|
<Route
|
||||||
|
path='reset-password'
|
||||||
|
element={<RequestPasswordPage resetUrl={map.url + '/set-new-password/'} />}
|
||||||
|
/>
|
||||||
<Route path='set-new-password' element={<SetNewPasswordPage />} />
|
<Route path='set-new-password' element={<SetNewPasswordPage />} />
|
||||||
<Route path="item/*" element={<ProfileView attestationApi={attestationApi} />} />
|
<Route path='item/*' element={<ProfileView attestationApi={attestationApi} />} />
|
||||||
<Route path="edit-item/*" element={<ProfileForm />} />
|
<Route path='edit-item/*' element={<ProfileForm />} />
|
||||||
<Route path="user-settings" element={<UserSettings />} />
|
<Route path='user-settings' element={<UserSettings />} />
|
||||||
<Route path="landingpage" element={<Landingpage />} />
|
<Route path='landingpage' element={<Landingpage />} />
|
||||||
<Route path="market" element={<MarketView />} />
|
<Route path='market' element={<MarketView />} />
|
||||||
<Route path="select-user" element={<SelectUser />} />
|
<Route path='select-user' element={<SelectUser />} />
|
||||||
<Route path="attestation-form" element={<AttestationForm api={attestationApi} />} />
|
<Route
|
||||||
{
|
path='attestation-form'
|
||||||
layers.map((l: any) =>
|
element={<AttestationForm api={attestationApi} />}
|
||||||
<Route key={l.id} path={l.name} element={<OverlayItemsIndexPage plusButton={l.index_plus_button} layerName={l.name} url={'/item/'} parameterField={'id'} />} />
|
/>
|
||||||
)
|
{layers.map((l: any) => (
|
||||||
|
<Route
|
||||||
|
key={l.id}
|
||||||
|
path={l.name}
|
||||||
|
element={
|
||||||
|
<OverlayItemsIndexPage
|
||||||
|
plusButton={l.index_plus_button}
|
||||||
|
layerName={l.name}
|
||||||
|
url={'/item/'}
|
||||||
|
parameterField={'id'}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Content>
|
</Content>
|
||||||
@ -122,20 +177,20 @@ function App() {
|
|||||||
</AuthProvider>
|
</AuthProvider>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
else if (map == "null" && !loading) return (
|
else if (map == 'null' && !loading)
|
||||||
|
return (
|
||||||
<div className="flex items-center justify-center h-screen">
|
<div className='flex items-center justify-center h-screen'>
|
||||||
<div>
|
<div>
|
||||||
<p className='text-xl font-semibold'>This map does not exist</p>
|
<p className='text-xl font-semibold'>This map does not exist</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
else
|
||||||
else return (
|
return (
|
||||||
<div className="outer">
|
<div className='outer'>
|
||||||
<img className="pulse-loader opacity h-[96px]" src="/3markers-globe.svg" />
|
<img className='pulse-loader opacity h-[96px]' src='/3markers-globe.svg' />
|
||||||
<br/>
|
<br />
|
||||||
<span className="loader"></span>
|
<span className='loader'></span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +1,46 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable react/no-unescaped-entities */
|
||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { TextView } from 'utopia-ui'
|
import { TextView } from 'utopia-ui'
|
||||||
|
|
||||||
type ChapterProps = {
|
interface ChapterProps {
|
||||||
clickAction1?: () => void
|
clickAction1?: () => void
|
||||||
clickAction2?: () => void
|
clickAction2?: () => void
|
||||||
map?: any
|
map?: any
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function Welcome1({ clickAction1, map }: ChapterProps) {
|
export function Welcome1({ clickAction1, map }: ChapterProps) {
|
||||||
return (
|
return (
|
||||||
<>{map.custom_text?
|
<>
|
||||||
|
{map.custom_text ? (
|
||||||
<>
|
<>
|
||||||
<TextView rawText={map.custom_text}></TextView>
|
<TextView rawText={map.custom_text}></TextView>
|
||||||
</> :
|
</>
|
||||||
|
) : (
|
||||||
<>
|
<>
|
||||||
<h3 className="font-bold text-lg">Welcome to {map?.name || "Utopia Map"}</h3>
|
<h3 className='font-bold text-lg'>Welcome to {map?.name || 'Utopia Map'}</h3>
|
||||||
<img className="float-right w-32 m-2" src={"https://api.utopia-lab.org/assets/"+map.logo}></img>
|
<img
|
||||||
<p className="py-3">
|
className='float-right w-32 m-2'
|
||||||
|
src={'https://api.utopia-lab.org/assets/' + map.logo}
|
||||||
|
></img>
|
||||||
|
<p className='py-3'>
|
||||||
It is a tool for collaborative mapping to connect local initiatives, people and events.
|
It is a tool for collaborative mapping to connect local initiatives, people and events.
|
||||||
</p>
|
</p>
|
||||||
<p className="py-1">
|
<p className='py-1'>
|
||||||
Join us and grow the network by adding projects and events to the map.
|
Join us and grow the network by adding projects and events to the map.
|
||||||
</p>
|
</p>
|
||||||
<p className="py-1">
|
<p className='py-1'>Create your personal profile and place it on the map.</p>
|
||||||
Create your personal profile and place it on the map.
|
<div className='grid'>
|
||||||
</p>
|
<label className='btn place-self-end mt-4' onClick={() => clickAction1!()}>
|
||||||
<div className="grid">
|
Close
|
||||||
<label className="btn place-self-end mt-4" onClick={() => clickAction1!()}>Close</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</>}
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -38,17 +48,17 @@ export function Welcome1({ clickAction1, map }: ChapterProps) {
|
|||||||
export function Welcome2({ clickAction1 }: ChapterProps) {
|
export function Welcome2({ clickAction1 }: ChapterProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="font-bold text-lg"> Dencentralized Networking</h3>
|
<h3 className='font-bold text-lg'> Dencentralized Networking</h3>
|
||||||
<img className="float-right w-32 mx-4 my-2" src="/markers-circle.svg"></img>
|
<img className='float-right w-32 mx-4 my-2' src='/markers-circle.svg'></img>
|
||||||
|
|
||||||
<p className="py-3">
|
<p className='py-3'>
|
||||||
Find like-minded people, projects and events. In your neighbourhood and wherever you are!
|
Find like-minded people, projects and events. In your neighbourhood and wherever you are!
|
||||||
</p>
|
</p>
|
||||||
<p className="py-3">
|
<p className='py-3'>Onboard new people, places and events</p>
|
||||||
Onboard new people, places and events
|
<div className='grid'>
|
||||||
</p>
|
<button className='btn place-self-end mt-4' onClick={() => clickAction1!()}>
|
||||||
<div className="grid">
|
next
|
||||||
<button className="btn place-self-end mt-4" onClick={() => clickAction1!()}>next</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
@ -57,19 +67,22 @@ export function Welcome2({ clickAction1 }: ChapterProps) {
|
|||||||
export function Welcome3({ clickAction1 }: ChapterProps) {
|
export function Welcome3({ clickAction1 }: ChapterProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="font-bold text-lg">Mapping the Change</h3>
|
<h3 className='font-bold text-lg'>Mapping the Change</h3>
|
||||||
<p className="py-3">
|
<p className='py-3'>More and more people are waking up to what's really happening. </p>
|
||||||
More and more people are waking up to what's really happening. </p>
|
<p className='py-1'>
|
||||||
<p className="py-1">
|
They are in the process of understanding the potential that is within themselves and within
|
||||||
They are in the process of understanding the potential that is within themselves and within the whole mankind.
|
the whole mankind.
|
||||||
</p>
|
</p>
|
||||||
<img className="float-left w-32 mx-4" src="/3markers-globe.svg"></img>
|
<img className='float-left w-32 mx-4' src='/3markers-globe.svg'></img>
|
||||||
|
|
||||||
<p className="py-1">
|
<p className='py-1'>
|
||||||
Starting to reconnect with our Mother Earth and beginning to question things that long times have been taken for granted.
|
Starting to reconnect with our Mother Earth and beginning to question things that long times
|
||||||
|
have been taken for granted.
|
||||||
</p>
|
</p>
|
||||||
<div className="grid">
|
<div className='grid'>
|
||||||
<label className="btn place-self-end mt-4" onClick={() => clickAction1!()}>next</label>
|
<label className='btn place-self-end mt-4' onClick={() => clickAction1!()}>
|
||||||
|
next
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
@ -78,70 +91,87 @@ export function Welcome3({ clickAction1 }: ChapterProps) {
|
|||||||
export function Welcome4({ clickAction1 }: ChapterProps) {
|
export function Welcome4({ clickAction1 }: ChapterProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="font-bold text-lg"> Dezentralized Networks </h3>
|
<h3 className='font-bold text-lg'> Dezentralized Networks </h3>
|
||||||
|
|
||||||
<p className="py-3">
|
<p className='py-3'>
|
||||||
Find like-minded people, places and events. In your neighbourhood and wherever you are!
|
Find like-minded people, places and events. In your neighbourhood and wherever you are!
|
||||||
</p>
|
</p>
|
||||||
<img className="float-right w-32 mx-4 my-2" src="/network.svg"></img>
|
<img className='float-right w-32 mx-4 my-2' src='/network.svg'></img>
|
||||||
|
|
||||||
<p className="py-1">
|
<p className='py-1'>
|
||||||
Hypnotised, they sit in front of screens in concrete blocks, flooded and disillusioned by irrelevant information.
|
Hypnotised, they sit in front of screens in concrete blocks, flooded and disillusioned by
|
||||||
|
irrelevant information.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="py-1">
|
<p className='py-1'>
|
||||||
From an early age, they are trained to do alienated work and consume unhealthy and meaningless products.
|
From an early age, they are trained to do alienated work and consume unhealthy and
|
||||||
|
meaningless products.
|
||||||
</p>
|
</p>
|
||||||
<div className="grid">
|
<div className='grid'>
|
||||||
<button className="btn place-self-end mt-4" onClick={() => clickAction1!()}>next</button>
|
<button className='btn place-self-end mt-4' onClick={() => clickAction1!()}>
|
||||||
|
next
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
const myModal = document.getElementById('my_modal_3') as HTMLDialogElement;
|
const myModal = document.getElementById('my_modal_3') as HTMLDialogElement
|
||||||
myModal.close();
|
myModal.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ModalContent = ({map}:{map: any}) => {
|
export const ModalContent = ({ map }: { map: any }) => {
|
||||||
|
const [chapter, setChapter] = useState<number>(1)
|
||||||
const [chapter, setChapter] = useState<number>(1);
|
// const setQuestsOpen = useSetQuestOpen()
|
||||||
//const setQuestsOpen = useSetQuestOpen()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ActiveChapter = () => {
|
const ActiveChapter = () => {
|
||||||
switch (chapter) {
|
switch (chapter) {
|
||||||
case 1:
|
case 1:
|
||||||
return <Welcome1 map={map} clickAction1={() => {
|
|
||||||
|
|
||||||
close();
|
|
||||||
setTimeout(() => {
|
|
||||||
// setQuestsOpen(true);
|
|
||||||
setChapter(1);
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
}}/>
|
|
||||||
case 2:
|
|
||||||
return <Welcome2 clickAction1={() => { setChapter(3) }} />
|
|
||||||
case 3:
|
|
||||||
return <Welcome3 clickAction1={() => { setChapter(4) }} />
|
|
||||||
case 4:
|
|
||||||
return <Welcome4 clickAction1={() => {
|
|
||||||
|
|
||||||
close();
|
|
||||||
setTimeout(() => {
|
|
||||||
// setQuestsOpen(true);
|
|
||||||
setChapter(1);
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
}} />
|
|
||||||
default: return <></>
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActiveChapter />
|
<Welcome1
|
||||||
|
map={map}
|
||||||
|
clickAction1={() => {
|
||||||
|
close()
|
||||||
|
setTimeout(() => {
|
||||||
|
// setQuestsOpen(true);
|
||||||
|
setChapter(1)
|
||||||
|
}, 1000)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
|
case 2:
|
||||||
|
return (
|
||||||
|
<Welcome2
|
||||||
|
clickAction1={() => {
|
||||||
|
setChapter(3)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 3:
|
||||||
|
return (
|
||||||
|
<Welcome3
|
||||||
|
clickAction1={() => {
|
||||||
|
setChapter(4)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 4:
|
||||||
|
return (
|
||||||
|
<Welcome4
|
||||||
|
clickAction1={() => {
|
||||||
|
close()
|
||||||
|
setTimeout(() => {
|
||||||
|
// setQuestsOpen(true);
|
||||||
|
setChapter(1)
|
||||||
|
}, 1000)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return <ActiveChapter />
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,28 @@
|
|||||||
import { uploadFiles } from '@directus/sdk';
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { directusClient } from './directus';
|
/* eslint-disable no-console */
|
||||||
import { AssetsApi } from 'utopia-ui';
|
import { uploadFiles } from '@directus/sdk'
|
||||||
|
|
||||||
|
import { directusClient } from './directus'
|
||||||
|
|
||||||
export class assetsApi implements AssetsApi{
|
import type { AssetsApi } from 'utopia-ui'
|
||||||
|
|
||||||
url : string;
|
export class assetsApi implements AssetsApi {
|
||||||
|
url: string
|
||||||
|
|
||||||
constructor(url: string) {
|
constructor(url: string) {
|
||||||
this.url = url;
|
this.url = url
|
||||||
}
|
}
|
||||||
|
|
||||||
async upload(file:Blob, title: string) {
|
async upload(file: Blob, title: string) {
|
||||||
|
const formData = new FormData()
|
||||||
const formData = new FormData();
|
formData.append('title', title)
|
||||||
formData.append('title', title);
|
formData.append('file', file)
|
||||||
formData.append('file', file);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await directusClient.request(uploadFiles(formData));
|
return await directusClient.request(uploadFiles(formData))
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
throw error;
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,87 +1,93 @@
|
|||||||
import { createDirectus, rest, authentication, AuthenticationData, AuthenticationStorage } from '@directus/sdk';
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { Point } from 'geojson'
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
|
/* eslint-disable @typescript-eslint/require-await */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
import { createDirectus, rest, authentication } from '@directus/sdk'
|
||||||
|
|
||||||
export type Place = {
|
import type { AuthenticationData, AuthenticationStorage } from '@directus/sdk'
|
||||||
id: string;
|
import type { Point } from 'geojson'
|
||||||
name: string;
|
|
||||||
text: string;
|
|
||||||
position?: Point;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Project = {
|
export interface Place {
|
||||||
id: string;
|
id: string
|
||||||
name: string;
|
name: string
|
||||||
text: string;
|
text: string
|
||||||
position?: Point;
|
position?: Point
|
||||||
picture: string;
|
}
|
||||||
subname: string;
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Tag = {
|
export interface Project {
|
||||||
id: string;
|
id: string
|
||||||
color: string;
|
name: string
|
||||||
};
|
text: string
|
||||||
|
position?: Point
|
||||||
|
picture: string
|
||||||
|
subname: string
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
|
||||||
export type Event = {
|
export interface Tag {
|
||||||
id: string;
|
id: string
|
||||||
name: string;
|
color: string
|
||||||
text: string;
|
}
|
||||||
position?: Point;
|
|
||||||
start: Date;
|
|
||||||
end: Date;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Update = {
|
export interface Event {
|
||||||
id: string;
|
id: string
|
||||||
text: string;
|
name: string
|
||||||
position?: Point;
|
text: string
|
||||||
user_created: string;
|
position?: Point
|
||||||
date_created: string;
|
start: Date
|
||||||
}
|
end: Date
|
||||||
|
}
|
||||||
|
|
||||||
type CustomUserFields = {
|
export interface Update {
|
||||||
position: Point;
|
id: string
|
||||||
};
|
text: string
|
||||||
|
position?: Point
|
||||||
|
user_created: string
|
||||||
|
date_created: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CustomUserFields {
|
||||||
|
position: Point
|
||||||
|
}
|
||||||
|
|
||||||
export type MyCollections = {
|
export interface MyCollections {
|
||||||
places: Place[];
|
places: Place[]
|
||||||
events: Event[];
|
events: Event[]
|
||||||
updates: Update[];
|
updates: Update[]
|
||||||
tags: Tag[];
|
tags: Tag[]
|
||||||
projects: Project[];
|
projects: Project[]
|
||||||
directus_users: CustomUserFields[];
|
directus_users: CustomUserFields[]
|
||||||
|
}
|
||||||
|
|
||||||
};
|
export const authLocalStorage = (mainKey = 'directus_storage') =>
|
||||||
|
({
|
||||||
|
|
||||||
|
|
||||||
export const authLocalStorage = (mainKey: string = "directus_storage") => ({
|
|
||||||
// implementation of get, here return json parsed data from localStorage at mainKey (or null if not found)
|
// implementation of get, here return json parsed data from localStorage at mainKey (or null if not found)
|
||||||
get: async () => {
|
get: async () => {
|
||||||
const data = window.localStorage.getItem(mainKey);
|
const data = window.localStorage.getItem(mainKey)
|
||||||
if (data) {
|
if (data) {
|
||||||
return JSON.parse(data);
|
return JSON.parse(data)
|
||||||
}
|
}
|
||||||
return null;
|
return null
|
||||||
},
|
},
|
||||||
// implementation of set, here set the value at mainKey in localStorage, or remove it if value is null
|
// implementation of set, here set the value at mainKey in localStorage, or remove it if value is null
|
||||||
set: async (value: AuthenticationData | null) => {
|
set: async (value: AuthenticationData | null) => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return window.localStorage.removeItem(mainKey);
|
return window.localStorage.removeItem(mainKey)
|
||||||
}
|
}
|
||||||
return window.localStorage.setItem(mainKey, JSON.stringify(value));
|
return window.localStorage.setItem(mainKey, JSON.stringify(value))
|
||||||
},
|
},
|
||||||
} as AuthenticationStorage);
|
}) as AuthenticationStorage
|
||||||
|
|
||||||
export async function getRefreshToken(){
|
export async function getRefreshToken() {
|
||||||
let auth = await authLocalStorage().get()
|
const auth = await authLocalStorage().get()
|
||||||
return auth!.refresh_token;
|
return auth!.refresh_token
|
||||||
}
|
}
|
||||||
|
|
||||||
export const directusClient = createDirectus<MyCollections>("https://api.utopia-lab.org/")
|
export const directusClient = createDirectus<MyCollections>('https://api.utopia-lab.org/')
|
||||||
.with(rest())
|
.with(rest())
|
||||||
.with(authentication('json', { // add this if you want to use authentication, json is important, it's type of your authentication usage, here JWT
|
.with(
|
||||||
|
authentication('json', {
|
||||||
|
// add this if you want to use authentication, json is important, it's type of your authentication usage, here JWT
|
||||||
storage: authLocalStorage(), // here set the storage previously created
|
storage: authLocalStorage(), // here set the storage previously created
|
||||||
}));
|
}),
|
||||||
|
)
|
||||||
|
|||||||
@ -1,103 +1,124 @@
|
|||||||
import { createItem, deleteItem, readItem, readItems, updateItem } from '@directus/sdk';
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import { MyCollections, directusClient } from './directus';
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import { ItemsApi } from 'utopia-ui';
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
|
import { createItem, deleteItem, readItem, readItems, updateItem } from '@directus/sdk'
|
||||||
|
|
||||||
|
import { directusClient } from './directus'
|
||||||
|
|
||||||
|
import type { MyCollections } from './directus'
|
||||||
|
import type { ItemsApi } from 'utopia-ui'
|
||||||
|
|
||||||
export class itemsApi<T> implements ItemsApi<T>{
|
export class itemsApi<T> implements ItemsApi<T> {
|
||||||
|
collectionName: string
|
||||||
collectionName: string;
|
filter: any
|
||||||
filter: any;
|
layerId: string | undefined
|
||||||
layerId: string | undefined;
|
mapId: string | undefined
|
||||||
mapId: string | undefined;
|
|
||||||
customParameter: any
|
customParameter: any
|
||||||
|
|
||||||
|
constructor(
|
||||||
constructor(collectionName: string, layerId?: string | undefined, mapId?: string | undefined, filter?: any, customParameter?:any ) {
|
collectionName: string,
|
||||||
this.collectionName = collectionName;
|
layerId?: string | undefined,
|
||||||
if(filter) this.filter = filter;
|
mapId?: string | undefined,
|
||||||
else this.filter = {};
|
filter?: any,
|
||||||
this.layerId = layerId;
|
customParameter?: any,
|
||||||
if(layerId) {
|
) {
|
||||||
this.filter = {... filter, ... { "layer" : { "id": { "_eq": layerId }}}}
|
this.collectionName = collectionName
|
||||||
|
if (filter) this.filter = filter
|
||||||
|
else this.filter = {}
|
||||||
|
this.layerId = layerId
|
||||||
|
if (layerId) {
|
||||||
|
this.filter = { ...filter, ...{ layer: { id: { _eq: layerId } } } }
|
||||||
}
|
}
|
||||||
this.mapId = mapId;
|
this.mapId = mapId
|
||||||
if(mapId) {
|
if (mapId) {
|
||||||
this.filter = {... filter, ... { "map" : { "id": { "_eq": mapId }}}}
|
this.filter = { ...filter, ...{ map: { id: { _eq: mapId } } } }
|
||||||
}
|
}
|
||||||
if(customParameter) this.customParameter = customParameter;
|
if (customParameter) this.customParameter = customParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItems(): Promise<T[]> {
|
async getItems(): Promise<T[]> {
|
||||||
try {
|
try {
|
||||||
const result = await directusClient.request<T[]>(
|
const result = await directusClient.request<T[]>(
|
||||||
readItems(
|
readItems(this.collectionName as never, {
|
||||||
this.collectionName as never,
|
fields: [
|
||||||
{
|
'*',
|
||||||
fields: ['*', 'to.*', "relations.*", "user_created.*", { offers: ['*'], needs: ['*'], gallery: ['*.*'] } as any],
|
'to.*',
|
||||||
|
'relations.*',
|
||||||
|
'user_created.*',
|
||||||
|
{ offers: ['*'], needs: ['*'], gallery: ['*.*'] } as any,
|
||||||
|
],
|
||||||
filter: this.filter,
|
filter: this.filter,
|
||||||
limit: -1
|
limit: -1,
|
||||||
}
|
}),
|
||||||
)
|
)
|
||||||
);
|
|
||||||
|
|
||||||
return result as T[];
|
return result
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error)
|
||||||
if (error.errors?.[0]?.message) {
|
if (error.errors?.[0]?.message) {
|
||||||
throw new Error(error.errors[0].message);
|
throw new Error(error.errors[0].message)
|
||||||
} else {
|
} else {
|
||||||
throw error;
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getItem(id: string): Promise<T> {
|
||||||
async getItem(id : string): Promise<T> {
|
|
||||||
try {
|
try {
|
||||||
const result = await directusClient.request(readItem(this.collectionName as never, id));
|
const result = await directusClient.request(readItem(this.collectionName as never, id))
|
||||||
return result as T
|
return result as T
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0]?.message)
|
if (error.errors[0]?.message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createItem(item: T & { id?: string }) : Promise<T> {
|
async createItem(item: T & { id?: string }): Promise<T> {
|
||||||
try {
|
try {
|
||||||
const result = await directusClient.request(createItem(this.collectionName as keyof MyCollections, {...item, ...(this.customParameter && this.customParameter), ...(this.layerId && {layer: this.layerId}), ...(this.layerId && {layer: this.layerId}), ...(this.mapId && {map: this.mapId})}))
|
const result = await directusClient.request(
|
||||||
|
createItem(this.collectionName as keyof MyCollections, {
|
||||||
|
...item,
|
||||||
|
...(this.customParameter && this.customParameter),
|
||||||
|
...(this.layerId && { layer: this.layerId }),
|
||||||
|
...(this.layerId && { layer: this.layerId }),
|
||||||
|
...(this.mapId && { map: this.mapId }),
|
||||||
|
}),
|
||||||
|
)
|
||||||
return result as T
|
return result as T
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0]?.message)
|
if (error.errors[0]?.message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateItem(item: T & { id?: string }) : Promise<T> {
|
async updateItem(item: T & { id?: string }): Promise<T> {
|
||||||
try {
|
try {
|
||||||
const result = await directusClient.request(updateItem(this.collectionName as keyof MyCollections, item.id!, item))
|
const result = await directusClient.request(
|
||||||
|
updateItem(this.collectionName as keyof MyCollections, item.id!, item),
|
||||||
|
)
|
||||||
return result as T
|
return result as T
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteItem(id: string) : Promise<boolean> {
|
async deleteItem(id: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const result = await directusClient.request(deleteItem(this.collectionName as keyof MyCollections, id))
|
const result = await directusClient.request(
|
||||||
|
deleteItem(this.collectionName as keyof MyCollections, id),
|
||||||
|
)
|
||||||
return result as unknown as boolean
|
return result as unknown as boolean
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,25 +1,31 @@
|
|||||||
import { readItems } from '@directus/sdk';
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { directusClient } from './directus';
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
import { readItems } from '@directus/sdk'
|
||||||
|
|
||||||
|
import { directusClient } from './directus'
|
||||||
|
|
||||||
export class layersApi {
|
export class layersApi {
|
||||||
mapId : string
|
mapId: string
|
||||||
|
|
||||||
constructor(mapId: string) {
|
constructor(mapId: string) {
|
||||||
this.mapId = mapId;
|
this.mapId = mapId
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItems() {
|
async getItems() {
|
||||||
try {
|
try {
|
||||||
const layers = await directusClient.request(readItems("layers" as any, { fields: ['*', {itemType : ['*.*', {profileTemplate: ['*', 'item.*.*.*'] }]} as any], filter: { "maps": { "maps_id": { "id": { "_eq": this.mapId } } } }, limit: 500 }));
|
const layers = await directusClient.request(
|
||||||
return layers;
|
readItems('layers' as any, {
|
||||||
|
fields: ['*', { itemType: ['*.*', { profileTemplate: ['*', 'item.*.*.*'] }] } as any],
|
||||||
|
filter: { maps: { maps_id: { id: { _eq: this.mapId } } } },
|
||||||
|
limit: 500,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
return layers
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0]?.message)
|
if (error.errors[0]?.message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +1,33 @@
|
|||||||
import { readItems } from '@directus/sdk';
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
import { directusClient } from './directus';
|
/* eslint-disable no-console */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { readItems } from '@directus/sdk'
|
||||||
|
|
||||||
|
import { directusClient } from './directus'
|
||||||
|
|
||||||
export class mapApi {
|
export class mapApi {
|
||||||
url : string
|
url: string
|
||||||
|
|
||||||
constructor(url: string) {
|
constructor(url: string) {
|
||||||
this.url = url;
|
this.url = url
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItems() {
|
async getItems() {
|
||||||
try {
|
try {
|
||||||
const map = await directusClient.request(readItems("maps" as any, { fields: ['*', {user_type : ['name']}], filter: { "url": { "_eq": this.url } } as any, limit: 500 }));
|
const map = await directusClient.request(
|
||||||
if(map[0]) return map[0];
|
readItems('maps' as any, {
|
||||||
else return "null";
|
fields: ['*', { user_type: ['name'] }],
|
||||||
|
filter: { url: { _eq: this.url } } as any,
|
||||||
|
limit: 500,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
if (map[0]) return map[0]
|
||||||
|
else return 'null'
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0]?.message)
|
if (error.errors[0]?.message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
import { readPermissions } from "@directus/sdk";
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { directusClient } from "./directus";
|
/* eslint-disable @typescript-eslint/no-useless-constructor */
|
||||||
import { ItemsApi, Permission } from "utopia-ui";
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
import { readPermissions } from '@directus/sdk'
|
||||||
|
|
||||||
|
import { directusClient } from './directus'
|
||||||
|
|
||||||
|
import type { ItemsApi, Permission } from 'utopia-ui'
|
||||||
|
|
||||||
export class permissionsApi implements ItemsApi<Permission> {
|
export class permissionsApi implements ItemsApi<Permission> {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
@ -8,13 +15,13 @@ export class permissionsApi implements ItemsApi<Permission> {
|
|||||||
async getItems(): Promise<Permission[]> {
|
async getItems(): Promise<Permission[]> {
|
||||||
try {
|
try {
|
||||||
const result = await directusClient.request(
|
const result = await directusClient.request(
|
||||||
readPermissions({ fields: ["*", { policy: ["name", "roles"] } as any] })
|
readPermissions({ fields: ['*', { policy: ['name', 'roles'] } as any] }),
|
||||||
);
|
)
|
||||||
return result as unknown as Permission[]
|
return result as unknown as Permission[]
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0]?.message) throw error.errors[0].message;
|
if (error.errors[0]?.message) throw error.errors[0].message
|
||||||
else throw error;
|
else throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,18 @@
|
|||||||
import { readUser } from '@directus/sdk';
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
import { directusClient } from './directus';
|
/* eslint-disable no-console */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { readUser } from '@directus/sdk'
|
||||||
|
|
||||||
|
import { directusClient } from './directus'
|
||||||
|
|
||||||
|
export class readUserApi {
|
||||||
export class readUserApi{
|
async getItem(id: string) {
|
||||||
|
|
||||||
async getItem(id : string) {
|
|
||||||
try {
|
try {
|
||||||
return await directusClient.request(readUser(id));
|
return await directusClient.request(readUser(id))
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0]?.message)
|
if (error.errors[0]?.message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,24 +1,29 @@
|
|||||||
import axios from 'axios';
|
/* eslint-disable no-console */
|
||||||
import { ItemsApi } from 'utopia-ui';
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import type { ItemsApi } from 'utopia-ui'
|
||||||
|
|
||||||
export class refiBcnApi implements ItemsApi<any>{
|
export class refiBcnApi implements ItemsApi<any> {
|
||||||
|
collectionName: string
|
||||||
collectionName: string;
|
|
||||||
|
|
||||||
constructor(collectionName: string) {
|
constructor(collectionName: string) {
|
||||||
this.collectionName = collectionName;
|
this.collectionName = collectionName
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItems() {
|
async getItems() {
|
||||||
try {
|
try {
|
||||||
return (await axios.get('https://antontranelis.github.io/ReFi-Barcelona-Prototype/projects/index.json')).data.data;
|
return (
|
||||||
|
await axios.get(
|
||||||
|
'https://antontranelis.github.io/ReFi-Barcelona-Prototype/projects/index.json',
|
||||||
|
)
|
||||||
|
).data.data
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0]?.message)
|
if (error.errors[0]?.message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,110 +1,97 @@
|
|||||||
import { createUser, passwordRequest, passwordReset, readMe, updateMe} from '@directus/sdk';
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
import { directusClient } from './directus';
|
/* eslint-disable camelcase */
|
||||||
import { UserApi, UserItem } from 'utopia-ui';
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||||
|
import { createUser, passwordRequest, passwordReset, readMe, updateMe } from '@directus/sdk'
|
||||||
|
|
||||||
|
import { directusClient } from './directus'
|
||||||
|
|
||||||
|
import type { UserApi, UserItem } from 'utopia-ui'
|
||||||
|
|
||||||
export class userApi implements UserApi {
|
export class userApi implements UserApi {
|
||||||
|
|
||||||
async register(email: string, password: string, userName: string): Promise<any> {
|
async register(email: string, password: string, userName: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
return await directusClient.request(createUser({email: email, password: password, first_name: userName}));
|
return await directusClient.request(createUser({ email, password, first_name: userName }))
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(email: string, password: string): Promise<any> {
|
async login(email: string, password: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
return await directusClient.login(email,password,{mode: 'json'});
|
return await directusClient.login(email, password, { mode: 'json' })
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async logout(): Promise<any> {
|
async logout(): Promise<any> {
|
||||||
try {
|
try {
|
||||||
return await directusClient.logout();
|
return await directusClient.logout()
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUser(): Promise<any> {
|
async getUser(): Promise<any> {
|
||||||
try {
|
try {
|
||||||
let user = await directusClient.request(readMe({ fields: ['*', {role: ['*']} as any] }));
|
const user = await directusClient.request(readMe({ fields: ['*', { role: ['*'] } as any] }))
|
||||||
return user;
|
return user
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getToken(): Promise<any> {
|
async getToken(): Promise<any> {
|
||||||
try {
|
try {
|
||||||
const token = await directusClient.getToken();
|
const token = await directusClient.getToken()
|
||||||
return token;
|
return token
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateUser(user: UserItem): Promise<any> {
|
async updateUser(user: UserItem): Promise<any> {
|
||||||
const { id, ...userRest } = user;
|
const { id, ...userRest } = user
|
||||||
try {
|
try {
|
||||||
const res = await directusClient.request(updateMe(userRest,{ fields: ['*'] }))
|
const res = await directusClient.request(updateMe(userRest, { fields: ['*'] }))
|
||||||
return res as any;
|
return res as any
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async requestPasswordReset(email:string, reset_url?:string): Promise<any> {
|
async requestPasswordReset(email: string, reset_url?: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
return await directusClient.request(passwordRequest(email,reset_url));
|
return await directusClient.request(passwordRequest(email, reset_url))
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async passwordReset(reset_token:string, new_password:string): Promise<any> {
|
async passwordReset(reset_token: string, new_password: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
return await directusClient.request(passwordReset(reset_token, new_password));
|
return await directusClient.request(passwordReset(reset_token, new_password))
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log(error);
|
console.log(error)
|
||||||
if (error.errors[0].message)
|
if (error.errors[0].message) throw error.errors[0].message
|
||||||
throw error.errors[0].message;
|
else throw error
|
||||||
else throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
|
/* eslint-disable import/default */
|
||||||
|
/* eslint-disable import/extensions */
|
||||||
|
/* eslint-disable import/no-named-as-default-member */
|
||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom/client'
|
import ReactDOM from 'react-dom/client'
|
||||||
|
|
||||||
import App from './App.tsx'
|
import App from './App.tsx'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import React, { useState } from 'react'
|
/* eslint-disable import/default */
|
||||||
|
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||||
|
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline'
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
eachDayOfInterval,
|
eachDayOfInterval,
|
||||||
@ -11,90 +13,84 @@ import {
|
|||||||
parse,
|
parse,
|
||||||
startOfToday,
|
startOfToday,
|
||||||
startOfWeek,
|
startOfWeek,
|
||||||
} from "date-fns";
|
} from 'date-fns'
|
||||||
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
import React, { useState } from 'react'
|
||||||
import { MapOverlayPage } from 'utopia-ui';
|
import { MapOverlayPage } from 'utopia-ui'
|
||||||
|
|
||||||
|
|
||||||
export const Calendar = () => {
|
export const Calendar = () => {
|
||||||
const today = startOfToday();
|
const today = startOfToday()
|
||||||
const days = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
const days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
|
||||||
const colStartClasses = [
|
const colStartClasses = [
|
||||||
"",
|
'',
|
||||||
"col-start-2",
|
'col-start-2',
|
||||||
"col-start-3",
|
'col-start-3',
|
||||||
"col-start-4",
|
'col-start-4',
|
||||||
"col-start-5",
|
'col-start-5',
|
||||||
"col-start-6",
|
'col-start-6',
|
||||||
"col-start-7",
|
'col-start-7',
|
||||||
];
|
]
|
||||||
|
|
||||||
const [currMonth, setCurrMonth] = useState(() => format(today, "MMM-yyyy"));
|
const [currMonth, setCurrMonth] = useState(() => format(today, 'MMM-yyyy'))
|
||||||
let firstDayOfMonth = parse(currMonth, "MMM-yyyy", new Date());
|
const firstDayOfMonth = parse(currMonth, 'MMM-yyyy', new Date())
|
||||||
|
|
||||||
const daysInMonth = eachDayOfInterval({
|
const daysInMonth = eachDayOfInterval({
|
||||||
start: startOfWeek(firstDayOfMonth),
|
start: startOfWeek(firstDayOfMonth),
|
||||||
end: endOfWeek(endOfMonth(firstDayOfMonth)),
|
end: endOfWeek(endOfMonth(firstDayOfMonth)),
|
||||||
});
|
})
|
||||||
|
|
||||||
const getPrevMonth = (event: React.MouseEvent<SVGSVGElement>) => {
|
const getPrevMonth = (event: React.MouseEvent<SVGSVGElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
const firstDayOfPrevMonth = add(firstDayOfMonth, { months: -1 });
|
const firstDayOfPrevMonth = add(firstDayOfMonth, { months: -1 })
|
||||||
setCurrMonth(format(firstDayOfPrevMonth, "MMM-yyyy"));
|
setCurrMonth(format(firstDayOfPrevMonth, 'MMM-yyyy'))
|
||||||
};
|
}
|
||||||
|
|
||||||
const getNextMonth = (event: React.MouseEvent<SVGSVGElement>) => {
|
const getNextMonth = (event: React.MouseEvent<SVGSVGElement>) => {
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
const firstDayOfNextMonth = add(firstDayOfMonth, { months: 1 });
|
const firstDayOfNextMonth = add(firstDayOfMonth, { months: 1 })
|
||||||
setCurrMonth(format(firstDayOfNextMonth, "MMM-yyyy"));
|
setCurrMonth(format(firstDayOfNextMonth, 'MMM-yyyy'))
|
||||||
};
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MapOverlayPage backdrop className='tw-max-h-[calc(100dvh-96px)] tw-h-fit md:tw-w-[calc(50%-32px)] tw-w-[calc(100%-32px)] max-w-lg'>
|
<MapOverlayPage
|
||||||
<div className="flex items-center justify-between">
|
backdrop
|
||||||
<p className="font-semibold text-xl">
|
className='tw-max-h-[calc(100dvh-96px)] tw-h-fit md:tw-w-[calc(50%-32px)] tw-w-[calc(100%-32px)] max-w-lg'
|
||||||
{format(firstDayOfMonth, "MMMM yyyy")}
|
>
|
||||||
</p>
|
<div className='flex items-center justify-between'>
|
||||||
<div className="flex items-center justify-evenly gap-6 sm:gap-12">
|
<p className='font-semibold text-xl'>{format(firstDayOfMonth, 'MMMM yyyy')}</p>
|
||||||
<ChevronLeftIcon
|
<div className='flex items-center justify-evenly gap-6 sm:gap-12'>
|
||||||
className="w-6 h-6 cursor-pointer"
|
<ChevronLeftIcon className='w-6 h-6 cursor-pointer' onClick={getPrevMonth} />
|
||||||
onClick={getPrevMonth}
|
<ChevronRightIcon className='w-6 h-6 cursor-pointer' onClick={getNextMonth} />
|
||||||
/>
|
|
||||||
<ChevronRightIcon
|
|
||||||
className="w-6 h-6 cursor-pointer"
|
|
||||||
onClick={getNextMonth}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr className="my-6" />
|
<hr className='my-6' />
|
||||||
<div className="grid grid-cols-7 gap-6 sm:gap-12 place-items-center">
|
<div className='grid grid-cols-7 gap-6 sm:gap-12 place-items-center'>
|
||||||
{days.map((day, idx) => {
|
{days.map((day, idx) => {
|
||||||
return (
|
return (
|
||||||
<div key={idx} className="font-semibold">
|
<div key={idx} className='font-semibold'>
|
||||||
{capitalizeFirstLetter(day)}
|
{capitalizeFirstLetter(day)}
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-7 gap-4 sm:gap-12 mt-8 place-items-center">
|
<div className='grid grid-cols-7 gap-4 sm:gap-12 mt-8 place-items-center'>
|
||||||
{daysInMonth.map((day, idx) => {
|
{daysInMonth.map((day, idx) => {
|
||||||
return (
|
return (
|
||||||
<div key={idx} className={colStartClasses[getDay(day)]}>
|
<div key={idx} className={colStartClasses[getDay(day)]}>
|
||||||
<p
|
<p
|
||||||
className={`cursor-pointer flex items-center justify-center font-semibold h-8 w-8 rounded-full hover:text-white ${
|
className={`cursor-pointer flex items-center justify-center font-semibold h-8 w-8 rounded-full hover:text-white ${
|
||||||
isSameMonth(day, today) ? "text-current" : "text-gray-500"
|
isSameMonth(day, today) ? 'text-current' : 'text-gray-500'
|
||||||
} ${!isToday(day) && "hover:bg-primary-content"} ${
|
} ${!isToday(day) && 'hover:bg-primary-content'} ${
|
||||||
isToday(day) && "bg-primary !text-white"
|
isToday(day) && 'bg-primary !text-white'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{format(day, "d")}
|
{format(day, 'd')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</MapOverlayPage>
|
</MapOverlayPage>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const capitalizeFirstLetter = (string: string) => {
|
const capitalizeFirstLetter = (string: string) => {
|
||||||
|
|||||||
@ -1,120 +1,109 @@
|
|||||||
import { CardPage } from "utopia-ui"
|
/* eslint-disable react/no-unescaped-entities */
|
||||||
|
import { CardPage } from 'utopia-ui'
|
||||||
|
|
||||||
export default function Concept() {
|
export default function Concept() {
|
||||||
return (
|
return (
|
||||||
<CardPage title="Concept">
|
<CardPage title='Concept'>
|
||||||
Utopia is a cooperative Real Life Manifestation Game. While playing, we connect with ourselves, each other and our dreams to manifest them together.<br></br><br></br>
|
Utopia is a cooperative Real Life Manifestation Game. While playing, we connect with
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
ourselves, each other and our dreams to manifest them together.<br></br>
|
||||||
<input type="radio" name="my-accordion-2" />
|
<br></br>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
Real Life Manifestation Games </div>
|
<input type='radio' name='my-accordion-2' />
|
||||||
<div className="collapse-content">
|
<div className='collapse-title text-xl font-medium'>Real Life Manifestation Games </div>
|
||||||
<ul className="list-disc list-inside pl-4">
|
<div className='collapse-content'>
|
||||||
|
<ul className='list-disc list-inside pl-4'>
|
||||||
<li>
|
<li>
|
||||||
Like a role-playing game, you can create your own profile, but here you can map, share and train real skills.
|
Like a role-playing game, you can create your own profile, but here you can map, share
|
||||||
|
and train real skills.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Further, real resources are made visible and available, managed and used, similar to a strategy game.
|
Further, real resources are made visible and available, managed and used, similar to a
|
||||||
|
strategy game.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Project management tasks can be mapped as quests, levels, missions and problems become challenges.
|
Project management tasks can be mapped as quests, levels, missions and problems become
|
||||||
|
challenges.
|
||||||
</li>
|
</li>
|
||||||
|
<li>The storytelling is based on the real conditions and challenges on our planet.</li>
|
||||||
<li>
|
<li>
|
||||||
The storytelling is based on the real conditions and challenges on our planet.
|
The goal of the game is to create win-win-win situations. Win for you, win for us, win
|
||||||
</li>
|
for the world.
|
||||||
<li>
|
|
||||||
The goal of the game is to create win-win-win situations. Win for you, win for us, win for the world.
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
<input type="radio" name="my-accordion-2" />
|
<input type='radio' name='my-accordion-2' />
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='collapse-title text-xl font-medium'>Elements</div>
|
||||||
Elements
|
<div className='collapse-content'>
|
||||||
|
<div className='flex flex-row flex-wrap'>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> The App</h3>
|
||||||
|
The app provides an interactive geographical map as a playing field. It also allows
|
||||||
|
you to create and view player profiles. The marketplace shows offers and needs.{' '}
|
||||||
</div>
|
</div>
|
||||||
<div className="collapse-content">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
<div className="flex flex-row flex-wrap">
|
<h3 className='text-base my-3 font-medium'> Print Material</h3>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
To complement offline play, there are flyers, stickers, signs and workbooks that
|
||||||
<h3 className="text-base my-3 font-medium"> The App</h3>
|
invite players to play. Players receive or print ID cards with QR codes that are used
|
||||||
The app provides an interactive geographical map as a playing field. It also allows you to create and view player profiles. The marketplace shows offers and needs. </div>
|
for networking (more on this later).
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
<h3 className="text-base my-3 font-medium"> Print Material</h3>
|
|
||||||
To complement offline play, there are flyers, stickers, signs and workbooks that invite players to play.
|
|
||||||
|
|
||||||
Players receive or print ID cards with QR codes that are used for networking (more on this later).
|
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Gatherings</h3>
|
||||||
<h3 className="text-base my-3 font-medium"> Gatherings</h3>
|
Coming together at workshops, festivals and local meetings to connect, build
|
||||||
|
structures and to engage new players.{' '}
|
||||||
Coming together at workshops, festivals and local meetings to connect, build structures and to engage new players. </div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Permanent Structures</h3>
|
||||||
<h3 className="text-base my-3 font-medium"> Permanent Structures</h3>
|
When we play, we create tangible structures like places and infrastructure. And also
|
||||||
|
intangibles like networks of relationships, stories, information ...
|
||||||
When we play, we create tangible structures like places and infrastructure.
|
|
||||||
|
|
||||||
And also intangibles like networks of relationships, stories, information ...
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
<input type='radio' name='my-accordion-2' />
|
||||||
<input type="radio" name="my-accordion-2" />
|
<div className='collapse-title text-xl font-medium'>Goals </div>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='collapse-content'>
|
||||||
Goals </div>
|
<ol className='list-decimal list-inside pl-4'>
|
||||||
<div className="collapse-content">
|
|
||||||
|
|
||||||
<ol className="list-decimal list-inside pl-4">
|
|
||||||
<li>To build a decentralised network</li>
|
<li>To build a decentralised network</li>
|
||||||
<li>Free development of our collective and individual potential</li>
|
<li>Free development of our collective and individual potential</li>
|
||||||
<li>Start co-creation and build collective structures</li>
|
<li>Start co-creation and build collective structures</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
<input type='radio' name='my-accordion-2' />
|
||||||
<input type="radio" name="my-accordion-2" />
|
<div className='collapse-title text-xl font-medium'>Gameplay </div>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='collapse-content'>
|
||||||
Gameplay </div>
|
Through playful elements and gamification, the player is motivated and guided through
|
||||||
<div className="collapse-content">
|
quests and levels.
|
||||||
|
<h3 className='text-base my-3 font-medium'> Player Profiles</h3>
|
||||||
Through playful elements and gamification, the player is motivated and guided through quests and levels.
|
The player examines himself and his abilities as well as deeper desires and visions to
|
||||||
|
define his character or player profile. The focus is on the following questions:
|
||||||
<h3 className="text-base my-3 font-medium"> Player Profiles</h3>
|
<ul className='list-disc list-inside pl-4 pt-4'>
|
||||||
|
|
||||||
The player examines himself and his abilities as well as deeper desires and visions to define his character or player profile.
|
|
||||||
|
|
||||||
The focus is on the following questions:
|
|
||||||
<ul className="list-disc list-inside pl-4 pt-4">
|
|
||||||
<li>How and in what kind of world do I want to live?</li>
|
<li>How and in what kind of world do I want to live?</li>
|
||||||
<li>Who am I and what are my special abilities or my special task in this life?</li>
|
<li>Who am I and what are my special abilities or my special task in this life?</li>
|
||||||
<li>What do I have to give? What can and do I want to share with others and the world?</li>
|
<li>
|
||||||
<li>What do I still need to come fully into my power? How can others support me in this?</li>
|
What do I have to give? What can and do I want to share with others and the world?
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
What do I still need to come fully into my power? How can others support me in this?
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Resources</h3>
|
||||||
|
The player explores and defines his/her offers and needs, shares his/her resources and
|
||||||
|
uses those of the network. E.g. tools, machines, electrical appliances, vehicles, food and
|
||||||
|
drink, places to sleep, rides, books, access to the internet, individual skills and help
|
||||||
<h3 className="text-base my-3 font-medium"> Resources</h3>
|
in everyday life
|
||||||
The player explores and defines his/her offers and needs, shares his/her resources and uses those of the network.
|
<h3 className='text-base my-3 font-medium'> Realising Projects</h3>
|
||||||
|
The player joins projects and starts his own. The game offers support in project
|
||||||
E.g. tools, machines, electrical appliances, vehicles, food and drink, places to sleep, rides, books, access to the internet, individual skills and help in everyday life
|
management or crowdfunding. In this way, structures, events, permanent places,
|
||||||
<h3 className="text-base my-3 font-medium"> Realising Projects</h3>
|
infrastructure and everything we need to meet our human needs in harmony with Mother Earth
|
||||||
|
can be created.
|
||||||
The player joins projects and starts his own.
|
<h3 className='text-base my-3 font-medium'> Making Change visible</h3>
|
||||||
|
|
||||||
The game offers support in project management or crowdfunding.
|
|
||||||
|
|
||||||
In this way, structures, events, permanent places, infrastructure and everything we need to meet our human needs in harmony with Mother Earth can be created.
|
|
||||||
<h3 className="text-base my-3 font-medium"> Making Change visible</h3>
|
|
||||||
|
|
||||||
The player is motivated to map and document the newly emerging world by ...
|
The player is motivated to map and document the newly emerging world by ...
|
||||||
<ul className="list-disc list-inside pl-4 pt-4">
|
<ul className='list-disc list-inside pl-4 pt-4'>
|
||||||
|
|
||||||
<li>adding places, events etc. to the map</li>
|
<li>adding places, events etc. to the map</li>
|
||||||
|
|
||||||
<li>documenting projects with text, images, audio and video</li>
|
<li>documenting projects with text, images, audio and video</li>
|
||||||
@ -123,106 +112,77 @@ export default function Concept() {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
|
<input type='radio' name='my-accordion-2' />
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
<div className='collapse-title text-xl font-medium'>Web of Trust </div>
|
||||||
<input type="radio" name="my-accordion-2" />
|
<div className='collapse-content'>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='flex flex-row flex-wrap'>
|
||||||
Web of Trust </div>
|
While we connect with other people in real life and build our personal network, we are
|
||||||
<div className="collapse-content">
|
simultaneously exchanging cryptographic keys and building a "Web of Trust".{' '}
|
||||||
<div className="flex flex-row flex-wrap">
|
<div className='basis-full'>
|
||||||
|
<div className='divider divider-vertical'></div>
|
||||||
While we connect with other people in real life and build our personal network, we are simultaneously exchanging cryptographic keys and building a "Web of Trust". <div className="basis-full">
|
|
||||||
<div className="divider divider-vertical"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-base basis-full my-3 font-medium"> Decentralised IDs</h3>
|
<h3 className='text-base basis-full my-3 font-medium'> Decentralised IDs</h3>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<img className='float-right h-28 px-4 pb-4' src='/public-private-key.svg'></img>
|
||||||
|
|
||||||
<img className="float-right h-28 px-4 pb-4" src="/public-private-key.svg"></img>
|
|
||||||
|
|
||||||
<p>When we create our profile, a key pair consisting of a private key and a public key is generated at the same time.</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When we create our profile, a key pair consisting of a private key and a public key
|
||||||
|
is generated at the same time.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<p className='basis-full pb-4'>
|
||||||
<p className="basis-full pb-4">We share the public key with our friends and they can use it to encrypt data for us. We keep the private key secret. It is needed to decrypt data that has been encrypted for us on our device.</p>
|
We share the public key with our friends and they can use it to encrypt data for us.
|
||||||
|
We keep the private key secret. It is needed to decrypt data that has been encrypted
|
||||||
|
for us on our device.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full">
|
<div className='basis-full'>
|
||||||
<div className="divider divider-vertical"></div>
|
<div className='divider divider-vertical'></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<h3 className='text-base my-3 font-medium'> Key Exchange</h3>
|
||||||
|
<img className='float-left h-32 px-4' src='/qr-scan.svg'></img>
|
||||||
<h3 className="text-base my-3 font-medium"> Key Exchange</h3>
|
When we meet people in real life, we can exchange our public keys by scanning each
|
||||||
<img className="float-left h-32 px-4" src="/qr-scan.svg"></img>
|
other's QR codes or on paper.{' '}
|
||||||
|
|
||||||
When we meet people in real life, we can exchange our public keys by scanning each other's QR codes or on paper. </div>
|
|
||||||
|
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
<h3 className="text-base my-3 font-medium"> Private data sharing</h3>
|
|
||||||
<img className="float-right h-32 px-4" src="/web-of-trust.svg"></img>
|
|
||||||
|
|
||||||
Within our network, we can then share our profiles, offers, needs, projects, locations and events end-to-end encrypted.
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
</div>
|
<h3 className='text-base my-3 font-medium'> Private data sharing</h3>
|
||||||
|
<img className='float-right h-32 px-4' src='/web-of-trust.svg'></img>
|
||||||
|
Within our network, we can then share our profiles, offers, needs, projects, locations
|
||||||
|
and events end-to-end encrypted.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
|
||||||
<input type="radio" name="my-accordion-2" />
|
|
||||||
<h2 className="collapse-title text-xl font-medium">
|
|
||||||
Principles </h2>
|
|
||||||
<div className="collapse-content">
|
|
||||||
<div className="flex flex-row flex-wrap">
|
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
<h3 className="text-base my-3 font-medium"> Everything is just a game</h3>
|
|
||||||
|
|
||||||
Everything happens voluntarily, out of ourselves in the flow. Everyone is invited to join in at any time.
|
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
</div>
|
||||||
<h3 className="text-base my-3 font-medium"> No Money</h3>
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
|
<input type='radio' name='my-accordion-2' />
|
||||||
|
<h2 className='collapse-title text-xl font-medium'>Principles </h2>
|
||||||
|
<div className='collapse-content'>
|
||||||
|
<div className='flex flex-row flex-wrap'>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Everything is just a game</h3>
|
||||||
|
Everything happens voluntarily, out of ourselves in the flow. Everyone is invited to
|
||||||
|
join in at any time.
|
||||||
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> No Money</h3>
|
||||||
Since the fun stops with money, we don't pay each other money when we play.
|
Since the fun stops with money, we don't pay each other money when we play.
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Decentralised Structures</h3>
|
||||||
|
All structures we create are decentralised and free of hierarchies. The same rules
|
||||||
<h3 className="text-base my-3 font-medium"> Decentralised Structures</h3>
|
apply to everyone.
|
||||||
|
</div>
|
||||||
All structures we create are decentralised and free of hierarchies. The same rules apply to everyone.
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Real Life</h3>
|
||||||
|
Real change happens in real life. We only use the internet where it directly helps to
|
||||||
|
organise real encounters.{' '}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
|
|
||||||
<h3 className="text-base my-3 font-medium"> Real Life</h3>
|
|
||||||
|
|
||||||
Real change happens in real life. We only use the internet where it directly helps to organise real encounters. </div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</CardPage>
|
</CardPage>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,130 +1,118 @@
|
|||||||
import { CardPage } from "utopia-ui"
|
import { CardPage } from 'utopia-ui'
|
||||||
|
|
||||||
|
|
||||||
export default function Concept() {
|
export default function Concept() {
|
||||||
return (
|
return (
|
||||||
<CardPage title="Concept">
|
<CardPage title='Concept'>
|
||||||
<b>Utopia Game</b> is a cooperative <b>Real Life Manifestation Game</b>. While playing, we connect with ourselves, each other and our dreams to manifest them together.<br></br><br></br>
|
<b>Utopia Game</b> is a cooperative <b>Real Life Manifestation Game</b>. While playing, we
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
connect with ourselves, each other and our dreams to manifest them together.<br></br>
|
||||||
<input type="radio" name="my-accordion-2" />
|
<br></br>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
Real-Life-Manifestations-Spiel ? </div>
|
<input type='radio' name='my-accordion-2' />
|
||||||
<div className="collapse-content">
|
<div className='collapse-title text-xl font-medium'>Real-Life-Manifestations-Spiel ? </div>
|
||||||
<div className="flex flex-row flex-wrap">
|
<div className='collapse-content'>
|
||||||
<div className="basis-full pr-4 pb-4">
|
<div className='flex flex-row flex-wrap'>
|
||||||
Ähnlich wie bei einem Rollenspiel kann man sich sein eigenes Profil erstellen, mit dem Unterschied, dass hier echte Fähigkeiten abgebildet, geteilt und trainiert werden können.
|
<div className='basis-full pr-4 pb-4'>
|
||||||
|
Ähnlich wie bei einem Rollenspiel kann man sich sein eigenes Profil erstellen, mit dem
|
||||||
|
Unterschied, dass hier echte Fähigkeiten abgebildet, geteilt und trainiert werden
|
||||||
|
können.
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full pr-4 pb-4">
|
<div className='basis-full pr-4 pb-4'>
|
||||||
Die Geschichte und das Storytelling orientiert sich an den realen Zuständen und Herausforderungen auf unserer Erde.
|
Die Geschichte und das Storytelling orientiert sich an den realen Zuständen und
|
||||||
|
Herausforderungen auf unserer Erde.
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full pr-4 pb-4">
|
<div className='basis-full pr-4 pb-4'>
|
||||||
Des weiteren werden reale Ressourcen sichtbar und verfügbar gemacht, verwaltet und eingesetzt, ähnlich wie bei einem Strategie-Spiel.
|
Des weiteren werden reale Ressourcen sichtbar und verfügbar gemacht, verwaltet und
|
||||||
|
eingesetzt, ähnlich wie bei einem Strategie-Spiel.
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full pr-4 pb-4">
|
<div className='basis-full pr-4 pb-4'>
|
||||||
Die Aufgaben des Projektmanagements können als Quests bzw. Spielaufträge abgebildet werden. Kleine und große Aufgaben werden in Abenteuer und Herausforderungen verwandelt und Probleme in Rätsel.
|
Die Aufgaben des Projektmanagements können als Quests bzw. Spielaufträge abgebildet
|
||||||
|
werden. Kleine und große Aufgaben werden in Abenteuer und Herausforderungen verwandelt
|
||||||
|
und Probleme in Rätsel.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full pr-4 pb-4">
|
<div className='basis-full pr-4 pb-4'>
|
||||||
Ziel des Spiels ist es, WinWinWin Situationen zu erzeugen. Win für Dich, Win für Uns, Win für die Welt.
|
Ziel des Spiels ist es, WinWinWin Situationen zu erzeugen. Win für Dich, Win für Uns,
|
||||||
</div>
|
Win für die Welt.
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
|
||||||
<input type="radio" name="my-accordion-2" />
|
|
||||||
<div className="collapse-title text-xl font-medium">
|
|
||||||
Elemente des Spiels </div>
|
|
||||||
<div className="collapse-content">
|
|
||||||
<div className="flex flex-row flex-wrap">
|
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
<h3 className="text-base my-3 font-medium"> App</h3>
|
|
||||||
|
|
||||||
Die App bietet eine interaktive geografische Karte als Spielfeld. Außerdem ermöglicht sie das Erstellen und Ansehen von Spieler-Profilen. Der Marktplatz zeigt Angebote und Bedürfnisse
|
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
|
<input type='radio' name='my-accordion-2' />
|
||||||
<h3 className="text-base my-3 font-medium"> Print Material</h3>
|
<div className='collapse-title text-xl font-medium'>Elemente des Spiels </div>
|
||||||
|
<div className='collapse-content'>
|
||||||
Als Ergänzung und zum Offline-Spielen gibt es Flyer, Aufkleber, Schilder und Workbooks, welche zum Spielen einladen.
|
<div className='flex flex-row flex-wrap'>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
Spieler erhalten Ausweise und Visitenkarten mit QR-Codes, die zu Vernetzung genutzt werden (später mehr)
|
<h3 className='text-base my-3 font-medium'> App</h3>
|
||||||
|
Die App bietet eine interaktive geografische Karte als Spielfeld. Außerdem ermöglicht
|
||||||
|
sie das Erstellen und Ansehen von Spieler-Profilen. Der Marktplatz zeigt Angebote und
|
||||||
|
Bedürfnisse
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Print Material</h3>
|
||||||
<h3 className="text-base my-3 font-medium"> Temporäre Events</h3>
|
Als Ergänzung und zum Offline-Spielen gibt es Flyer, Aufkleber, Schilder und
|
||||||
|
Workbooks, welche zum Spielen einladen. Spieler erhalten Ausweise und Visitenkarten
|
||||||
Wir kommen zusammen bei Workshops, auf Festivals und bei lokalen Treffen um uns zu connecten, Strukturen zu bilden und neue Spieler zu gewinnen.
|
mit QR-Codes, die zu Vernetzung genutzt werden (später mehr)
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Temporäre Events</h3>
|
||||||
<h3 className="text-base my-3 font-medium"> Dauerhafte Strukturen</h3>
|
Wir kommen zusammen bei Workshops, auf Festivals und bei lokalen Treffen um uns zu
|
||||||
|
connecten, Strukturen zu bilden und neue Spieler zu gewinnen.
|
||||||
Beim Spielen erschaffen wir dauerhafte materielle Strukturen wie Orte und Infrastruktur.
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
Und Immaterielles wie Netzwerke aus Beziehungen, Geschichten, Informationen ...
|
<h3 className='text-base my-3 font-medium'> Dauerhafte Strukturen</h3>
|
||||||
|
Beim Spielen erschaffen wir dauerhafte materielle Strukturen wie Orte und
|
||||||
|
Infrastruktur. Und Immaterielles wie Netzwerke aus Beziehungen, Geschichten,
|
||||||
|
Informationen ...
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
<input type='radio' name='my-accordion-2' />
|
||||||
<input type="radio" name="my-accordion-2" />
|
<div className='collapse-title text-xl font-medium'>Ziel des Spiels </div>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='collapse-content'>
|
||||||
Ziel des Spiels </div>
|
<ol className='list-decimal list-inside pl-4'>
|
||||||
<div className="collapse-content">
|
|
||||||
|
|
||||||
<ol className="list-decimal list-inside pl-4">
|
|
||||||
<li>Ein dezentrales Netzwerk aufspannen</li>
|
<li>Ein dezentrales Netzwerk aufspannen</li>
|
||||||
<li>Freie Entfaltung unserer kollektiven und individuellen Potentiale</li>
|
<li>Freie Entfaltung unserer kollektiven und individuellen Potentiale</li>
|
||||||
<li>Aufbau kollektiver Strukturen und Co-Kreation</li>
|
<li>Aufbau kollektiver Strukturen und Co-Kreation</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
<input type='radio' name='my-accordion-2' />
|
||||||
<input type="radio" name="my-accordion-2" />
|
<div className='collapse-title text-xl font-medium'>Ablauf </div>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='collapse-content'>
|
||||||
Ablauf </div>
|
|
||||||
<div className="collapse-content">
|
|
||||||
|
|
||||||
Durch spielerische Elemente / Gamification wird der Spieler motiviert und angeleitet ...
|
Durch spielerische Elemente / Gamification wird der Spieler motiviert und angeleitet ...
|
||||||
<h3 className="text-base my-3 font-medium"> Spieler Profile</h3>
|
<h3 className='text-base my-3 font-medium'> Spieler Profile</h3>
|
||||||
|
Der Spieler setzt sich mit sich selbst und seinen Fähigkeiten sowie tieferen Wünschen und
|
||||||
Der Spieler setzt sich mit sich selbst und seinen Fähigkeiten sowie tieferen Wünschen und Visionen auseinander und definiert seinen Charakter bzw. Spieler-Profil
|
Visionen auseinander und definiert seinen Charakter bzw. Spieler-Profil Dabei stehen
|
||||||
|
folgende Fragen im Mittelpunkt:
|
||||||
Dabei stehen folgende Fragen im Mittelpunkt:
|
<ul className='list-disc list-inside pl-4 pt-4'>
|
||||||
<ul className="list-disc list-inside pl-4 pt-4">
|
|
||||||
<li>Wie und in was für einer Welt möchte ich leben?</li>
|
<li>Wie und in was für einer Welt möchte ich leben?</li>
|
||||||
<li>Wer bin ich und was sind meine besonderen Fähigkeiten oder meine spezielle Aufgabe in diesem Leben?</li>
|
<li>
|
||||||
|
Wer bin ich und was sind meine besonderen Fähigkeiten oder meine spezielle Aufgabe in
|
||||||
|
diesem Leben?
|
||||||
|
</li>
|
||||||
<li>Was habe ich zu geben? Was kann und möchte ich mit anderen und der Welt teilen?</li>
|
<li>Was habe ich zu geben? Was kann und möchte ich mit anderen und der Welt teilen?</li>
|
||||||
<li>Was brauche ich noch um ganz in meine Kraft zu kommen? Wie können mich andere dabei unterstützen?</li>
|
<li>
|
||||||
|
Was brauche ich noch um ganz in meine Kraft zu kommen? Wie können mich andere dabei
|
||||||
|
unterstützen?
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Ressourcen</h3>
|
||||||
|
Der Spieler erforscht und definiert seine Angebote und Bedürfnisse, teilt seine Ressourcen
|
||||||
|
und nutzt die des Netzwerks Z.B. Werkzeuge, Maschinen, Elektrogeräte, Fahrzeuge, Essen und
|
||||||
|
Trinken, Schlafplätze, Mitfahrten, Bücher, Zugang zum Internet, individuelle Fähigkeiten
|
||||||
<h3 className="text-base my-3 font-medium"> Ressourcen</h3>
|
sowie Hilfe im Alltag
|
||||||
|
<h3 className='text-base my-3 font-medium'> Projekte umsetzen</h3>
|
||||||
Der Spieler erforscht und definiert seine Angebote und Bedürfnisse, teilt seine Ressourcen und nutzt die des Netzwerks
|
Der Spieler schließt sich Projekten an und startet selbst welche. Das Spiel unterstützt
|
||||||
|
beim Projektmanagement oder beim Crowdfunding So entstehen Strukturen, Veranstaltungen,
|
||||||
Z.B. Werkzeuge, Maschinen, Elektrogeräte, Fahrzeuge, Essen und Trinken, Schlafplätze, Mitfahrten, Bücher, Zugang zum Internet, individuelle Fähigkeiten sowie Hilfe im Alltag
|
dauerhafte Orte, Infrastruktur und alles was wir brauchen um unsere menschlichen
|
||||||
|
Bedürfnisse im Einklang mit Mutter Erde zu befriedigen.
|
||||||
<h3 className="text-base my-3 font-medium"> Projekte umsetzen</h3>
|
<h3 className='text-base my-3 font-medium'> Wandel sichtbar machen</h3>
|
||||||
|
Der Spieler wird motiviert die neu entstehende Welt zu kartieren und zu dokumentieren
|
||||||
Der Spieler schließt sich Projekten an und startet selbst welche.
|
indem er ...
|
||||||
|
<ul className='list-disc list-inside pl-4 pt-4'>
|
||||||
Das Spiel unterstützt beim Projektmanagement oder beim Crowdfunding
|
|
||||||
|
|
||||||
So entstehen Strukturen, Veranstaltungen, dauerhafte Orte, Infrastruktur und alles was wir brauchen um unsere menschlichen Bedürfnisse im Einklang mit Mutter Erde zu befriedigen.
|
|
||||||
|
|
||||||
<h3 className="text-base my-3 font-medium"> Wandel sichtbar machen</h3>
|
|
||||||
|
|
||||||
Der Spieler wird motiviert die neu entstehende Welt zu kartieren und zu dokumentieren indem er ...
|
|
||||||
<ul className="list-disc list-inside pl-4 pt-4">
|
|
||||||
|
|
||||||
<li>Orte, Veranstaltungen usw. in der Karte einträgt</li>
|
<li>Orte, Veranstaltungen usw. in der Karte einträgt</li>
|
||||||
|
|
||||||
<li>Projekte mit Text, Bild und Ton dokumentiert</li>
|
<li>Projekte mit Text, Bild und Ton dokumentiert</li>
|
||||||
@ -133,117 +121,83 @@ export default function Concept() {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
|
<input type='radio' name='my-accordion-2' />
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
<div className='collapse-title text-xl font-medium'>Web of Trust </div>
|
||||||
<input type="radio" name="my-accordion-2" />
|
<div className='collapse-content'>
|
||||||
<div className="collapse-title text-xl font-medium">
|
<div className='flex flex-row flex-wrap'>
|
||||||
Web of Trust </div>
|
Während wir uns mit anderen Menschen im echten Leben connecten und unser persönliches
|
||||||
<div className="collapse-content">
|
Netzwerk aufbauen, tauschen wir gleichzeitig kryptografische Schlüssel aus und bauen ein
|
||||||
<div className="flex flex-row flex-wrap">
|
sogenanntes Web of Trust.
|
||||||
|
<div className='basis-full'>
|
||||||
Während wir uns mit anderen Menschen im echten Leben connecten und unser persönliches Netzwerk aufbauen, tauschen wir gleichzeitig kryptografische Schlüssel aus und bauen ein sogenanntes Web of Trust.
|
<div className='divider divider-vertical'></div>
|
||||||
<div className="basis-full">
|
|
||||||
<div className="divider divider-vertical"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-base basis-full my-3 font-medium"> Dezentrale IDs</h3>
|
<h3 className='text-base basis-full my-3 font-medium'> Dezentrale IDs</h3>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<img className='float-right h-24 px-4' src='/public-private-key.svg'></img>
|
||||||
|
|
||||||
<img className="float-right h-24 px-4" src="/public-private-key.svg"></img>
|
|
||||||
|
|
||||||
<p>Wenn wir unser Profil erstellen wird gleichzeitig ein Schlüsselpaar bestehend aus einem privaten und einem öffentlichen Schlüssel erzeugt.</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Wenn wir unser Profil erstellen wird gleichzeitig ein Schlüsselpaar bestehend aus
|
||||||
|
einem privaten und einem öffentlichen Schlüssel erzeugt.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<p className='basis-full pb-4'>
|
||||||
<p className="basis-full pb-4">Den öffentlichen Schlüssel teilen wir mit unseren Freunden und diese können damit Daten für uns verschlüsseln.</p>
|
Den öffentlichen Schlüssel teilen wir mit unseren Freunden und diese können damit
|
||||||
|
Daten für uns verschlüsseln.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p className="basis-full">Den privaten Schlüssel halten wir geheim. Er wird benötigt um Daten die für uns verschlüsselt wurden auf unserem Gerät wieder zu entschlüsselt.</p>
|
|
||||||
|
|
||||||
|
<p className='basis-full'>
|
||||||
|
Den privaten Schlüssel halten wir geheim. Er wird benötigt um Daten die für uns
|
||||||
|
verschlüsselt wurden auf unserem Gerät wieder zu entschlüsselt.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-full">
|
<div className='basis-full'>
|
||||||
<div className="divider divider-vertical"></div>
|
<div className='divider divider-vertical'></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<h3 className='text-base my-3 font-medium'> Schlüsseltausch</h3>
|
||||||
|
<img className='float-left h-32 px-4' src='/qr-scan.svg'></img>
|
||||||
<h3 className="text-base my-3 font-medium"> Schlüsseltausch</h3>
|
Wenn wir Menschen im echten Leben begegnen tauschen wir unsere öffentlichen Schlüssel
|
||||||
<img className="float-left h-32 px-4" src="/qr-scan.svg"></img>
|
via QR-Code-Scan oder auf Papier.
|
||||||
|
|
||||||
Wenn wir Menschen im echten Leben begegnen tauschen wir unsere öffentlichen Schlüssel via QR-Code-Scan oder auf Papier.
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
<h3 className='text-base my-3 font-medium'> Private Daten teilen</h3>
|
||||||
<h3 className="text-base my-3 font-medium"> Private Daten teilen</h3>
|
<img className='float-right h-32 px-4' src='/web-of-trust.svg'></img>
|
||||||
<img className="float-right h-32 px-4" src="/web-of-trust.svg"></img>
|
Innerhalb unseres Netzwerkes können wir dann unsere Profile, Angebote, Bedürfnisse,
|
||||||
|
Projekte, Orte und Veranstaltungen ende-zu-ende-verschlüsselt teilen.
|
||||||
Innerhalb unseres Netzwerkes können wir dann unsere Profile, Angebote, Bedürfnisse, Projekte, Orte und Veranstaltungen ende-zu-ende-verschlüsselt teilen.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="collapse collapse-arrow bg-base-200 mb-2">
|
|
||||||
<input type="radio" name="my-accordion-2" />
|
|
||||||
<h2 className="collapse-title text-xl font-semibold">
|
|
||||||
Prinzipien </h2>
|
|
||||||
<div className="collapse-content">
|
|
||||||
<div className="flex flex-row flex-wrap">
|
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
<h3 className="text-base my-3 font-medium"> Alles ist nur ein Spiel</h3>
|
|
||||||
|
|
||||||
Alles passiert freiwillig, aus uns selbst heraus im Flow. Jeder ist jederzeit eingeladen mitzumachen.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
<h3 className="text-base my-3 font-medium"> Kein Geld</h3>
|
|
||||||
|
|
||||||
Da beim Geld der Spaß bekanntlich aufhört, bezahlen wir uns beim Spielen gegenseitig kein Geld.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
|
|
||||||
|
|
||||||
<h3 className="text-base my-3 font-medium"> Dezentrale Strukturen</h3>
|
|
||||||
|
|
||||||
Alle Strukturen, die wir erschaffen, gestalten wir dezentral und frei von Hierarchien. Für alle gelten die gleichen Regeln.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div className="basis-full md:basis-1/2 pr-4 pb-4">
|
|
||||||
|
|
||||||
<h3 className="text-base my-3 font-medium"> Real Life</h3>
|
|
||||||
|
|
||||||
Veränderung passiert im echten Leben. Wir nutzen das Internet nur wo es direkt hilft echte Begegnungen zu organisieren.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='collapse collapse-arrow bg-base-200 mb-2'>
|
||||||
|
<input type='radio' name='my-accordion-2' />
|
||||||
|
<h2 className='collapse-title text-xl font-semibold'>Prinzipien </h2>
|
||||||
|
<div className='collapse-content'>
|
||||||
|
<div className='flex flex-row flex-wrap'>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Alles ist nur ein Spiel</h3>
|
||||||
|
Alles passiert freiwillig, aus uns selbst heraus im Flow. Jeder ist jederzeit
|
||||||
|
eingeladen mitzumachen.
|
||||||
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Kein Geld</h3>
|
||||||
|
Da beim Geld der Spaß bekanntlich aufhört, bezahlen wir uns beim Spielen gegenseitig
|
||||||
|
kein Geld.
|
||||||
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Dezentrale Strukturen</h3>
|
||||||
|
Alle Strukturen, die wir erschaffen, gestalten wir dezentral und frei von Hierarchien.
|
||||||
|
Für alle gelten die gleichen Regeln.
|
||||||
|
</div>
|
||||||
|
<div className='basis-full md:basis-1/2 pr-4 pb-4'>
|
||||||
|
<h3 className='text-base my-3 font-medium'> Real Life</h3>
|
||||||
|
Veränderung passiert im echten Leben. Wir nutzen das Internet nur wo es direkt hilft
|
||||||
|
echte Begegnungen zu organisieren.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</CardPage>
|
</CardPage>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,195 +1,216 @@
|
|||||||
import { useEffect, useState } from 'react';
|
/* eslint-disable react/no-unescaped-entities */
|
||||||
|
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable import/no-relative-parent-imports */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||||
|
/* eslint-disable new-cap */
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { MapOverlayPage } from 'utopia-ui'
|
import { MapOverlayPage } from 'utopia-ui'
|
||||||
import { itemsApi } from '../api/itemsApi';
|
|
||||||
|
import { itemsApi } from '../api/itemsApi'
|
||||||
|
|
||||||
export const Landingpage = () => {
|
export const Landingpage = () => {
|
||||||
|
const [isLandingpageVisible, setIsLandingpageVisible] = useState(true)
|
||||||
|
const [isBoxVisible, setIsBoxVisible] = useState(true)
|
||||||
|
const [isPhoneVisible, setIsPhoneVisible] = useState(true)
|
||||||
|
|
||||||
const [isLandingpageVisible, setIsLandingpageVisible] = useState(true);
|
const [featuresApi, setFeaturesApi] = useState<itemsApi<any>>()
|
||||||
const [isBoxVisible, setIsBoxVisible] = useState(true);
|
const [features, setFeatures] = useState<any[]>()
|
||||||
const [isPhoneVisible, setIsPhoneVisible] = useState(true);
|
|
||||||
|
|
||||||
const [featuresApi, setFeaturesApi] = useState<itemsApi<any>>();
|
const [teamApi, setTeamApi] = useState<itemsApi<any>>()
|
||||||
const [features, setFeatures] = useState<any[]>();
|
const [team, setTeam] = useState<any[]>()
|
||||||
|
|
||||||
|
|
||||||
const [teamApi, setTeamApi] = useState<itemsApi<any>>();
|
|
||||||
const [team, setTeam] = useState<any[]>();
|
|
||||||
|
|
||||||
const loadFeatures = async () => {
|
const loadFeatures = async () => {
|
||||||
const items = await featuresApi?.getItems();
|
const items = await featuresApi?.getItems()
|
||||||
setFeatures(items as any);
|
setFeatures(items as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadTeam = async () => {
|
const loadTeam = async () => {
|
||||||
const items = await teamApi?.getItems();
|
const items = await teamApi?.getItems()
|
||||||
setTeam(items as any);
|
setTeam(items as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setFeaturesApi(new itemsApi<any>('features',undefined, undefined, {"status":{"_eq": "published"}}));
|
setFeaturesApi(
|
||||||
setTeamApi(new itemsApi<any>('team'));
|
new itemsApi<any>('features', undefined, undefined, { status: { _eq: 'published' } }),
|
||||||
loadTeam();
|
)
|
||||||
loadFeatures();
|
setTeamApi(new itemsApi<any>('team'))
|
||||||
|
loadTeam()
|
||||||
|
loadFeatures()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadFeatures();
|
loadFeatures()
|
||||||
}, [featuresApi])
|
}, [featuresApi])
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadTeam();
|
loadTeam()
|
||||||
}, [teamApi])
|
}, [teamApi])
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const startGame = () => {
|
const startGame = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsBoxVisible(false)
|
setIsBoxVisible(false)
|
||||||
}, 200
|
}, 200)
|
||||||
)
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsPhoneVisible(false)
|
setIsPhoneVisible(false)
|
||||||
}, 200
|
}, 200)
|
||||||
)
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsLandingpageVisible(false)
|
setIsLandingpageVisible(false)
|
||||||
}, 500
|
}, 500)
|
||||||
)
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate("/")
|
navigate('/')
|
||||||
}, 1500
|
}, 1500)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MapOverlayPage className={`!rounded-none overflow-y-auto !p-0 fadeable-div flex-none ${isLandingpageVisible ? '' : 'div-hidden'}`} card={false}>
|
<MapOverlayPage
|
||||||
<div className="hero min-h-full text-base">
|
className={`!rounded-none overflow-y-auto !p-0 fadeable-div flex-none ${isLandingpageVisible ? '' : 'div-hidden'}`}
|
||||||
<div className="hero-content text-center flex flex-col place-items-center p-0" >
|
card={false}
|
||||||
<div className='bg-no-repeat bg-center w-full' style={{ backgroundImage: "url(bg1.webp)" }}>
|
>
|
||||||
|
<div className='hero min-h-full text-base'>
|
||||||
|
<div className='hero-content text-center flex flex-col place-items-center p-0'>
|
||||||
|
<div
|
||||||
|
className='bg-no-repeat bg-center w-full'
|
||||||
|
style={{ backgroundImage: 'url(bg1.webp)' }}
|
||||||
|
>
|
||||||
<div className='min-h-[calc(100vh-60px)] flex flex-row items-center justify-center '>
|
<div className='min-h-[calc(100vh-60px)] flex flex-row items-center justify-center '>
|
||||||
<div className={`max-w-md text-center bg-black p-8 m-8 bg-opacity-50 text-white backdrop-blur-sm rounded-xl movable-div ${isBoxVisible ? '' : 'move-out-left'}`}>
|
<div
|
||||||
<h1 className="text-5xl font-bold">Utopia Game</h1>
|
className={`max-w-md text-center bg-black p-8 m-8 bg-opacity-50 text-white backdrop-blur-sm rounded-xl movable-div ${isBoxVisible ? '' : 'move-out-left'}`}
|
||||||
<p className="py-6">ist mehr als nur ein Spiel. Es ist eine Bewegung, die darauf abzielt, die Spieler aus ihren virtuellen Welten zu befreien und sie zu inspirieren, das echte Leben zu erkunden, Fähigkeiten zu entwickeln und die Welt um sie herum zu gestalten. Bist du bereit, Teil dieser Revolution zu werden? </p>
|
>
|
||||||
<div className="btn !text-white btn-primary" onClick={startGame}>Play ▶</div>
|
<h1 className='text-5xl font-bold'>Utopia Game</h1>
|
||||||
|
<p className='py-6'>
|
||||||
|
ist mehr als nur ein Spiel. Es ist eine Bewegung, die darauf abzielt, die Spieler
|
||||||
|
aus ihren virtuellen Welten zu befreien und sie zu inspirieren, das echte Leben zu
|
||||||
|
erkunden, Fähigkeiten zu entwickeln und die Welt um sie herum zu gestalten. Bist
|
||||||
|
du bereit, Teil dieser Revolution zu werden?{' '}
|
||||||
|
</p>
|
||||||
|
<div className='btn !text-white btn-primary' onClick={startGame}>
|
||||||
|
Play ▶
|
||||||
</div>
|
</div>
|
||||||
<div className={`mockup-phone m-8 hidden lg:block movable-div ${isPhoneVisible ? '' : 'move-out-right'}`}>
|
</div>
|
||||||
<div className="camera"></div>
|
<div
|
||||||
<div className="display">my-8
|
className={`mockup-phone m-8 hidden lg:block movable-div ${isPhoneVisible ? '' : 'move-out-right'}`}
|
||||||
<div className="artboard artboard-demo phone-1">
|
>
|
||||||
<iframe src="/" height={568} width={320}></iframe>
|
<div className='camera'></div>
|
||||||
|
<div className='display'>
|
||||||
|
my-8
|
||||||
|
<div className='artboard artboard-demo phone-1'>
|
||||||
|
<iframe src='/' height={568} width={320}></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<section className='min-h-[50em] p-8 flex h-full items-center justify-center'>
|
||||||
<section className="min-h-[50em] p-8 flex h-full items-center justify-center">
|
<ul className='my-8 grid gap-y-8 gap-x-12 sm:grid-cols-2 lg:grid-cols-3'>
|
||||||
<ul className="my-8 grid gap-y-8 gap-x-12 sm:grid-cols-2 lg:grid-cols-3">
|
{features?.map((item, idx) => (
|
||||||
{
|
<li key={idx} className='space-y-3'>
|
||||||
features?.map((item, idx) => (
|
<div className='w-12tw-card tw-card-body h-12 mx-auto !bg-transparent text-indigo-600 rounded-full flex items-center justify-center text-5xl'>
|
||||||
<li key={idx} className="space-y-3">
|
|
||||||
<div className="w-12tw-card tw-card-body h-12 mx-auto !bg-transparent text-indigo-600 rounded-full flex items-center justify-center text-5xl">
|
|
||||||
{item.symbol}
|
{item.symbol}
|
||||||
</div>
|
</div>
|
||||||
<h4 className="text-lg font-semibold">
|
<h4 className='text-lg font-semibold'>{item.heading}</h4>
|
||||||
{item.heading}
|
<p>{item.text}</p>
|
||||||
</h4>
|
|
||||||
<p>
|
|
||||||
{item.text}
|
|
||||||
</p>
|
|
||||||
</li>
|
</li>
|
||||||
))
|
))}
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="py-14 min-h-[40em] p-8 flex h-full items-center justify-center mb-28">
|
<section className='py-14 min-h-[40em] p-8 flex h-full items-center justify-center mb-28'>
|
||||||
<div className="max-w-screen-xl mx-auto text-center">
|
<div className='max-w-screen-xl mx-auto text-center'>
|
||||||
<div className="max-w-xl mx-auto">
|
<div className='max-w-xl mx-auto'>
|
||||||
<h3 className="text-3xl font-semibold sm:text-4xl">
|
<h3 className='text-3xl font-semibold sm:text-4xl'>Meet our team</h3>
|
||||||
Meet our team
|
<p className='mt-3'>
|
||||||
</h3>
|
Lorem Ipsum is simply dummy text of the printing and typesetting industry.Lorem
|
||||||
<p className="mt-3">
|
Ipsum has been the industry's standard dummy.
|
||||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry.Lorem Ipsum has been the industry's standard dummy.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-12">
|
<div className='mt-12'>
|
||||||
<ul className="grid gap-8 sm:grid-cols-2 md:grid-cols-3">
|
<ul className='grid gap-8 sm:grid-cols-2 md:grid-cols-3'>
|
||||||
{
|
{team?.map((item, idx) => (
|
||||||
team?.map((item, idx) => (
|
|
||||||
<li key={idx}>
|
<li key={idx}>
|
||||||
<div className="w-24 h-24 mx-auto">
|
<div className='w-24 h-24 mx-auto'>
|
||||||
<img
|
<img
|
||||||
src={`https://api.utopia-lab.org/assets/${item.image}`}
|
src={`https://api.utopia-lab.org/assets/${item.image}`}
|
||||||
className="w-full h-full rounded-full"
|
className='w-full h-full rounded-full'
|
||||||
alt=""
|
alt=''
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2">
|
<div className='mt-2'>
|
||||||
<h4 className="font-semibold sm:text-lg">{item.name}</h4>
|
<h4 className='font-semibold sm:text-lg'>{item.name}</h4>
|
||||||
<p className="text-indigo-600">{item.role}</p>
|
<p className='text-indigo-600'>{item.role}</p>
|
||||||
<p className="mt-2">{item.text}</p>
|
<p className='mt-2'>{item.text}</p>
|
||||||
<div className="mt-4 flex justify-center gap-4">
|
<div className='mt-4 flex justify-center gap-4'></div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
))
|
))}
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer className="text-gray-500 bg-base-200 px-4 py-5 w-full mx-auto md:px-8 text-base">
|
<footer className='text-gray-500 bg-base-200 px-4 py-5 w-full mx-auto md:px-8 text-base'>
|
||||||
|
<div className='mt-8 items-center justify-center flex'>
|
||||||
<div className="mt-8 items-center justify-center flex">
|
<div className='mt-6 sm:mt-0'>
|
||||||
|
<ul className='flex items-center space-x-4'>
|
||||||
<div className="mt-6 sm:mt-0">
|
<li className='w-8 h-8 border-current bg-white rounded-full flex items-center justify-center'>
|
||||||
<ul className="flex items-center space-x-4">
|
<a href='https://t.me/UtopiaMap'>
|
||||||
|
<svg
|
||||||
|
stroke='currentColor'
|
||||||
<li className="w-8 h-8 border-current bg-white rounded-full flex items-center justify-center">
|
fill='#1d93d2'
|
||||||
<a href="https://t.me/UtopiaMap">
|
strokeWidth='0'
|
||||||
<svg stroke="currentColor" fill="#1d93d2" strokeWidth="0" viewBox="0 0 512 512" height="1.4rem" width="1.4rem" xmlns="http://www.w3.org/2000/svg"><path d="M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z"></path></svg>
|
viewBox='0 0 512 512'
|
||||||
</a>
|
height='1.4rem'
|
||||||
</li>
|
width='1.4rem'
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
<li className="w-8 h-8 border-current bg-white rounded-full flex items-center justify-center">
|
>
|
||||||
<a href="mailto:hello@utopia-lab.org">
|
<path d='M446.7 98.6l-67.6 318.8c-5.1 22.5-18.4 28.1-37.3 17.5l-103-75.9-49.7 47.8c-5.5 5.5-10.1 10.1-20.7 10.1l7.4-104.9 190.9-172.5c8.3-7.4-1.8-11.5-12.9-4.1L117.8 284 16.2 252.2c-22.1-6.9-22.5-22.1 4.6-32.7L418.2 66.4c18.4-6.9 34.5 4.1 28.5 32.2z'></path>
|
||||||
<svg stroke="currentColor" fill="#333" strokeWidth="0" viewBox="0 0 24 24" height="1.25rem" width="1.25rem" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4-8 5-8-5V6l8 5 8-5v2z"></path></svg> </a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li className="w-8 h-8 border-current bg-white rounded-full flex items-center justify-center">
|
|
||||||
<a href="https://twitter.com/UtopiaMapGame/" className='text-white'>
|
|
||||||
<svg className="svg-icon w-[1.4rem] h-[1.4rem] text-[#1d93d2]" viewBox="0 0 20 20">
|
|
||||||
<path fill="currentColor" d="M18.258,3.266c-0.693,0.405-1.46,0.698-2.277,0.857c-0.653-0.686-1.586-1.115-2.618-1.115c-1.98,0-3.586,1.581-3.586,3.53c0,0.276,0.031,0.545,0.092,0.805C6.888,7.195,4.245,5.79,2.476,3.654C2.167,4.176,1.99,4.781,1.99,5.429c0,1.224,0.633,2.305,1.596,2.938C2.999,8.349,2.445,8.19,1.961,7.925C1.96,7.94,1.96,7.954,1.96,7.97c0,1.71,1.237,3.138,2.877,3.462c-0.301,0.08-0.617,0.123-0.945,0.123c-0.23,0-0.456-0.021-0.674-0.062c0.456,1.402,1.781,2.422,3.35,2.451c-1.228,0.947-2.773,1.512-4.454,1.512c-0.291,0-0.575-0.016-0.855-0.049c1.588,1,3.473,1.586,5.498,1.586c6.598,0,10.205-5.379,10.205-10.045c0-0.153-0.003-0.305-0.01-0.456c0.7-0.499,1.308-1.12,1.789-1.827c-0.644,0.28-1.334,0.469-2.06,0.555C17.422,4.782,17.99,4.091,18.258,3.266"></path>
|
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li className='w-8 h-8 border-current bg-white rounded-full flex items-center justify-center'>
|
||||||
|
<a href='mailto:hello@utopia-lab.org'>
|
||||||
|
<svg
|
||||||
|
stroke='currentColor'
|
||||||
|
fill='#333'
|
||||||
|
strokeWidth='0'
|
||||||
|
viewBox='0 0 24 24'
|
||||||
|
height='1.25rem'
|
||||||
|
width='1.25rem'
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
>
|
||||||
|
<path fill='none' d='M0 0h24v24H0z'></path>
|
||||||
|
<path d='M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4-8 5-8-5V6l8 5 8-5v2z'></path>
|
||||||
|
</svg>{' '}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li className='w-8 h-8 border-current bg-white rounded-full flex items-center justify-center'>
|
||||||
|
<a href='https://twitter.com/UtopiaMapGame/' className='text-white'>
|
||||||
|
<svg
|
||||||
|
className='svg-icon w-[1.4rem] h-[1.4rem] text-[#1d93d2]'
|
||||||
|
viewBox='0 0 20 20'
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill='currentColor'
|
||||||
|
d='M18.258,3.266c-0.693,0.405-1.46,0.698-2.277,0.857c-0.653-0.686-1.586-1.115-2.618-1.115c-1.98,0-3.586,1.581-3.586,3.53c0,0.276,0.031,0.545,0.092,0.805C6.888,7.195,4.245,5.79,2.476,3.654C2.167,4.176,1.99,4.781,1.99,5.429c0,1.224,0.633,2.305,1.596,2.938C2.999,8.349,2.445,8.19,1.961,7.925C1.96,7.94,1.96,7.954,1.96,7.97c0,1.71,1.237,3.138,2.877,3.462c-0.301,0.08-0.617,0.123-0.945,0.123c-0.23,0-0.456-0.021-0.674-0.062c0.456,1.402,1.781,2.422,3.35,2.451c-1.228,0.947-2.773,1.512-4.454,1.512c-0.291,0-0.575-0.016-0.855-0.049c1.588,1,3.473,1.586,5.498,1.586c6.598,0,10.205-5.379,10.205-10.045c0-0.153-0.003-0.305-0.01-0.456c0.7-0.499,1.308-1.12,1.789-1.827c-0.644,0.28-1.334,0.469-2.06,0.555C17.422,4.782,17.99,4.091,18.258,3.266'
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex item s-center justify-center">
|
<div className='mt-8 flex item s-center justify-center'>© 2024</div>
|
||||||
|
|
||||||
© 2024
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
</MapOverlayPage>
|
</MapOverlayPage>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,104 +1,145 @@
|
|||||||
import { UtopiaMap, Layer, ItemView, PopupButton, StartEndView, TextView, ItemForm, PopupStartEndInput, PopupTextAreaInput, PopupTextInput, LayerProps } from 'utopia-ui'
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||||
import { itemsApi } from '../api/itemsApi';
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { Place } from '../api/directus';
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import { useEffect, useState } from 'react';
|
/* eslint-disable import/no-relative-parent-imports */
|
||||||
|
/* eslint-disable array-callback-return */
|
||||||
|
/* eslint-disable new-cap */
|
||||||
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import {
|
||||||
|
UtopiaMap,
|
||||||
|
Layer,
|
||||||
|
ItemView,
|
||||||
|
PopupButton,
|
||||||
|
StartEndView,
|
||||||
|
TextView,
|
||||||
|
ItemForm,
|
||||||
|
PopupStartEndInput,
|
||||||
|
PopupTextAreaInput,
|
||||||
|
PopupTextInput,
|
||||||
|
} from 'utopia-ui'
|
||||||
|
|
||||||
type layerApi = {
|
import { itemsApi } from '../api/itemsApi'
|
||||||
id: string;
|
|
||||||
|
import type { Place } from '../api/directus'
|
||||||
|
import type { LayerProps } from 'utopia-ui'
|
||||||
|
|
||||||
|
interface layerApi {
|
||||||
|
id: string
|
||||||
api: itemsApi<Place>
|
api: itemsApi<Place>
|
||||||
}
|
}
|
||||||
|
|
||||||
function MapContainer({ layers, map }: { layers: Array<LayerProps>, map: any }) {
|
function MapContainer({ layers, map }: { layers: LayerProps[]; map: any }) {
|
||||||
const [apis, setApis] = useState<Array<layerApi>>([]);
|
const [apis, setApis] = useState<layerApi[]>([])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// get timestamp for the end of the current day
|
// get timestamp for the end of the current day
|
||||||
let now = new Date();
|
const now = new Date()
|
||||||
let startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate())
|
||||||
let etartOfDayISO = startOfDay.toISOString();
|
const etartOfDayISO = startOfDay.toISOString()
|
||||||
|
|
||||||
layers.map((layer: LayerProps) => {
|
layers.map((layer: LayerProps) => {
|
||||||
apis && setApis(current => [...current, {
|
apis &&
|
||||||
id: layer.id!, api: new itemsApi<Place>('items', layer.id, undefined, {
|
setApis((current) => [
|
||||||
"_or": [
|
...current,
|
||||||
{
|
{
|
||||||
"end": {
|
id: layer.id!,
|
||||||
"_gt": etartOfDayISO
|
api: new itemsApi<Place>('items', layer.id, undefined, {
|
||||||
}
|
_or: [
|
||||||
|
{
|
||||||
|
end: {
|
||||||
|
_gt: etartOfDayISO,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"end": {
|
end: {
|
||||||
"_null": true
|
_null: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
}),
|
||||||
)
|
},
|
||||||
}])
|
])
|
||||||
})
|
})
|
||||||
}, [layers])
|
}, [layers])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {}, [apis])
|
||||||
}, [apis])
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<UtopiaMap
|
<UtopiaMap
|
||||||
geo={map.geo}
|
geo={map.geo}
|
||||||
zoom={map.zoom || 5}
|
zoom={map.zoom || 5}
|
||||||
center={map.center ? [map.center?.coordinates[1], map.center?.coordinates[0]] : [50.6, 9.5]}
|
center={map.center ? [map.center?.coordinates[1], map.center?.coordinates[0]] : [50.6, 9.5]}
|
||||||
height='100%'
|
height='100%'
|
||||||
width="100%"
|
width='100%'
|
||||||
showFilterControl={map.show_filter_control}
|
showFilterControl={map.show_filter_control}
|
||||||
showLayerControl={map.show_layer_control}
|
showLayerControl={map.show_layer_control}
|
||||||
showGratitudeControl={map.show_gratitude_control}
|
showGratitudeControl={map.show_gratitude_control}
|
||||||
donationWidget = {map.donation_widget}
|
donationWidget={map.donation_widget}
|
||||||
>
|
>
|
||||||
{layers && apis &&
|
{layers &&
|
||||||
layers.map(layer =>
|
apis &&
|
||||||
|
layers.map((layer) => (
|
||||||
<Layer
|
<Layer
|
||||||
id={layer.id}
|
id={layer.id}
|
||||||
key={layer.id}
|
key={layer.id}
|
||||||
name={layer.name}
|
name={layer.name}
|
||||||
menuIcon={"https://api.utopia-lab.org/assets/" + layer.menuIcon}
|
menuIcon={'https://api.utopia-lab.org/assets/' + layer.menuIcon}
|
||||||
menuText={layer.menuText}
|
menuText={layer.menuText}
|
||||||
menuColor={layer.menuColor}
|
menuColor={layer.menuColor}
|
||||||
markerIcon={layer.markerIcon}
|
markerIcon={layer.markerIcon}
|
||||||
markerShape={layer.markerShape}
|
markerShape={layer.markerShape}
|
||||||
userProfileLayer={layer.userProfileLayer}
|
userProfileLayer={layer.userProfileLayer}
|
||||||
markerDefaultColor={layer.menuColor}
|
markerDefaultColor={layer.menuColor}
|
||||||
markerDefaultColor2={layer.markerDefaultColor2 ? layer.markerDefaultColor2 : "RGBA(35, 31, 32, 0.2)"}
|
markerDefaultColor2={
|
||||||
|
layer.markerDefaultColor2 ? layer.markerDefaultColor2 : 'RGBA(35, 31, 32, 0.2)'
|
||||||
|
}
|
||||||
itemType={layer.itemType}
|
itemType={layer.itemType}
|
||||||
customEditLink='/edit-item'
|
customEditLink='/edit-item'
|
||||||
customEditParameter='id'
|
customEditParameter='id'
|
||||||
public_edit_items={layer.public_edit_items}
|
public_edit_items={layer.public_edit_items}
|
||||||
listed={layer.listed}
|
listed={layer.listed}
|
||||||
api={apis?.find(api => api.id === layer.id)?.api}>
|
api={apis.find((api) => api.id === layer.id)?.api}
|
||||||
|
>
|
||||||
<ItemView>
|
<ItemView>
|
||||||
{layer.itemType.show_start_end &&
|
{layer.itemType.show_start_end && <StartEndView></StartEndView>}
|
||||||
<StartEndView></StartEndView>
|
{layer.itemType.show_profile_button && (
|
||||||
}
|
|
||||||
{layer.itemType.show_profile_button &&
|
|
||||||
<PopupButton url={'/item'} parameterField={'id'} text={'Profile'} />
|
<PopupButton url={'/item'} parameterField={'id'} text={'Profile'} />
|
||||||
}
|
)}
|
||||||
{layer.itemType.show_text &&
|
{layer.itemType.show_text && <TextView truncate></TextView>}
|
||||||
<TextView truncate></TextView>
|
|
||||||
}
|
|
||||||
</ItemView>
|
</ItemView>
|
||||||
<ItemForm>
|
<ItemForm>
|
||||||
{layer.itemType.show_name_input && <PopupTextInput dataField='name' placeholder='Name'></PopupTextInput>}
|
{layer.itemType.show_name_input && (
|
||||||
|
<PopupTextInput dataField='name' placeholder='Name'></PopupTextInput>
|
||||||
|
)}
|
||||||
{layer.itemType.show_start_end_input && <PopupStartEndInput></PopupStartEndInput>}
|
{layer.itemType.show_start_end_input && <PopupStartEndInput></PopupStartEndInput>}
|
||||||
{layer.itemType.show_text_input && <div className='mt-4'><PopupTextAreaInput dataField='text' placeholder={'Text ...'} style="tw-h-40"></PopupTextAreaInput></div>}
|
{layer.itemType.show_text_input && (
|
||||||
{//layer.public_edit_items && <PopupCheckboxInput dataField={'public_edit'} label={'public edit'}/>
|
<div className='mt-4'>
|
||||||
|
<PopupTextAreaInput
|
||||||
|
dataField='text'
|
||||||
|
placeholder={'Text ...'}
|
||||||
|
style='tw-h-40'
|
||||||
|
></PopupTextAreaInput>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{
|
||||||
|
// layer.public_edit_items && <PopupCheckboxInput dataField={'public_edit'} label={'public edit'}/>
|
||||||
}
|
}
|
||||||
{layer.itemType.custom_text && <div className='flex justify-center'>
|
{layer.itemType.custom_text && (
|
||||||
|
<div className='flex justify-center'>
|
||||||
<p>{layer.itemType.custom_text}</p>
|
<p>{layer.itemType.custom_text}</p>
|
||||||
</div>}
|
</div>
|
||||||
{layer.item_presets && Object.entries(layer.item_presets).map((ip: any) => <input key={ip[0]} type="hidden" id={ip[0]} name={ip[0]} value={ip[1]} />)}
|
)}
|
||||||
|
{layer.item_presets &&
|
||||||
|
Object.entries(layer.item_presets).map((ip: any) => (
|
||||||
|
<input key={ip[0]} type='hidden' id={ip[0]} name={ip[0]} value={ip[1]} />
|
||||||
|
))}
|
||||||
</ItemForm>
|
</ItemForm>
|
||||||
</Layer>)
|
</Layer>
|
||||||
}
|
))}
|
||||||
</UtopiaMap>
|
</UtopiaMap>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,129 +1,115 @@
|
|||||||
import { Item, Tag } from "utopia-ui";
|
import type { Item, Tag } from 'utopia-ui'
|
||||||
|
|
||||||
export const tags : Tag[] = [
|
export const tags: Tag[] = [
|
||||||
{
|
{
|
||||||
"id": "423423423423",
|
id: '423423423423',
|
||||||
"name": "Activism",
|
name: 'Activism',
|
||||||
"color": "#6d398b"
|
color: '#6d398b',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4234423",
|
id: '4234423',
|
||||||
"name": "Art",
|
name: 'Art',
|
||||||
"color": "#fdc60b"
|
color: '#fdc60b',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4231223423",
|
id: '4231223423',
|
||||||
"name": "Community",
|
name: 'Community',
|
||||||
"color": "#FFA439"
|
color: '#FFA439',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "429803423423",
|
id: '429803423423',
|
||||||
"name": "Culture",
|
name: 'Culture',
|
||||||
"color": "#f18e1c"
|
color: '#f18e1c',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "42423423",
|
id: '42423423',
|
||||||
"name": "Education",
|
name: 'Education',
|
||||||
"color": "#444e99"
|
color: '#444e99',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4565654423",
|
id: '4565654423',
|
||||||
"name": "Gardening",
|
name: 'Gardening',
|
||||||
"color": "#008e5b"
|
color: '#008e5b',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4234gfh423",
|
id: '4234gfh423',
|
||||||
"name": "Healing",
|
name: 'Healing',
|
||||||
"color": "#c4037d"
|
color: '#c4037d',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "4223423",
|
id: '4223423',
|
||||||
"name": "Market",
|
name: 'Market',
|
||||||
"color": "#2a71b0"
|
color: '#2a71b0',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "42342gd3423",
|
id: '42342gd3423',
|
||||||
"name": "Nature",
|
name: 'Nature',
|
||||||
"color": "#8cbb26"
|
color: '#8cbb26',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "423123423",
|
id: '423123423',
|
||||||
"name": "Technology",
|
name: 'Technology',
|
||||||
"color": "#0696bb"
|
color: '#0696bb',
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const events : Item[] = [
|
export const events: Item[] = [
|
||||||
|
{
|
||||||
|
id: '243253f3645643',
|
||||||
|
name: 'Vollmondtrommeln',
|
||||||
|
text: 'Zu den Vollmonden vom März bis Oktober treffen sich traditionell Menschen zum gemeinsamen Musizieren, Tanzen, Spielen, Grillen und Entspannen am Gerloser Häuschen im Niesiger Wald.\r\n\r\nUhrzeit: immer ab 17 Uhr\r\n\r\nhttps://trommeln-fulda.de/vollmondtrommeln/',
|
||||||
|
position: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: [9.667615, 50.588632],
|
||||||
|
},
|
||||||
|
start: '2022-03-18T12:00:00',
|
||||||
|
end: '2022-10-08T12:00:00',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'fsdfsdfsdfsdfdse',
|
||||||
|
name: 'anderes Event',
|
||||||
|
text: 'Zu den Vollmonden vom März bis Oktober treffen sich traditionell Menschen zum gemeinsamen Musizieren, Tanzen, Spielen, Grillen und Entspannen am Gerloser Häuschen im Niesiger Wald.\r\n\r\nUhrzeit: immer ab 17 Uhr\r\n\r\nhttps://trommeln-fulda.de/vollmondtrommeln/',
|
||||||
|
position: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: [9.68, 50.59],
|
||||||
|
},
|
||||||
|
start: '2022-03-18T12:00:00',
|
||||||
|
end: '2022-10-08T12:00:00',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const places: Item[] = [
|
||||||
{
|
{
|
||||||
"id": "243253f3645643",
|
id: '1asdasdasd',
|
||||||
"name": "Vollmondtrommeln",
|
name: 'Gärtnerei am Leisebach',
|
||||||
"text": "Zu den Vollmonden vom März bis Oktober treffen sich traditionell Menschen zum gemeinsamen Musizieren, Tanzen, Spielen, Grillen und Entspannen am Gerloser Häuschen im Niesiger Wald.\r\n\r\nUhrzeit: immer ab 17 Uhr\r\n\r\nhttps://trommeln-fulda.de/vollmondtrommeln/",
|
text: 'Wir sind eine Bio-Gemüsegärtnerei und suchen noch fleißige Helfer für diese Saison.',
|
||||||
"position": {
|
position: {
|
||||||
"type": "Point",
|
type: 'Point',
|
||||||
"coordinates": [
|
coordinates: [8.476371, 51.0044],
|
||||||
9.667615,
|
|
||||||
50.588632
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"start": "2022-03-18T12:00:00",
|
date_created: '2021-04-15T07:46:26.906Z',
|
||||||
"end": "2022-10-08T12:00:00",
|
date_updated: '2021-04-15T07:46:26.906Z',
|
||||||
}, {
|
|
||||||
"id": "fsdfsdfsdfsdfdse",
|
|
||||||
"name": "anderes Event",
|
|
||||||
"text": "Zu den Vollmonden vom März bis Oktober treffen sich traditionell Menschen zum gemeinsamen Musizieren, Tanzen, Spielen, Grillen und Entspannen am Gerloser Häuschen im Niesiger Wald.\r\n\r\nUhrzeit: immer ab 17 Uhr\r\n\r\nhttps://trommeln-fulda.de/vollmondtrommeln/",
|
|
||||||
"position": {
|
|
||||||
"type": "Point",
|
|
||||||
"coordinates": [
|
|
||||||
9.68,
|
|
||||||
50.59
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"start": "2022-03-18T12:00:00",
|
|
||||||
"end": "2022-10-08T12:00:00",
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export const places : Item[] = [
|
|
||||||
{
|
|
||||||
"id": "1asdasdasd",
|
|
||||||
"name": "Gärtnerei am Leisebach",
|
|
||||||
"text": "Wir sind eine Bio-Gemüsegärtnerei und suchen noch fleißige Helfer für diese Saison.",
|
|
||||||
"position": {
|
|
||||||
"type": "Point",
|
|
||||||
"coordinates": [
|
|
||||||
8.476371,
|
|
||||||
51.0044
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"date_created": "2021-04-15T07:46:26.906Z",
|
|
||||||
"date_updated": "2021-04-15T07:46:26.906Z"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "adsasdas2",
|
id: 'adsasdas2',
|
||||||
"name": "Rainbow Crystal Land",
|
name: 'Rainbow Crystal Land',
|
||||||
"text": "https://rainbowcrystal.land",
|
text: 'https://rainbowcrystal.land',
|
||||||
"position": {
|
position: {
|
||||||
"type": "Point",
|
type: 'Point',
|
||||||
"coordinates": [
|
coordinates: [-76.367426, 1.87],
|
||||||
-76.367426,
|
|
||||||
1.87
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"date_created": "2021-04-04T18:01:24.596Z",
|
date_created: '2021-04-04T18:01:24.596Z',
|
||||||
"date_updated": "2021-04-04T18:01:24.596Z"
|
date_updated: '2021-04-04T18:01:24.596Z',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "f345v34",
|
id: 'f345v34',
|
||||||
"name": "🌈 RainbowCrystaleARThshipKinderGarten",
|
name: '🌈 RainbowCrystaleARThshipKinderGarten',
|
||||||
"text": "AMYTIME WELCOME HOME\r\n\r\n#lebenliebenlernen\r\n#symbioticsynergysolutions\r\n#lebenlanglachen\r\n#soriendosiempresaludpazyamor\r\n#laughinglearninglivingloving\r\n#souriresantétoujoursamoure\r\n\r\n\r\n<b>Garden IntroductionVideo</b>\r\n<br>\r\n\r\n\r\n<iframe width='250' src='https://www.youtube-nocookie.com/embed/7jUaixJGK08' title='YouTube video player' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>",
|
text: "AMYTIME WELCOME HOME\r\n\r\n#lebenliebenlernen\r\n#symbioticsynergysolutions\r\n#lebenlanglachen\r\n#soriendosiempresaludpazyamor\r\n#laughinglearninglivingloving\r\n#souriresantétoujoursamoure\r\n\r\n\r\n<b>Garden IntroductionVideo</b>\r\n<br>\r\n\r\n\r\n<iframe width='250' src='https://www.youtube-nocookie.com/embed/7jUaixJGK08' title='YouTube video player' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>",
|
||||||
"position": {
|
position: {
|
||||||
"type": "Point",
|
type: 'Point',
|
||||||
"coordinates": [
|
coordinates: [9.502648, 51.334741],
|
||||||
9.502648,
|
|
||||||
51.334741
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"date_created": "2022-03-13T23:09:56.305Z",
|
date_created: '2022-03-13T23:09:56.305Z',
|
||||||
"date_updated": "2022-03-13T23:09:56.305Z"
|
date_updated: '2022-03-13T23:09:56.305Z',
|
||||||
}]
|
},
|
||||||
|
]
|
||||||
|
|||||||
@ -1,22 +1,17 @@
|
|||||||
import { MapIcon } from '@heroicons/react/24/outline'
|
import { MapIcon } from '@heroicons/react/24/outline'
|
||||||
|
|
||||||
|
|
||||||
export const routes = [
|
export const routes = [
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
icon: <MapIcon style={{width: 24 }}/>,
|
icon: <MapIcon style={{ width: 24 }} />,
|
||||||
name: 'Map',
|
name: 'Map',
|
||||||
}/**
|
} /**
|
||||||
{
|
{
|
||||||
path: '/people', // url
|
path: '/people', // url
|
||||||
icon: <UsersIcon style={{width: 24 }}/>, // icon component
|
icon: <UsersIcon style={{width: 24 }}/>, // icon component
|
||||||
name: 'People', // name that appear in Sidebar
|
name: 'People', // name that appear in Sidebar
|
||||||
}, */,
|
}, */,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
path: '', //no url needed as this has submenu
|
path: '', //no url needed as this has submenu
|
||||||
@ -44,21 +39,29 @@ export const routes = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export const getBottomRoutes = (currentUrl: string) => {
|
export const getBottomRoutes = (currentUrl: string) => {
|
||||||
const url = new URL(currentUrl);
|
const url = new URL(currentUrl)
|
||||||
const isEmbedded = url.searchParams.get('embedded') === 'true';
|
const isEmbedded = url.searchParams.get('embedded') === 'true'
|
||||||
|
|
||||||
const bottomRoutes = [
|
const bottomRoutes = [
|
||||||
// Other routes can be added here
|
// Other routes can be added here
|
||||||
];
|
]
|
||||||
|
|
||||||
if (!isEmbedded) {
|
if (!isEmbedded) {
|
||||||
bottomRoutes.push({
|
bottomRoutes.push({
|
||||||
path: 'https://github.com/utopia-os/utopia-ui', // url
|
path: 'https://github.com/utopia-os/utopia-ui', // url
|
||||||
icon: <svg viewBox="0 0 24 24" aria-hidden="true" className="tw-h-6 tw-w-6" stroke="currentColor"><path fillRule="evenodd" clipRule="evenodd" d="M12 2C6.477 2 2 6.463 2 11.97c0 4.404 2.865 8.14 6.839 9.458.5.092.682-.216.682-.48 0-.236-.008-.864-.013-1.695-2.782.602-3.369-1.337-3.369-1.337-.454-1.151-1.11-1.458-1.11-1.458-.908-.618.069-.606.069-.606 1.003.07 1.531 1.027 1.531 1.027.892 1.524 2.341 1.084 2.91.828.092-.643.35-1.083.636-1.332-2.22-.251-4.555-1.107-4.555-4.927 0-1.088.39-1.979 1.029-2.675-.103-.252-.446-1.266.098-2.638 0 0 .84-.268 2.75 1.022A9.607 9.607 0 0 1 12 6.82c.85.004 1.705.114 2.504.336 1.909-1.29 2.747-1.022 2.747-1.022.546 1.372.202 2.386.1 2.638.64.696 1.028 1.587 1.028 2.675 0 3.83-2.339 4.673-4.566 4.92.359.307.678.915.678 1.846 0 1.332-.012 2.407-.012 2.734 0 .267.18.577.688.48 3.97-1.32 6.833-5.054 6.833-9.458C22 6.463 17.522 2 12 2Z"></path></svg>,
|
icon: (
|
||||||
|
<svg viewBox='0 0 24 24' aria-hidden='true' className='tw-h-6 tw-w-6' stroke='currentColor'>
|
||||||
|
<path
|
||||||
|
fillRule='evenodd'
|
||||||
|
clipRule='evenodd'
|
||||||
|
d='M12 2C6.477 2 2 6.463 2 11.97c0 4.404 2.865 8.14 6.839 9.458.5.092.682-.216.682-.48 0-.236-.008-.864-.013-1.695-2.782.602-3.369-1.337-3.369-1.337-.454-1.151-1.11-1.458-1.11-1.458-.908-.618.069-.606.069-.606 1.003.07 1.531 1.027 1.531 1.027.892 1.524 2.341 1.084 2.91.828.092-.643.35-1.083.636-1.332-2.22-.251-4.555-1.107-4.555-4.927 0-1.088.39-1.979 1.029-2.675-.103-.252-.446-1.266.098-2.638 0 0 .84-.268 2.75 1.022A9.607 9.607 0 0 1 12 6.82c.85.004 1.705.114 2.504.336 1.909-1.29 2.747-1.022 2.747-1.022.546 1.372.202 2.386.1 2.638.64.696 1.028 1.587 1.028 2.675 0 3.83-2.339 4.673-4.566 4.92.359.307.678.915.678 1.846 0 1.332-.012 2.407-.012 2.734 0 .267.18.577.688.48 3.97-1.32 6.833-5.054 6.833-9.458C22 6.463 17.522 2 12 2Z'
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
name: 'Github', // name that appear in Sidebar
|
name: 'Github', // name that appear in Sidebar
|
||||||
blank: true
|
blank: true,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return bottomRoutes;
|
return bottomRoutes
|
||||||
};
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
export default {
|
export default {
|
||||||
content: ["./src/**/*.{html,js,jsx,tsx,ts}"],
|
content: ['./src/**/*.{html,js,jsx,tsx,ts}'],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
// that is animation class
|
// that is animation class
|
||||||
@ -9,9 +9,8 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [import("daisyui")],
|
plugins: [import('daisyui')],
|
||||||
daisyui: {
|
daisyui: {
|
||||||
themes: ["light", "dark", "cupcake", "retro", "cyberpunk", "aqua"]
|
themes: ['light', 'dark', 'cupcake', 'retro', 'cyberpunk', 'aqua'],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user