most add/delete api cals in use

This commit is contained in:
Akito123321 2024-08-29 16:11:28 +02:00
parent 4aae0c1724
commit f06fbd69a9
11 changed files with 269 additions and 175 deletions

View File

@ -5,7 +5,8 @@ import { A, HashRouter, Route, RouteSectionProps, useNavigate } from '@solidjs/r
import Login from './pages/Login'; import Login from './pages/Login';
import Groups from './pages/Groups'; import Groups from './pages/Groups';
import Account from './pages/Account'; import Account from './pages/Account';
import GroupPage from './pages/GroupPage' import GroupPage from './pages/GroupPage';
import StratPage from './pages/StratPage';
import { BsArrowBarRight, BsBookmarkHeartFill, BsPeopleFill } from 'solid-icons/bs'; import { BsArrowBarRight, BsBookmarkHeartFill, BsPeopleFill } from 'solid-icons/bs';
import { API, api, setAPI, setAuthConfig } from './api'; import { API, api, setAPI, setAuthConfig } from './api';
@ -88,6 +89,7 @@ const App: Component = () => {
<HashRouter root={AppLayout}> <HashRouter root={AppLayout}>
<Route path='groups' component={Groups} /> <Route path='groups' component={Groups} />
<Route path='group/:id' component={GroupPage} /> <Route path='group/:id' component={GroupPage} />
<Route path='group/:groupId/strat/:stratId' component={StratPage} />
{localState.accountInfo != null ? {localState.accountInfo != null ?
<> <>
<Route path='account' component={Account} /> <Route path='account' component={Account} />

View File

@ -81,13 +81,11 @@ export interface StratRequest {
title: string, title: string,
description: string, description: string,
stratType: string, stratType: string,
attempts: number,
success: number,
} }
export interface MapRequest { export interface MapRequest {
name: string, name: string,
image: File, image: string,
} }
export interface ProfileRequest { export interface ProfileRequest {
@ -102,12 +100,12 @@ export interface PlayerTypeRequest {
export interface StratStateRequest { export interface StratStateRequest {
description: string, description: string,
image: File, image: string,
} }
export interface LineupRequest { export interface LineupRequest {
description: string, description: string,
image: File, image: string,
} }
export class API { export class API {

View File

@ -1,58 +1,54 @@
import { Component, For, Setter, Show } from 'solid-js'; import { Component, createSignal, For, JSX } from 'solid-js';
import styles from './Dialog.module.css'; import styles from './Dialog.module.css';
import { UploadFile, FileUploader } from '@solid-primitives/upload'; import DialogButtonComponent from './DialogButtonComponent';
export interface DialogButton { export interface DialogButton {
name: string, name: string,
action?: () => void, action?: () => void | boolean | Promise<void> | Promise<boolean>,
type?: 'default' | 'danger' | 'success', type?: 'default' | 'danger' | 'success'
closeOnClick?: boolean
} }
export interface DialogInputField { export interface DialogInputField {
placeholder: string,
onInput: (text: string) => void,
}
export interface ImageInputField {
name: string, name: string,
onInput: () => Setter<UploadFile[]>, placeholder?: string,
onInput: (text: string) => void,
} }
export interface DialogProps { export interface DialogProps {
title: string, title: string,
text: string, text?: string,
buttons?: (string | DialogButton)[], buttons?: (string | DialogButton)[],
onDismiss?: () => void, onDismiss?: () => void,
inputFields?: DialogInputField[], inputFields?: DialogInputField[],
} content?: JSX.Element,
function createButton(button: (string | DialogButton), dismiss?: () => void) { //TODO configurable if dismiss on click
if (typeof button == 'string') {
return <button onclick={dismiss} class={styles.defaultButton}>{button}</button>;
} else {
return <button onclick={() => { button.action?.(); button.closeOnClick ? dismiss?.() : () => { }; }} class={styles[button.type + 'Button']}>{button.name}</button>;
}
} }
function createInputField(field: DialogInputField) { function createInputField(field: DialogInputField) {
return <input placeholder={field.placeholder} onInput={e => field.onInput(e.currentTarget.value)}></input> return <div class={styles.dialogInput}>
<span>{field.name}</span>
<input placeholder={field.placeholder ?? field.name} onInput={e => field.onInput(e.currentTarget.value)}></input>
</div>;
} }
const Dialog: Component<DialogProps> = props => { const Dialog: Component<DialogProps> = props => {
const buttons: () => (string | DialogButton)[] = () => props.buttons == null ? [{ name: 'Okay', action: props.onDismiss }] : props.buttons; const buttons: () => (string | DialogButton)[] = () => props.buttons == null ? ["Okay"] : props.buttons;
const [loading, setLoading] = createSignal(false);
return ( return (
<div class={styles.dialogContainer}> <div class={styles.dialogContainer}>
<div class={styles.dialog}> <div class={styles.dialog}>
<div class={styles.dialogTitle}>{props.title}</div> <div class={styles.dialogTitle}>{props.title}</div>
<div class={styles.dialogText}>{props.text}</div> <div class={styles.dialogText}>{props.text}</div>
<div class={styles.dialogInputFields}> {props.inputFields && props.inputFields.length > 0 && <div class={styles.dialogInputFields}>
<For each={props.inputFields}>{f => createInputField(f)}</For> <For each={props.inputFields}>{f => createInputField(f)}</For>
</div> </div>}
{props.content}
<div class={styles.dialogButtons}> <div class={styles.dialogButtons}>
<For each={buttons()}>{b => createButton(b, props.onDismiss)}</For> <For each={buttons()}>{b => //createButton(b, props.onDismiss);
<DialogButtonComponent button={b} dismiss={props.onDismiss} loading={loading()} setLoading={setLoading} />
}
</For>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,27 @@
import { Component } from "solid-js";
import { DialogButton } from "./Dialog";
import styles from './Dialog.module.css';
export interface DialogButtonProps {
dismiss?: () => void
button: string | DialogButton
loading: boolean
setLoading: (b: boolean) => void
}
const DialogButtonComponent: Component<DialogButtonProps> = (props) => {
if (typeof props.button == 'string') {
return <button onclick={props.dismiss} class={styles.defaultButton}>{props.button}</button>;
} else {
const clickHandler = () => {
props.setLoading(true);
Promise.resolve((props.button as DialogButton).action?.()).then(v => {
if (v === undefined || v === true) props.dismiss?.();
props.setLoading(false);
});
};
return <button disabled={props.loading} onclick={clickHandler} class={styles[props.button.type + 'Button']}>{props.button.name}</button>;
}
}
export default DialogButtonComponent;

View File

@ -21,7 +21,6 @@ const ProfileItem: Component<ProfileItemProps> = (props) => {
{ {
name: 'Remove', name: 'Remove',
type: 'danger', type: 'danger',
closeOnClick: true,
action: async () => { action: async () => {
try { try {
await api().removeProfileFromGroup(props.group.id, props.profile.id); await api().removeProfileFromGroup(props.group.id, props.profile.id);
@ -31,11 +30,7 @@ const ProfileItem: Component<ProfileItemProps> = (props) => {
} }
} }
}, },
{ 'Cancel'
name: 'Cancel',
closeOnClick: true,
action: () => { }
}
] ]
}); });
}; };

View File

@ -4,6 +4,7 @@ import { Group, Strat, api } from "../api";
import { showDialog, showMessageDialog } from "../state"; import { showDialog, showMessageDialog } from "../state";
import { errorToString } from "../util"; import { errorToString } from "../util";
import { BsTrash } from 'solid-icons/bs'; import { BsTrash } from 'solid-icons/bs';
import { useNavigate } from '@solidjs/router';
export interface StratItemProps { export interface StratItemProps {
group: Group, group: Group,
@ -12,6 +13,7 @@ export interface StratItemProps {
} }
const StratItem: Component<StratItemProps> = (props) => { const StratItem: Component<StratItemProps> = (props) => {
const navigate = useNavigate();
const deleteMember = async () => { const deleteMember = async () => {
showDialog({ showDialog({
@ -41,10 +43,10 @@ const StratItem: Component<StratItemProps> = (props) => {
return ( return (
<div class={styles.member}> <div class={styles.member}>
<div class={styles.memberDetails}> <div class={styles.memberDetails}>
<div class={styles.memberName}> <div class={styles.memberName} onclick={() => navigate('/group/' + props.group.id + '/strat/' + props.strat.id)}>
<span innerText={props.strat.title} /> <span innerText={props.strat.title} />
<span innerText={props.strat.description} />
<span innerText={props.strat.stratType} /> <span innerText={props.strat.stratType} />
<span innerText={props.strat.map.name} />
</div> </div>
<div> <div>
<button onClick={deleteMember}><BsTrash /></button> <button onClick={deleteMember}><BsTrash /></button>

View File

@ -1,10 +1,10 @@
import { useNavigate, useParams } from "@solidjs/router"; import { useNavigate, useParams } from "@solidjs/router";
import { Component, Show, createEffect, createSignal } from "solid-js"; import { Component, Show, createEffect, createSignal, onMount } from "solid-js";
import styles from './GroupPage.module.css' import styles from './GroupPage.module.css'
import { Group, Map, Profile, Strat, User, api } from "../api"; import { Group, Map, Profile, Strat, User, api } from "../api";
import { showDialog, showInputDialog, showMessageDialog } from "../state"; import { showDialog, showInputDialog, showMessageDialog } from "../state";
import { _arrayBufferToBase64, errorToString, normalize } from "../util"; import { _arrayBufferToBase64, addMap, addMember, addProfile, addStratType, errorToString, normalize } from "../util";
import { BsCheck2, BsPencil, BsTrash } from "solid-icons/bs"; import { BsCheck2, BsPencil, BsTrash } from "solid-icons/bs";
import { Collapse } from "solid-collapse"; import { Collapse } from "solid-collapse";
import MemberItem from "../components/MemberItem"; import MemberItem from "../components/MemberItem";
@ -29,7 +29,7 @@ const GroupPage: Component = () => {
const [profilesIsExpanded, setProfilesIsExpanded] = createSignal(false); const [profilesIsExpanded, setProfilesIsExpanded] = createSignal(false);
const [stratTypesIsExpanded, setStratTypesIsExpanded] = createSignal(false); const [stratTypesIsExpanded, setStratTypesIsExpanded] = createSignal(false);
createEffect(async () => { onMount(async () => {
try { try {
setGroup(await api().getGroup(params.id)); setGroup(await api().getGroup(params.id));
setName(group().name); setName(group().name);
@ -37,7 +37,7 @@ const GroupPage: Component = () => {
} catch (e) { } catch (e) {
showMessageDialog('Failed to load group', errorToString(e)); showMessageDialog('Failed to load group', errorToString(e));
} }
}, []); });
const updateGroup = async (newValue: Group) => { const updateGroup = async (newValue: Group) => {
try { try {
@ -73,66 +73,34 @@ const GroupPage: Component = () => {
}); });
}; };
const addMember = async () => { const createStrat = async () => {
showInputDialog('Add member to Group', 'enter the member id you want to add', 'member ID', async (memberId) => { const [title, setTitle] = createSignal('');
try { const [description, setDescription] = createSignal('');
const newGroup = await api().addMember(group().id, memberId); const [stratType, setStratType] = createSignal('');
setGroup(newGroup);
} catch (e) {
showMessageDialog('Failed to add member', errorToString(e));
}
})
};
const addStratType = async () => {
showInputDialog('Add strat type to Group', 'enter the name you want to add', 'strat type', async (stratType) => {
try {
const newGroup = await api().addStratType(group().id, stratType);
setGroup(newGroup);
} catch (e) {
showMessageDialog('Failed to add strat type', errorToString(e));
}
})
};
const addProfile = async () => {
const [profileName, setProfileName] = createSignal('');
const { files, selectFiles } = createFileUploader({
multiple: false,
accept: "image/*",
});
let fileReader = new FileReader();
fileReader.onload = async event => {
try {
const newGroup = await api().addProfileToGroup(group().id, { name: profileName(), image: _arrayBufferToBase64(event.target!.result as ArrayBuffer) });
setGroup(newGroup);
} catch (e) {
showMessageDialog('Failed to add profile', errorToString(e));
}
}
showDialog({ showDialog({
title: 'Add profile to Group', title: 'Add a strat to Group',
text: 'create a new profile', text: 'create a new strat',
inputFields: [{ inputFields: [{
onInput: setProfileName, onInput: setTitle,
placeholder: 'name' placeholder: 'title',
name: 'title'
}, {
onInput: setDescription,
placeholder: 'description',
name: 'description'
}], }],
onDismiss: async () => { onDismiss: async () => {
fileReader.readAsArrayBuffer(files()[0].file); const strat = await api().addStrat(group().id, { title: title(), description: description(), stratType: stratType() });
navigate('/group/' + group().id + '/strat/' + strat.id);
}, },
buttons: [{ content: <select name="stratType" id="stratType">
name: 'add image', action: () => selectFiles(([{ source, name, size, file }]) => { {group().stratTypes.map(p => <option value={p} onclick={() => setStratType(p)}>{p}</option>)}
console.log({ source, name, size, file }); </select>,
}), buttons: ['confirm'],
closeOnClick: false
}, });
'confirm' }
],
})
};
const toggleEdit = async () => { const toggleEdit = async () => {
if (!editing()) { if (!editing()) {
@ -178,7 +146,7 @@ const GroupPage: Component = () => {
<hr /> <hr />
<div> <div>
<button onClick={() => setMembersIsExpanded(!membersIsExpanded())}>Members</button> <button onClick={() => setMembersIsExpanded(!membersIsExpanded())}>Members</button>
<button class={styles.addMemberButton} onClick={addMember}>+</button> <button class={styles.addMemberButton} onClick={async () => addMember(group(), (g) => setGroup(g))}>+</button>
<Collapse value={membersIsExpanded()} class={styles.members}> <Collapse value={membersIsExpanded()} class={styles.members}>
<div class={styles.groupMembers}> <div class={styles.groupMembers}>
{group().members?.map(m => <MemberItem group={group()} member={m} onDelete={onDeleteMember} />)} {group().members?.map(m => <MemberItem group={group()} member={m} onDelete={onDeleteMember} />)}
@ -186,6 +154,7 @@ const GroupPage: Component = () => {
</Collapse> </Collapse>
<br /> <br />
<button onClick={() => setStratsIsExpanded(!stratsIsExpanded())}>strats</button> <button onClick={() => setStratsIsExpanded(!stratsIsExpanded())}>strats</button>
<button class={styles.addStratButton} onClick={() => createStrat()}>+</button>
<Collapse value={stratsIsExpanded()} class={styles.strats}> <Collapse value={stratsIsExpanded()} class={styles.strats}>
<div class={styles.strats}> <div class={styles.strats}>
{group().strats?.map(s => <StratItem group={group()} strat={s} onDelete={onDeleteStrat} />)} {group().strats?.map(s => <StratItem group={group()} strat={s} onDelete={onDeleteStrat} />)}
@ -193,6 +162,7 @@ const GroupPage: Component = () => {
</Collapse> </Collapse>
<br /> <br />
<button onClick={() => setMapsIsExpanded(!mapsIsExpanded())}>maps</button> <button onClick={() => setMapsIsExpanded(!mapsIsExpanded())}>maps</button>
<button class={styles.addMapButton} onClick={async () => addMap(group(), (g) => setGroup(g))}>+</button>
<Collapse value={mapsIsExpanded()} class={styles.maps}> <Collapse value={mapsIsExpanded()} class={styles.maps}>
<div class={styles.maps}> <div class={styles.maps}>
{group().maps?.map(m => <MapItem group={group()} map={m} onDelete={onDeleteMap} />)} {group().maps?.map(m => <MapItem group={group()} map={m} onDelete={onDeleteMap} />)}
@ -200,7 +170,7 @@ const GroupPage: Component = () => {
</Collapse> </Collapse>
<br /> <br />
<button onClick={() => setStratTypesIsExpanded(!stratTypesIsExpanded())}>strat types</button> <button onClick={() => setStratTypesIsExpanded(!stratTypesIsExpanded())}>strat types</button>
<button class={styles.addMemberButton} onClick={addStratType}>+</button> <button class={styles.addMemberButton} onClick={async () => addStratType(group(), (g) => setGroup(g))}>+</button>
<Collapse value={stratTypesIsExpanded()} class={styles.stratTypes}> <Collapse value={stratTypesIsExpanded()} class={styles.stratTypes}>
<div class={styles.stratTypes}> <div class={styles.stratTypes}>
{group().stratTypes?.map(s => <StratTypeItem group={group()} stratType={s} onDelete={onDeleteStratType} />)} {group().stratTypes?.map(s => <StratTypeItem group={group()} stratType={s} onDelete={onDeleteStratType} />)}
@ -208,7 +178,7 @@ const GroupPage: Component = () => {
</Collapse> </Collapse>
<br /> <br />
<button onClick={() => setProfilesIsExpanded(!profilesIsExpanded())}>profiles</button> <button onClick={() => setProfilesIsExpanded(!profilesIsExpanded())}>profiles</button>
<button class={styles.addMemberButton} onClick={addProfile}>+</button> <button class={styles.addMemberButton} onClick={async () => addProfile(group(), (g) => setGroup(g))}>+</button>
<Collapse value={profilesIsExpanded()} class={styles.profiles}> <Collapse value={profilesIsExpanded()} class={styles.profiles}>
<div class={styles.profiles}> <div class={styles.profiles}>
{group().profiles?.map(p => <ProfileItem group={group()} profile={p} onDelete={onDeleteProfile} />)} {group().profiles?.map(p => <ProfileItem group={group()} profile={p} onDelete={onDeleteProfile} />)}

7
src/pages/StratPage.tsx Normal file
View File

@ -0,0 +1,7 @@
import { Component } from "solid-js";
const StratPage: Component = () => {
return <>strat page</>
}
export default StratPage

View File

@ -1,7 +1,7 @@
import { createEffect, createSignal } from 'solid-js'; import { createEffect, createSignal } from 'solid-js';
import { SetStoreFunction, Store, createStore } from 'solid-js/store'; import { SetStoreFunction, Store, createStore } from 'solid-js/store';
import { AuthenticationResponse } from './api'; import { AuthenticationResponse } from './api';
import { DialogInputField, DialogProps, ImageInputField } from './components/Dialog'; import { DialogInputField, DialogProps } from './components/Dialog';
// Source: https://www.solidjs.com/examples/todos // Source: https://www.solidjs.com/examples/todos
function createLocalStore<T extends object>( function createLocalStore<T extends object>(
@ -30,7 +30,9 @@ export const showDialog = (dialog: DialogProps) => {
onDismiss: () => { onDismiss: () => {
setDialogs(ds => { setDialogs(ds => {
const newDs = [...ds]; const newDs = [...ds];
newDs.splice(ds.indexOf(newDialog), 1); let idx = ds.indexOf(newDialog);
if (idx == -1) return newDs;
newDs.splice(idx, 1);
return newDs; return newDs;
}); });
dialog.onDismiss?.(); dialog.onDismiss?.();
@ -40,14 +42,14 @@ export const showDialog = (dialog: DialogProps) => {
setDialogs([...dialogs(), newDialog]); setDialogs([...dialogs(), newDialog]);
}; };
export const showInputDialog = (title: string, message: string, placeholder: string, callback: (text: string) => void) => { export const showInputDialog = (title: string, message: string, name: string, callback: (text: string) => void) => {
const [text, setText] = createSignal(''); const [text, setText] = createSignal('');
showDialog({ showDialog({
title, title,
text: message, text: message,
inputFields: [{ placeholder, onInput: setText }], inputFields: [{ name, onInput: setText }],
buttons: [{ name: 'Okay', action: () => callback(text()), closeOnClick: true }] buttons: [{ name: 'Okay', action: () => callback(text()) }, "cancel"]
}); });
} }
@ -56,7 +58,7 @@ export const showInputsDialog = async (title: string, message: string, inputFiel
title, title,
text: message, text: message,
inputFields: inputFields, inputFields: inputFields,
buttons: [{ name: 'Okay', action: () => callback(), closeOnClick: true }] buttons: [{ name: 'Okay', action: () => callback() }]
}); });
} }

View File

@ -1,69 +0,0 @@
export function errorToString(e: any): string { // eslint-disable-line @typescript-eslint/no-explicit-any
if (typeof e == 'string') {
return e;
} else if (e.toString) {
return e.toString() as string;
} else {
return 'Unknown error';
}
}
export function normalize(text: string, maxLength: number, oneLine: boolean) {
if (oneLine) text = text.replaceAll('\n', '');
text = text.substring(0, maxLength);
return text;
}
export function normalizeQuantity(text: string) {
let quantity = parseInt(text);
if (isNaN(quantity) || quantity < 0) {
return 1;
}
return quantity;
}
function clamp(value: number, min: number, max: number) {
return Math.min(Math.max(value, min), max);
};
export function normalizeRating(text: string) {
let rating = parseInt(text);
if (isNaN(rating)) {
return 1;
}
return clamp(rating, 0, 5);
}
export function _arrayBufferToBase64(buffer: ArrayBuffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
export const b64toBlob = (b64Data: string, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
}

164
src/util.tsx Normal file
View File

@ -0,0 +1,164 @@
import { createSignal } from "solid-js";
import { api, Group } from "./api";
import { showDialog, showInputDialog, showMessageDialog } from "./state";
import { createFileUploader } from "@solid-primitives/upload";
export function errorToString(e: any): string { // eslint-disable-line @typescript-eslint/no-explicit-any
if (typeof e == 'string') {
return e;
} else if (e.toString) {
return e.toString() as string;
} else {
return 'Unknown error';
}
}
export function normalize(text: string, maxLength: number, oneLine: boolean) {
if (oneLine) text = text.replaceAll('\n', '');
text = text.substring(0, maxLength);
return text;
}
export function normalizeQuantity(text: string) {
let quantity = parseInt(text);
if (isNaN(quantity) || quantity < 0) {
return 1;
}
return quantity;
}
function clamp(value: number, min: number, max: number) {
return Math.min(Math.max(value, min), max);
};
export function normalizeRating(text: string) {
let rating = parseInt(text);
if (isNaN(rating)) {
return 1;
}
return clamp(rating, 0, 5);
}
export function _arrayBufferToBase64(buffer: ArrayBuffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
export const b64toBlob = (b64Data: string, contentType = '', sliceSize = 512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, { type: contentType });
return blob;
}
export const addMember = (group: Group, onClose: (newGroup: Group) => void) => {
showInputDialog('Add member to Group', 'enter the member id you want to add', 'member ID', async (memberId) => {
try {
onClose(await api().addMember(group.id, memberId));
} catch (e) {
showMessageDialog('Failed to add member', errorToString(e));
}
})
};
export const addStratType = (group: Group, onClose: (newGroup: Group) => void) => {
showInputDialog('Add strat type to Group', 'enter the name you want to add', 'strat type', async (stratType) => {
try {
onClose(await api().addStratType(group.id, stratType));
} catch (e) {
showMessageDialog('Failed to add strat type', errorToString(e));
}
})
};
export const addProfile = (group: Group, onClose: (newGroup: Group) => void) => {
const [profileName, setProfileName] = createSignal('');
const { files, selectFiles } = createFileUploader({
multiple: false,
accept: "image/*",
});
let fileReader = new FileReader();
fileReader.onload = async event => {
try {
onClose(await api().addProfileToGroup(group.id, { name: profileName(), image: _arrayBufferToBase64(event.target!.result as ArrayBuffer) }));
} catch (e) {
showMessageDialog('Failed to add profile', errorToString(e));
}
}
showDialog({
title: 'Add profile to Group',
text: 'create a new profile',
inputFields: [{
onInput: setProfileName,
placeholder: 'name',
name: 'name'
}],
onDismiss: async () => {
fileReader.readAsArrayBuffer(files()[0].file);
},
content: <button onclick={() => selectFiles(([{ source, name, size, file }]) => {
console.log({ source, name, size, file });
})}> Add Image </button>,
buttons: ['confirm'],
});
};
export const addMap = async (group: Group, onClose: (newGroup: Group) => void) => {
const [mapName, setMapName] = createSignal('');
const { files, selectFiles } = createFileUploader({
multiple: false,
accept: "image/*",
});
let fileReader = new FileReader();
fileReader.onload = async event => {
try {
onClose(await api().addMap(group.id, { name: mapName(), image: _arrayBufferToBase64(event.target!.result as ArrayBuffer) }));
} catch (e) {
showMessageDialog('Failed to add map', errorToString(e));
}
}
showDialog({
title: 'Add map to Group',
text: 'create a new map',
inputFields: [{
onInput: setMapName,
placeholder: 'name',
name: 'name'
}],
onDismiss: async () => {
fileReader.readAsArrayBuffer(files()[0].file);
},
content: <button onclick={() => selectFiles(([{ source, name, size, file }]) => {
console.log({ source, name, size, file });
})}> Add Image </button>,
buttons: ['confirm'],
});
};