feat: group editing!
This commit is contained in:
parent
7e5cd338af
commit
9d3bbc7e5c
@ -10,7 +10,7 @@
|
|||||||
let avatarOpen = false;
|
let avatarOpen = false;
|
||||||
const toggleAvatarModal = () => (avatarOpen = !avatarOpen);
|
const toggleAvatarModal = () => (avatarOpen = !avatarOpen);
|
||||||
|
|
||||||
export let loading: boolean;
|
export let loading: boolean = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CardTitle style="margin-top: 0px; margin-bottom: 0px; outline: none; align-items: center;" class="d-flex justify-content-between align-middle w-100">
|
<CardTitle style="margin-top: 0px; margin-bottom: 0px; outline: none; align-items: center;" class="d-flex justify-content-between align-middle w-100">
|
||||||
|
@ -3,24 +3,38 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { toHTML } from 'discord-markdown';
|
import { toHTML } from 'discord-markdown';
|
||||||
import type Group from '../../api/group';
|
import type Group from '../../api/group';
|
||||||
|
import Edit from './Edit.svelte';
|
||||||
|
import twemoji from 'twemoji';
|
||||||
|
|
||||||
export let group: Group;
|
export let item: Group;
|
||||||
|
let group = item;
|
||||||
let editMode: boolean;
|
let editMode: boolean;
|
||||||
export let isPublic: boolean;
|
export let isPublic: boolean;
|
||||||
|
export let loading: boolean = false;
|
||||||
|
|
||||||
let htmlDescription: string;
|
let htmlDescription: string;
|
||||||
if (group.description) {
|
$: if (group.description) {
|
||||||
htmlDescription = toHTML(group.description, {embed: true});
|
htmlDescription = toHTML(group.description, {embed: true});
|
||||||
} else {
|
} else {
|
||||||
htmlDescription = "(no description)";
|
htmlDescription = "(no description)";
|
||||||
}
|
}
|
||||||
|
let htmlDisplayName: string;
|
||||||
|
if (group.display_name) htmlDisplayName = toHTML(group.display_name)
|
||||||
|
|
||||||
|
let settings = JSON.parse(localStorage.getItem("pk-settings"));
|
||||||
|
let descriptionElement: any;
|
||||||
|
let displayNameElement: any;
|
||||||
|
|
||||||
|
$: if (settings && settings.appearance.twemoji) {
|
||||||
|
if (descriptionElement) twemoji.parse(descriptionElement);
|
||||||
|
if (displayNameElement) twemoji.parse(displayNameElement);
|
||||||
|
};
|
||||||
|
|
||||||
let created = moment(group.created).format("MMM D, YYYY");
|
let created = moment(group.created).format("MMM D, YYYY");
|
||||||
|
|
||||||
let bannerOpen = false;
|
let bannerOpen = false;
|
||||||
const toggleBannerModal = () => (bannerOpen = !bannerOpen);
|
const toggleBannerModal = () => (bannerOpen = !bannerOpen);
|
||||||
|
|
||||||
let settings = JSON.parse(localStorage.getItem("pk-settings"));
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CardBody style="border-left: 4px solid #{group.color}; margin: -1rem -1.25rem">
|
<CardBody style="border-left: 4px solid #{group.color}; margin: -1rem -1.25rem">
|
||||||
@ -38,7 +52,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if group.display_name}
|
{#if group.display_name}
|
||||||
<Col xs={12} lg={4} class="mb-2">
|
<Col xs={12} lg={4} class="mb-2">
|
||||||
<b>Display Name:</b> {group.display_name}
|
<b>Display Name:</b> <span bind:this={displayNameElement}>{@html htmlDisplayName}</span>
|
||||||
</Col>
|
</Col>
|
||||||
{/if}
|
{/if}
|
||||||
{#if group.created && !isPublic}
|
{#if group.created && !isPublic}
|
||||||
@ -62,7 +76,7 @@
|
|||||||
</Col>
|
</Col>
|
||||||
{/if}
|
{/if}
|
||||||
</Row>
|
</Row>
|
||||||
<div class="my-2 description">
|
<div class="my-2 description" bind:this={descriptionElement}>
|
||||||
<b>Description:</b><br />
|
<b>Description:</b><br />
|
||||||
{@html htmlDescription}
|
{@html htmlDescription}
|
||||||
</div>
|
</div>
|
||||||
@ -73,6 +87,6 @@
|
|||||||
<Button style="flex: 0" color="primary" on:click={() => editMode = true}>Edit</Button>
|
<Button style="flex: 0" color="primary" on:click={() => editMode = true}>Edit</Button>
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
woohoo editing goes here
|
<Edit bind:loading bind:group bind:editMode />
|
||||||
{/if}
|
{/if}
|
||||||
</CardBody>
|
</CardBody>
|
76
src/lib/group/Edit.svelte
Normal file
76
src/lib/group/Edit.svelte
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Row, Col, Input, Button, Label, Alert } from 'sveltestrap';
|
||||||
|
import Group from '../../api/group';
|
||||||
|
import PKAPI from '../../api';
|
||||||
|
import autosize from 'svelte-autosize';
|
||||||
|
|
||||||
|
export let loading: boolean = false;
|
||||||
|
export let group: Group;
|
||||||
|
export let editMode: boolean;
|
||||||
|
|
||||||
|
let err: string[] = [];
|
||||||
|
|
||||||
|
let input = new Group(group);
|
||||||
|
|
||||||
|
async function submit() {
|
||||||
|
let data = input;
|
||||||
|
err = [];
|
||||||
|
|
||||||
|
if (data.color && !/^#?[A-Fa-f0-9]{6}$/.test(input.color)) {
|
||||||
|
err.push(`"${data.color}" is not a valid color, the color must be a 6-digit hex code. (example: #ff0000)`);
|
||||||
|
} else if (data.color) {
|
||||||
|
if (data.color.startsWith("#")) {
|
||||||
|
data.color = input.color.slice(1, input.color.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = err;
|
||||||
|
if (err.length > 0) return;
|
||||||
|
|
||||||
|
loading = true;
|
||||||
|
const api = new PKAPI();
|
||||||
|
try {
|
||||||
|
let res = await api.patchGroup({token: localStorage.getItem("pk-token"), id: group.id, data: data});
|
||||||
|
group = res;
|
||||||
|
err = [];
|
||||||
|
editMode = false;
|
||||||
|
loading = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
err.push(error.message);
|
||||||
|
err = err;
|
||||||
|
loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each err as error}
|
||||||
|
<Alert color="danger">{@html error}</Alert>
|
||||||
|
{/each}
|
||||||
|
<Row>
|
||||||
|
<Col xs={12} lg={4} class="mb-2">
|
||||||
|
<Label>Name:</Label>
|
||||||
|
<Input bind:value={input.name} maxlength={100} type="text" placeholder={group.name} />
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} lg={4} class="mb-2">
|
||||||
|
<Label>Display name:</Label>
|
||||||
|
<Input bind:value={input.display_name} maxlength={100} type="text" placeholder={group.display_name} />
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} lg={4} class="mb-2">
|
||||||
|
<Label>Color:</Label>
|
||||||
|
<Input bind:value={input.color} type="text" placeholder={group.color}/>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} lg={4} class="mb-2">
|
||||||
|
<Label>Avatar url:</Label>
|
||||||
|
<Input bind:value={input.icon} maxlength={256} type="url" placeholder={group.icon}/>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} lg={4} class="mb-2">
|
||||||
|
<Label>Banner url:</Label>
|
||||||
|
<Input bind:value={input.banner} maxlength={256} type="url" placeholder={group.banner}/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<div class="my-2">
|
||||||
|
<b>Description:</b><br />
|
||||||
|
<textarea class="form-control" bind:value={input.description} maxlength={1000} use:autosize placeholder={group.description}/>
|
||||||
|
</div>
|
||||||
|
<Button style="flex: 0" color="primary" on:click={submit}>Submit</Button> <Button style="flex: 0" color="light" on:click={() => editMode = false}>Back</Button>
|
@ -13,7 +13,6 @@
|
|||||||
import Svelecte, { addFormatter } from 'svelecte';
|
import Svelecte, { addFormatter } from 'svelecte';
|
||||||
|
|
||||||
export let isPublic: boolean;
|
export let isPublic: boolean;
|
||||||
let itemLoading = false;
|
|
||||||
|
|
||||||
export let list: Group[];
|
export let list: Group[];
|
||||||
export let members: Member[];
|
export let members: Member[];
|
||||||
@ -146,6 +145,8 @@
|
|||||||
'member-list': memberListRenderer
|
'member-list': memberListRenderer
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let itemLoading: boolean[] = [];
|
||||||
|
$: itemLoading.length = slicedList.length;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card class="mb-3">
|
<Card class="mb-3">
|
||||||
@ -248,12 +249,12 @@
|
|||||||
</Row>
|
</Row>
|
||||||
<ListPagination bind:currentPage bind:pageAmount />
|
<ListPagination bind:currentPage bind:pageAmount />
|
||||||
<Accordion class="my-3" stayOpen>
|
<Accordion class="my-3" stayOpen>
|
||||||
{#each slicedList as group (group.id)}
|
{#each slicedList as group, index (group.id)}
|
||||||
<AccordionItem>
|
<AccordionItem>
|
||||||
<CardsHeader bind:item={group} bind:loading={itemLoading} slot="header">
|
<CardsHeader bind:item={group} bind:loading={itemLoading[index]} slot="header">
|
||||||
<FaUserCircle slot="icon"/>
|
<FaUserCircle slot="icon"/>
|
||||||
</CardsHeader>
|
</CardsHeader>
|
||||||
<Body bind:group bind:isPublic={isPublic}/>
|
<Body bind:item={group} bind:isPublic={isPublic} bind:loading={itemLoading[index]}/>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
{/each}
|
{/each}
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
Loading…
Reference in New Issue
Block a user