feat: creating groups! ✨
This commit is contained in:
		@@ -9,6 +9,7 @@
 | 
			
		||||
    import Body from './Body.svelte';
 | 
			
		||||
    import Svelecte, { addFormatter } from 'svelecte';
 | 
			
		||||
    import FaLock from 'svelte-icons/fa/FaLock.svelte';
 | 
			
		||||
    import NewGroup from './NewGroup.svelte';
 | 
			
		||||
 | 
			
		||||
    import { Member, Group } from '../../api/types';
 | 
			
		||||
    import api from '../../api';
 | 
			
		||||
@@ -168,6 +169,11 @@
 | 
			
		||||
  function updateDelete(event: any) {
 | 
			
		||||
      list = list.filter(group => group.id !== event.detail);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function addGroupToList(event: any) {
 | 
			
		||||
      list.push(event.detail);
 | 
			
		||||
      list = list;
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<Card class="mb-3">
 | 
			
		||||
@@ -278,6 +284,7 @@
 | 
			
		||||
    </Col>
 | 
			
		||||
</Row>
 | 
			
		||||
<ListPagination bind:currentPage bind:pageAmount />
 | 
			
		||||
<NewGroup on:create={addGroupToList} />
 | 
			
		||||
<Accordion class="my-3" stayOpen>
 | 
			
		||||
    {#each slicedList as group, index (group.id)}
 | 
			
		||||
        {#if (!isPublic && group.privacy.visibility === "public") || isPublic}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										163
									
								
								src/lib/group/NewGroup.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								src/lib/group/NewGroup.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
    import { Row, Col, Input, Button, Label, Alert, Spinner, Accordion, AccordionItem, CardTitle } from 'sveltestrap';
 | 
			
		||||
    import { Group } from '../../api/types';
 | 
			
		||||
    import api from '../../api';
 | 
			
		||||
    import autosize from 'svelte-autosize';
 | 
			
		||||
    import { createEventDispatcher } from 'svelte';
 | 
			
		||||
    import FaPlus from 'svelte-icons/fa/FaPlus.svelte';
 | 
			
		||||
 | 
			
		||||
    let loading: boolean = false;
 | 
			
		||||
    let err: string[] = [];
 | 
			
		||||
    let message: string;
 | 
			
		||||
    let privacyMode = false;
 | 
			
		||||
 | 
			
		||||
    let defaultGroup: Group = {
 | 
			
		||||
        privacy: {
 | 
			
		||||
            description_privacy: "public",
 | 
			
		||||
            metadata_privacy: "public",
 | 
			
		||||
            list_privacy: "public",
 | 
			
		||||
            icon_privacy: "public",
 | 
			
		||||
            name_privacy: "public",
 | 
			
		||||
            visibility: "public"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const dispatch = createEventDispatcher();
 | 
			
		||||
 | 
			
		||||
    function create() {
 | 
			
		||||
        dispatch('create', input);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let input: Group = defaultGroup;
 | 
			
		||||
 | 
			
		||||
    async function submit() {
 | 
			
		||||
        let data = input;
 | 
			
		||||
        message = "";
 | 
			
		||||
        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;
 | 
			
		||||
        try {
 | 
			
		||||
            let res = await api().groups().post({data});
 | 
			
		||||
            input = res;
 | 
			
		||||
            err = [];
 | 
			
		||||
            create();
 | 
			
		||||
            message = `Group ${data.name} successfully created!`
 | 
			
		||||
            loading = false;
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            console.log(error);
 | 
			
		||||
            err.push(error.message);
 | 
			
		||||
            err = err;
 | 
			
		||||
            loading = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<Accordion class="mb-3">
 | 
			
		||||
    <AccordionItem>
 | 
			
		||||
        <CardTitle slot="header" style="margin-top: 0px; margin-bottom: 0px; outline: none; align-items: center;" class="d-flex align-middle w-100 p-2">
 | 
			
		||||
            <div class="icon d-inline-block">
 | 
			
		||||
                <FaPlus/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <span style="vertical-align: middle;">Add new Group</span>
 | 
			
		||||
        </CardTitle>
 | 
			
		||||
        {#if message}
 | 
			
		||||
            <Alert color="success">{@html message}</Alert>
 | 
			
		||||
        {/if}
 | 
			
		||||
        {#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" />
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-2">
 | 
			
		||||
                <Label>Display name:</Label>
 | 
			
		||||
                <textarea class="form-control" style="resize: none; height: 1em" bind:value={input.display_name} maxlength={100} type="text"/>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-2">
 | 
			
		||||
                <Label>Color:</Label>
 | 
			
		||||
                <Input bind:value={input.color} type="text"/>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-2">
 | 
			
		||||
                <Label>Icon url:</Label>
 | 
			
		||||
                <Input bind:value={input.icon} maxlength={256} type="url"/>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-2">
 | 
			
		||||
                <Label>Banner url:</Label>
 | 
			
		||||
                <Input bind:value={input.banner} maxlength={256} type="url"/>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-2">
 | 
			
		||||
                <Label>Privacy:</Label>
 | 
			
		||||
                <Button class="w-100" color="secondary" on:click={() => privacyMode = !privacyMode}>Toggle privacy</Button>
 | 
			
		||||
            </Col>
 | 
			
		||||
        </Row>
 | 
			
		||||
        {#if privacyMode}
 | 
			
		||||
        <hr />
 | 
			
		||||
        <Row>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-3">
 | 
			
		||||
                <Label>Description:</Label>
 | 
			
		||||
                <Input type="select" bind:value={input.privacy.description_privacy}>
 | 
			
		||||
                    <option>public</option>
 | 
			
		||||
                    <option>private</option>
 | 
			
		||||
                </Input>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-3">
 | 
			
		||||
                <Label>Name:</Label>
 | 
			
		||||
                <Input type="select" bind:value={input.privacy.name_privacy}>
 | 
			
		||||
                    <option>public</option>
 | 
			
		||||
                    <option>private</option>
 | 
			
		||||
                </Input>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-3">
 | 
			
		||||
                <Label>Member list:</Label>
 | 
			
		||||
                <Input type="select" bind:value={input.privacy.list_privacy}>
 | 
			
		||||
                    <option>public</option>
 | 
			
		||||
                    <option>private</option>
 | 
			
		||||
                </Input>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-3">
 | 
			
		||||
                <Label>Icon:</Label>
 | 
			
		||||
                <Input type="select" bind:value={input.privacy.icon_privacy}>
 | 
			
		||||
                    <option>public</option>
 | 
			
		||||
                    <option>private</option>
 | 
			
		||||
                </Input>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-3">
 | 
			
		||||
                <Label>Visibility:</Label>
 | 
			
		||||
                <Input type="select" bind:value={input.privacy.visibility}>
 | 
			
		||||
                    <option>public</option>
 | 
			
		||||
                    <option>private</option>
 | 
			
		||||
                </Input>
 | 
			
		||||
            </Col>
 | 
			
		||||
            <Col xs={12} lg={4} class="mb-3">
 | 
			
		||||
                <Label>Metadata:</Label>
 | 
			
		||||
                <Input type="select" bind:value={input.privacy.metadata_privacy}>
 | 
			
		||||
                    <option>public</option>
 | 
			
		||||
                    <option>private</option>
 | 
			
		||||
                </Input>
 | 
			
		||||
            </Col>
 | 
			
		||||
        </Row>
 | 
			
		||||
        <hr />
 | 
			
		||||
        {/if}
 | 
			
		||||
        <div class="my-2">
 | 
			
		||||
            <b>Description:</b><br />
 | 
			
		||||
            <textarea class="form-control" bind:value={input.description} maxlength={1000} use:autosize />
 | 
			
		||||
        </div>
 | 
			
		||||
        {#if !loading && input.name}<Button style="flex: 0" color="primary" on:click={submit}>Submit</Button>
 | 
			
		||||
        {:else if !input.name }<Button style="flex: 0" color="primary" disabled>Submit</Button>
 | 
			
		||||
        {:else}<Button style="flex: 0" color="primary" disabled><Spinner size="sm"/></Button>{/if}
 | 
			
		||||
    </AccordionItem>
 | 
			
		||||
</Accordion>
 | 
			
		||||
		Reference in New Issue
	
	Block a user