attestation form and profile experiments

This commit is contained in:
Anton Tranelis 2024-07-26 13:05:44 +02:00
parent 5e38215038
commit c3b074f22c
12 changed files with 340 additions and 186 deletions

View File

@ -1,10 +1,6 @@
{
"name": "utopia-ui",
<<<<<<< HEAD
"version": "3.0.0-alpha.204",
=======
"version": "3.0.0-alpha.215",
>>>>>>> 8dc8779fe58040fb5c2a763d6519e57ddffc7ab7
"description": "Reuseable React Components to build mapping apps for real life communities and networks",
"repository": "https://github.com/utopia-os/utopia-ui",
"homepage:": "https://utopia-os.org/",

View File

@ -0,0 +1,25 @@
import { useNavigate } from "react-router-dom"
export const GratitudeControl = () => {
const navigate = useNavigate();
return (
<div className="tw-card tw-bg-base-100 tw-shadow-xl tw-mt-2 tw-w-fit">
{
<div className="tw-card-body hover:tw-bg-slate-300 tw-card tw-p-2 tw-h-10 tw-w-10 tw-transition-all tw-duration-300 hover:tw-cursor-pointer" onClick={() => {
navigate("/select-user")
}}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={2.5} stroke="currentColor" className="size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12Z" />
</svg>
</div>
}
</div>
)
}

View File

@ -20,6 +20,7 @@ import {FilterControl} from "./Subcomponents/Controls/FilterControl";
import {LayerControl} from "./Subcomponents/Controls/LayerControl";
import { useLayers } from "./hooks/useLayers";
import { useAddVisibleLayer } from "./hooks/useFilter";
import { GratitudeControl } from "./Subcomponents/Controls/GratitudeControl";
// for refreshing map on resize (needs to be implemented)
const mapDivRef = React.createRef();
@ -60,21 +61,13 @@ function UtopiaMap({
const selectNewItemPosition = useSelectPosition();
const setSelectNewItemPosition = useSetSelectPosition();
const location = useLocation();
const setClusterRef = useSetClusterRef();
const clusterRef = useClusterRef();
const setMapClicked = useSetMapClicked();
const [itemFormPopup, setItemFormPopup] = useState<ItemFormPopupProps | null>(null);
const [embedded, setEmbedded] = useState<boolean>(true)
useEffect(() => {
let params = new URLSearchParams(location.search);
let urlPosition = params.get("position");
let embedded = params.get("embedded");
embedded != "true" && setEmbedded(false)
}, [location]);
const layers = useLayers();
@ -110,6 +103,7 @@ function UtopiaMap({
{showFilterControl && <FilterControl/>}
{/*todo: needed layer handling is located LayerControl*/}
{showLayerControl && <LayerControl></LayerControl>}
{<GratitudeControl/>}
</Control>
<TileLayer
maxZoom={19}

View File

@ -23,56 +23,6 @@ export const TabsForm = ({ item, state, setState, updatePermission, linkItem, un
navigate(location.pathname+ "?" + params.toString());
}
const attestations = [{
from: "Timo",
avatar: "https://api.utopia-lab.org/assets/262117f8-feb6-444f-9bd2-e84087285760?width=80&heigth=80",
symbol: "🥇",
text: "1. Platz im Bogenschießen",
date: "21.06.2024",
},
{
from: "Sebastian",
avatar: "https://api.utopia-lab.org/assets/7510a082-882b-41c3-aa7d-5a19f9502f25?width=80&heigth=80",
symbol: "🌱",
text: "danke fürs Rasen mähen",
date: "29.06.2024",
},
{
from: "Yurij",
avatar: "https://api.utopia-lab.org/assets/abe62291-35ad-45de-b978-e5906d8a3eb6?width=80&heigth=80",
symbol: "🏆",
text: "bester Coder ever",
date: "04.07.2024",
},
{
from: "Luca",
avatar: "https://api.utopia-lab.org/assets/e285e653-36e8-4211-a69d-00053c1f610e?width=80&heigth=80",
symbol: "🙏",
text: "Vielen Dank für deine Hilfe!!!",
date: "04.07.2024",
},
{
from: "Lisa",
avatar: "https://i.pinimg.com/originals/c0/ed/08/c0ed088cd6532d4fd27396aefddac57c.jpg",
symbol: "❤️",
text: "Vielen Dank für deine Hilfe!!!",
date: "04.07.2024",
},
{
from: "Timo",
avatar: "https://api.utopia-lab.org/assets/262117f8-feb6-444f-9bd2-e84087285760?width=80&heigth=80",
symbol: "🥈",
text: "2. Platz im Bogenschießen",
date: "21.06.2024",
},
{
from: "Anton",
avatar: "https://api.utopia-lab.org/assets/007dc678-6073-4ad1-9b47-f2cfe1dca582?width=80&heigth=80",
symbol: "🌱",
text: "danke fürs Rasen mähen",
date: "29.06.2024"
},
]
useEffect(() => {
let params = new URLSearchParams(location.search);
@ -89,51 +39,6 @@ export const TabsForm = ({ item, state, setState, updatePermission, linkItem, un
text: v
}))} containerStyle='tw-h-full' inputStyle='tw-h-full tw-border-t-0 tw-rounded-tl-none' />
</div>
{item.layer?.itemType.questlog &&
<>
<input type="radio" name="my_tabs_2" role="tab"
className={`tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`}
aria-label="❤️" checked={activeTab == 2 && true}
onChange={() => updateActiveTab(2)} />
<div role="tabpanel"
className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
<table className="sm:tw-table-sm md:tw-table-md">
<tbody>
{attestations.map((a, i) => <tr key={i}>
<td>
<div className='tw-mask tw-mask-circle tw-text-xl md:tw-text-2xl tw-bg-slate-200 tw-rounded-full tw-p-2 tw-my-1 tw-mr-2'>{a.symbol}</div>
</td>
<td>
<div className='tw-mr-2' ><i>{a.text}</i></div>
</td>
<td>
<div className="flex items-center gap-3">
<div className="tw-avatar">
<div className="tw-mask tw-rounded-full h-8 w-8 tw-mr-2">
<img
src={a.avatar}
alt="Avatar Tailwind CSS Component" />
</div>
</div>
<div>
<div className="font-bold">{a.from}</div>
<div className="tw-text-xs opacity-50 tw-text-zinc-500">{a.date}</div>
</div>
</div>
</td>
</tr>)}
</tbody>
</table>
</div>
</>
}
{item.layer?.itemType.offers_and_needs &&
<>
<input type="radio" name="my_tabs_2" role="tab" className={`tw-tab tw-min-w-[10em] [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`} aria-label="Offers & Needs" checked={activeTab == 3 && true} onChange={() => updateActiveTab(3)} />

View File

@ -41,11 +41,62 @@ export const TabsView = ({ item, offers, needs, relations, updatePermission, loa
urlTab ? setActiveTab(Number(urlTab)) : setActiveTab(1);
}, [location])
const attestations = [{
from: "Timo",
avatar: "https://api.utopia-lab.org/assets/262117f8-feb6-444f-9bd2-e84087285760?width=80&heigth=80",
symbol: "🥇",
text: "1. Platz im Bogenschießen",
date: "21.06.2024",
},
{
from: "Sebastian",
avatar: "https://api.utopia-lab.org/assets/7510a082-882b-41c3-aa7d-5a19f9502f25?width=80&heigth=80",
symbol: "🌱",
text: "danke fürs Rasen mähen",
date: "29.06.2024",
},
{
from: "Yurij",
avatar: "https://api.utopia-lab.org/assets/abe62291-35ad-45de-b978-e5906d8a3eb6?width=80&heigth=80",
symbol: "🏆",
text: "bester Coder ever",
date: "04.07.2024",
},
{
from: "Luca",
avatar: "https://api.utopia-lab.org/assets/e285e653-36e8-4211-a69d-00053c1f610e?width=80&heigth=80",
symbol: "🙏",
text: "Vielen Dank für deine Hilfe!!!",
date: "04.07.2024",
},
{
from: "Lisa",
avatar: "https://i.pinimg.com/originals/c0/ed/08/c0ed088cd6532d4fd27396aefddac57c.jpg",
symbol: "❤️",
text: "Vielen Dank für deine Hilfe!!!",
date: "04.07.2024",
},
{
from: "Timo",
avatar: "https://api.utopia-lab.org/assets/262117f8-feb6-444f-9bd2-e84087285760?width=80&heigth=80",
symbol: "🥈",
text: "2. Platz im Bogenschießen",
date: "21.06.2024",
},
{
from: "Anton",
avatar: "https://api.utopia-lab.org/assets/007dc678-6073-4ad1-9b47-f2cfe1dca582?width=80&heigth=80",
symbol: "🌱",
text: "danke fürs Rasen mähen",
date: "29.06.2024"
},
]
return (
<div role="tablist" className="tw-tabs tw-tabs-lifted tw-mt-2 tw-mb-2 tw-px-6">
<input type="radio" name="my_tabs_2" role="tab"
className={`tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`}
aria-label="Info" checked={activeTab == 1 && true}
aria-label="👤" checked={activeTab == 1 && true}
onChange={() => updateActiveTab(1)} />
<div role="tabpanel"
className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
@ -54,12 +105,56 @@ export const TabsView = ({ item, offers, needs, relations, updatePermission, loa
}
<TextView item={item} />
</div>
{item.layer?.itemType.questlog &&
<>
<input type="radio" name="my_tabs_2" role="tab"
className={`tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]`}
aria-label="❤️" checked={activeTab == 2 && true}
onChange={() => updateActiveTab(2)} />
<div role="tabpanel"
className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto fade tw-pt-2 tw-pb-4 tw-mb-4 tw-overflow-x-hidden">
<table className="sm:tw-table-sm md:tw-table-md">
<tbody>
{attestations.map((a, i) => <tr key={i}>
<td>
<div className='tw-mask tw-mask-circle tw-text-xl md:tw-text-2xl tw-bg-slate-200 tw-rounded-full tw-p-2 tw-my-1 tw-mr-2'>{a.symbol}</div>
</td>
<td>
<div className='tw-mr-2' ><i>{a.text}</i></div>
</td>
<td>
<div className="flex items-center gap-3">
<div className="tw-avatar">
<div className="tw-mask tw-rounded-full h-8 w-8 tw-mr-2">
<img
src={a.avatar}
alt="Avatar Tailwind CSS Component" />
</div>
</div>
<div>
<div className="font-bold">{a.from}</div>
<div className="tw-text-xs opacity-50 tw-text-zinc-500">{a.date}</div>
</div>
</div>
</td>
</tr>)}
</tbody>
</table>
</div>
</>
}
{item.layer?.itemType.offers_and_needs &&
<>
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab tw-min-w-[10em] [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Offers & Needs" checked={activeTab == 3 && true} onChange={() => updateActiveTab(3)} />
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="🧩" checked={activeTab == 3 && true} onChange={() => updateActiveTab(3)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-268px)] tw-overflow-y-auto fade tw-pt-4 tw-pb-1" >
<div className='tw-h-full'>
<div className='tw-grid tw-grid-cols-1'>
@ -97,7 +192,7 @@ export const TabsView = ({ item, offers, needs, relations, updatePermission, loa
{item.layer?.itemType.relations &&
<>
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="Relations" checked={activeTab == 7 && true} onChange={() => updateActiveTab(7)} />
<input type="radio" name="my_tabs_2" role="tab" className="tw-tab [--tab-border-color:var(--fallback-bc,oklch(var(--bc)/0.2))]" aria-label="🔗" checked={activeTab == 7 && true} onChange={() => updateActiveTab(7)} />
<div role="tabpanel" className="tw-tab-content tw-bg-base-100 tw-rounded-box tw-h-[calc(100dvh-280px)] tw-overflow-y-auto tw-pt-4 tw-pb-1 -tw-mr-4 -tw-mb-4 tw-overflow-x-hidden">
<div className='tw-h-full'>
<div className='tw-grid tw-grid-cols-1 sm:tw-grid-cols-2 md:tw-grid-cols-1 lg:tw-grid-cols-1 xl:tw-grid-cols-1 2xl:tw-grid-cols-2 tw-pb-4'>

View File

@ -1,65 +1,79 @@
import * as react from 'react'
import { useState } from 'react'
import { TitleCard } from './TitleCard'
import { timeAgo } from '../../Utils/TimeAgo'
import { MapOverlayPage } from './MapOverlayPage'
import { useItems } from '../Map/hooks/useItems'
import { useAssetApi } from '../AppShell/hooks/useAssets'
import { EmojiPicker } from './EmojiPicker';
import { Link } from 'react-router-dom';
import { ColorPicker } from '../Profile/Subcomponents/ColorPicker';
import { useRef, useState } from 'react';
import { Item, UserItem } from '../../types';
import { useEffect } from 'react';
export const AttestationForm = ({ userType }: { userType: string }) => {
export const AttestationForm = () => {
const items = useItems();
const users = items.filter(i => i.layer?.itemType.name == userType)
const assetsApi = useAssetApi();
const [users, setUsers] = useState<Array<Item>>();
useEffect(() => {
let params = new URLSearchParams(location.search);
let to_user_ids = params.get("to");
setUsers(items.filter(i => to_user_ids?.includes(i.id)))
}, [items, location])
const [inputValue, setInputValue] = useState('');
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.style.width = 'auto';
inputRef.current.style.width = `${inputRef.current.scrollWidth+20}px`;
}
}, [inputValue]);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
};
return (
<MapOverlayPage className='tw-h-3/4 tw-w-80'>
<div className='tw-text-center tw-text-xl tw-font-bold tw-mb-4'>Select User</div>
{/* Team Member list in table format loaded constant */}
<div className="tw-overflow-x-auto tw-w-full">
<table className="tw-table tw-w-full">
<tbody>
{
users.map((l, k) => {
return (
<tr key={k}>
<td>
<input type="checkbox" defaultChecked className="tw-checkbox" />
</td>
<td>
<div className="tw-flex tw-items-center tw-space-x-3">
{l.image ? <div className="tw-avatar">
<div className="tw-mask tw-mask-circle tw-w-8 tw-h-8">
<img src={assetsApi.url + l.image} alt="Avatar" />
</div>
</div> :
<div className='tw-mask tw-mask-circle tw-text-xl md:tw-text-2xl tw-bg-slate-200 tw-rounded-full tw-w-8 tw-h-8'></div>}
<div>
<div className="tw-font-bold">{l.name}</div>
</div>
</div>
</td>
</tr>
)
})
}
</tbody>
</table>
<MapOverlayPage backdrop className='tw-h-fit tw-min-h-56 tw-w-96'>
<div className='tw-text-center tw-text-xl tw-font-bold'>Gratitude</div>
<div className='tw-text-center tw-text-base tw-text-gray-400'>to</div>
<div className='tw-flex tw-flex-row tw-justify-center tw-items-center tw-flex-wrap'>
{users && users.map((u, k) => (
<div key={k} className="tw-flex tw-items-center tw-space-x-3 tw-mx-2 tw-my-1">
{u.image ? <div className="tw-avatar">
<div className="tw-mask tw-mask-circle tw-w-8 tw-h-8">
<img src={assetsApi.url + u.image + "?width=40&heigth=40"} alt="Avatar" />
</div>
</div> :
<div className='tw-mask tw-mask-circle tw-text-xl md:tw-text-2xl tw-bg-slate-200 tw-rounded-full tw-w-8 tw-h-8'></div>}
<div>
<div className="tw-font-bold">{u.name}</div>
</div>
</div>
), ", ")}
</div>
<button className="tw-btn">Next</button>
<div className='tw-w-full'>
<div className='tw-flex tw-justify-center tw-items-center'>
<div className=' tw-flex tw-justify-center tw-items-center tw-w-28 tw-h-28 tw-m-4'>
<EmojiPicker />
</div>
</div>
<div className='tw-flex tw-justify-center tw-items-center'>
<input ref={inputRef}
value={inputValue}
onChange={handleChange}
type="text"
placeholder="... and say some words"
className="tw-input tw-min-w-0 tw-w-fit tw-resize-none tw-overflow-hidden tw-text-center " />
</div>
</div>
<div className='tw-w-full tw-grid tw-mt-4'><Link className="tw-place-self-center" to="/item/b42a1404-fe08-4d84-8404-47ce623c3cf2?tab=2"><button className="tw-btn tw-px-8">Next</button></Link></div>
</MapOverlayPage>
)
}
const TEAM_MEMBERS = [
{ name: "Alex", avatar: "https://reqres.in/img/faces/1-image.jpg", email: "alex@dashwind.com", role: "Owner", joinedOn: timeAgo(new Date()), lastActive: "5 hr ago" },
{ name: "Ereena", avatar: "https://reqres.in/img/faces/2-image.jpg", email: "ereena@dashwind.com", role: "Admin", joinedOn: timeAgo(new Date()), lastActive: "15 min ago" },
{ name: "John", avatar: "https://reqres.in/img/faces/3-image.jpg", email: "jhon@dashwind.com", role: "Admin", joinedOn: timeAgo(new Date()), lastActive: "20 hr ago" },
{ name: "Matrix", avatar: "https://reqres.in/img/faces/4-image.jpg", email: "matrix@dashwind.com", role: "Manager", joinedOn: timeAgo(new Date()), lastActive: "1 hr ago" },
{ name: "Virat", avatar: "https://reqres.in/img/faces/5-image.jpg", email: "virat@dashwind.com", role: "Support", joinedOn: timeAgo(new Date()), lastActive: "40 min ago" },
{ name: "Miya", avatar: "https://reqres.in/img/faces/6-image.jpg", email: "miya@dashwind.com", role: "Support", joinedOn: timeAgo(new Date()), lastActive: "5 hr ago" },
]
}

View File

@ -0,0 +1,95 @@
import { useState } from 'react';
export const EmojiPicker = () => {
const [selectedEmoji, setSelectedEmoji] = useState('select badge');
const [selectedShape, setSelectedShape] = useState('circle');
const [selectedColor, setSelectedColor] = useState('#fff0d6');
const [isOpen, setIsOpen] = useState(false);
const emojis = [
'❤️', '🙏', '👍', '🌻',, '✨', '☀️',
'🔥', '🪵', '💧', '🎶', '🎨','🍄',
'📝', '✉️', '🧩','💡', '🎓', '💬',
'🛠', '💻', '🕹', '🖨', '🚐', '🛒',
'⚽️', '🧵', '👀', '🌱',
'🏕', '💪', '🎁', '🎉',
'🥕', '🥇', '🥈', '🥉'];
const shapes = ["squircle", "circle", "hexagon-2"];
const colors = ["#FF99C8", "#fff0d6", "#FCF6BD", "#D0F4DE", "#A9DEF9", "#E4C1F9", "#de324c", "#f4895f", "#f8e16f", "#95cf92", "#369acc", "#9656a2"]
const toggleDropdown = () => {
setIsOpen(!isOpen);
};
const selectEmoji = (emoji) => {
setSelectedEmoji(emoji);
setIsOpen(false);
};
const selectShape = (shape) => {
setSelectedShape(shape);
setIsOpen(false);
};
const selectColor = (color) => {
setSelectedColor(color);
setIsOpen(false);
};
return (
<>
<div
onClick={toggleDropdown}
className={`tw-cursor-pointer ${selectedEmoji=="select badge" ? 'tw-text-sm !tw-p-9 tw-text-center ' : 'tw-text-6xl'} tw-mask tw-mask-${selectedShape} tw-p-6 tw-bg-[${selectedColor}]`}
>
{selectedEmoji}
</div>
{isOpen && (
<div className="tw-absolute tw-z-3000 tw-top-0 tw-left-1/2 tw-transform tw--translate-x-1/2 tw-mt-12 tw-bg-base-100 tw-rounded-2xl tw-shadow-lg tw-p-2 tw-w-full">
<div className='tw-grid tw-grid-cols-6 tw-gap-2 tw-pb-2'>
{emojis.map((emoji) => (
<button
key={emoji}
onClick={() => selectEmoji(emoji)}
className={`tw-cursor-pointer tw-text-2xl tw-p-2 hover:tw-bg-base-200 tw-rounded-md ${emoji == selectedEmoji && "tw-bg-base-300"}`}
>
{emoji}
</button>
))}
</div>
<hr />
<div className='tw-grid tw-grid-cols-3 tw-gap-2 tw-py-2'>
{shapes.map(shape => (
<div
key={shape}
className={`tw-cursor-pointer hover:tw-bg-base-200 tw-rounded-md tw-p-2 ${shape == selectedShape && "tw-bg-base-300"}`}
onClick={() => selectShape(shape)}>
<div className={`tw-h-12 tw-mask tw-mask-${shape} tw-bg-neutral-content`}></div>
</div>
))}
</div>
<hr />
<div className='tw-grid tw-grid-cols-6 tw-gap-2 tw-py-2 tw-px-6'>
{colors.map(color => (
<div
key={color}
className={`tw-cursor-pointer hover:tw-bg-base-200 tw-rounded-md tw-p-2 tw-flex tw-justify-center tw-items-center ${color == selectedColor && "tw-bg-base-300"}`}
onClick={() => selectColor(color)}>
<div className={`tw-h-8 tw-w-8 tw-rounded-full tw-bg-[${color}]`}></div>
</div>
))}
</div>
</div>
)}
</>
);
};

View File

@ -5,6 +5,7 @@ import { timeAgo } from '../../Utils/TimeAgo'
import { MapOverlayPage } from './MapOverlayPage'
import { useItems } from '../Map/hooks/useItems'
import { useAssetApi } from '../AppShell/hooks/useAssets'
import { Link } from 'react-router-dom'
export const SelectUser = ({ userType }: { userType: string }) => {
@ -12,33 +13,35 @@ export const SelectUser = ({ userType }: { userType: string }) => {
const users = items.filter(i => i.layer?.itemType.name == userType)
const assetsApi = useAssetApi();
return (
<MapOverlayPage className='tw-h-3/4 tw-w-80'>
const [selectedUsers, setSelectedUsers] = useState<Array<string>>([]);
<div className='tw-text-center tw-text-xl tw-font-bold tw-mb-4'>Select User</div>
return (
<MapOverlayPage backdrop className='tw-h-3/4 tw-w-80'>
<div className='tw-text-center tw-text-xl tw-font-bold tw-mb-4'>Gratitude to ...</div>
{/* Team Member list in table format loaded constant */}
<div className="tw-overflow-x-auto tw-w-full">
<div className="tw-overflow-x-auto tw-w-full fade">
<table className="tw-table tw-w-full">
<tbody>
{
users.map((l, k) => {
users.map((u, k) => {
return (
<tr key={k}>
<td>
<input type="checkbox" className="tw-checkbox tw-checkbox-sm" />
<input type="checkbox" onChange={() => setSelectedUsers(prev => [...prev, u.id])} className="tw-checkbox tw-checkbox-sm" />
</td>
<td>
<div className="tw-flex tw-items-center tw-space-x-3">
{l.image ? <div className="tw-avatar">
{u.image ? <div className="tw-avatar">
<div className="tw-mask tw-mask-circle tw-w-8 tw-h-8">
<img src={assetsApi.url + l.image} alt="Avatar" />
<img src={assetsApi.url + u.image+ "?width=40&heigth=40"} alt="Avatar" />
</div>
</div> :
<div className='tw-mask tw-mask-circle tw-text-xl md:tw-text-2xl tw-bg-slate-200 tw-rounded-full tw-w-8 tw-h-8'></div>}
<div>
<div className="tw-font-bold">{l.name}</div>
<div className="tw-font-bold">{u.name}</div>
</div>
</div>
</td>
@ -49,7 +52,7 @@ export const SelectUser = ({ userType }: { userType: string }) => {
</tbody>
</table>
</div>
<button className="tw-btn">Next</button>
<div className='tw-w-full tw-grid tw-mt-4'><Link className="tw-place-self-center " to={"/attestation-form"+"?to="+selectedUsers.map(u=> u,",")}><button className="tw-btn tw-px-8">Next</button></Link></div>
</MapOverlayPage>
)
}

View File

@ -1,6 +1,9 @@
import { AttestationForm } from './AttestationForm'
export {CardPage} from './CardPage'
export {TitleCard} from './TitleCard'
export {MapOverlayPage} from './MapOverlayPage'
export {MoonCalendar} from './MoonCalendar'
export {SelectUser} from "./SelectUser"
export {OverlayItemsIndexPage} from "./OverlayItemsIndexPage"
export {AttestationForm} from "./AttestationForm"

View File

@ -52,6 +52,10 @@
}
.placeholder-center::placeholder {
text-align: center;
}
.custom-file-upload {
cursor: pointer;
}

View File

@ -3,7 +3,7 @@ export {AppShell, Content, SideBar, Sitemap } from "./Components/AppShell"
export {AuthProvider, useAuth, LoginPage, SignupPage, RequestPasswordPage, SetNewPasswordPage} from "./Components/Auth"
export {UserSettings, ProfileView, ProfileForm} from './Components/Profile'
export {Quests, Modal} from './Components/Gaming'
export {TitleCard, CardPage, MapOverlayPage, OverlayItemsIndexPage, MoonCalendar, SelectUser } from './Components/Templates'
export {TitleCard, CardPage, MapOverlayPage, OverlayItemsIndexPage, MoonCalendar, SelectUser, AttestationForm } from './Components/Templates'
export {TextInput, TextAreaInput, SelectBox} from './Components/Input'
import "./index.css"

View File

@ -4,6 +4,25 @@ module.exports = {
"./src/**/*.{js,jsx,ts,tsx}",
"./node_modules/tw-elements/dist/js/**/*.js"
],
safelist: [
'tw-mask-squircle',
'tw-mask-circle',
'tw-mask-hexagon-2',
'tw-mask-decagon',
'tw-bg-[#FF99C8]',
'tw-bg-[#fff0d6]',
'tw-bg-[#FCF6BD]',
'tw-bg-[#D0F4DE]',
'tw-bg-[#A9DEF9]',
'tw-bg-[#E4C1F9]',
'tw-bg-[#de324c]',
'tw-bg-[#f4895f]',
'tw-bg-[#f8e16f]',
'tw-bg-[#95cf92]',
'tw-bg-[#369acc]',
'tw-bg-[#9656a2]',
],
theme: {
extend: {
zIndex: {
@ -31,7 +50,7 @@ module.exports = {
'sans': ["Helvetica", "sans-serif", 'Roboto'],
},
fontSize: {
'map': "13px"
'map': "13px"
},
lineHeight: {
'map': "1.4em"
@ -44,17 +63,18 @@ module.exports = {
],
daisyui: {
themes: ["light", "dark", "cupcake", "retro", "cyberpunk", "aqua",
{
docutopia: {
"primary": "#8e00ff",
"secondary": "#00bb7a",
"accent": "#006aff",
"neutral": "#231502",
"base-content": "#ffad6b",
"base-100": "#440844",
},
},]
{
docutopia: {
"primary": "#8e00ff",
"secondary": "#00bb7a",
"accent": "#006aff",
"neutral": "#231502",
"base-content": "#ffad6b",
"base-100": "#440844",
},
},]
},
prefix: 'tw-',
content: ['./src/**/*.{js,jsx,ts,tsx}'],
}
}