auto save, poll and comments improvements
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
commentAt: new Date()
|
||||
}
|
||||
];
|
||||
$lesson.totalComments = comments.length;
|
||||
scrollToBottom();
|
||||
|
||||
isSaving = true;
|
||||
@@ -65,9 +66,8 @@
|
||||
})
|
||||
.then(() => {
|
||||
isSaving = false;
|
||||
});
|
||||
|
||||
comment = '';
|
||||
});
|
||||
}
|
||||
|
||||
function handleKeyDown(e: KeyboardEvent) {
|
||||
@@ -212,7 +212,7 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<article class="prose prose-sm sm:prose ml-8 max-w-[300px]">
|
||||
<article class="prose prose-sm sm:prose ml-8 max-w-[300px] dark:text-white">
|
||||
{comment.comment}
|
||||
</article>
|
||||
</div>
|
||||
|
||||
@@ -1,46 +1,47 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import FormSection from './FormSection.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import type { Poll } from '../types';
|
||||
|
||||
export let title = 'Poll';
|
||||
export let onSubmit;
|
||||
export let onCancel;
|
||||
export let onSubmit = (p: Poll) => {};
|
||||
export let onCancel = () => {};
|
||||
|
||||
let values = {
|
||||
let poll: Poll = {
|
||||
question: '',
|
||||
author: '',
|
||||
authorId: '',
|
||||
isPublic: false,
|
||||
expiration: '',
|
||||
options: [
|
||||
{
|
||||
label: '',
|
||||
selectedBy: [],
|
||||
},
|
||||
],
|
||||
selectedBy: []
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
function handleAddOptions() {
|
||||
values = {
|
||||
...values,
|
||||
poll = {
|
||||
...poll,
|
||||
options: [
|
||||
...values.options,
|
||||
...poll.options,
|
||||
{
|
||||
label: '',
|
||||
selectedBy: [],
|
||||
},
|
||||
],
|
||||
selectedBy: []
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
function handleRemoveOptions(index) {
|
||||
function handleRemoveOptions(index: number) {
|
||||
return () => {
|
||||
values.options = values.options.filter((o, i) => i !== index);
|
||||
poll.options = poll.options.filter((o, i) => i !== index);
|
||||
};
|
||||
}
|
||||
|
||||
function finishPoll() {
|
||||
onSubmit(values);
|
||||
onSubmit(poll);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -49,16 +50,23 @@
|
||||
{title}
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<FormSection label="Question" bind:value={values.question} />
|
||||
<FormSection
|
||||
label="Question"
|
||||
bind:value={poll.question}
|
||||
handleLabelButton={undefined}
|
||||
handleInputButton={undefined}
|
||||
/>
|
||||
<FormSection
|
||||
label="Expiration"
|
||||
bind:value={values.expiration}
|
||||
bind:value={poll.expiration}
|
||||
type="date"
|
||||
handleLabelButton={undefined}
|
||||
handleInputButton={undefined}
|
||||
/>
|
||||
|
||||
{#each values.options as option, index}
|
||||
{#each poll.options as option, index}
|
||||
<FormSection
|
||||
label={index === 0 && 'Options'}
|
||||
label={index === 0 ? 'Options' : ''}
|
||||
bind:value={option.label}
|
||||
handleLabelButton={handleAddOptions}
|
||||
handleInputButton={handleRemoveOptions(index)}
|
||||
@@ -68,10 +76,6 @@
|
||||
|
||||
<div class="w-full flex justify-center mb-3">
|
||||
<PrimaryButton label="Create poll" onClick={finishPoll} />
|
||||
<PrimaryButton
|
||||
label="Cancel"
|
||||
variant={VARIANTS.OUTLINED}
|
||||
onClick={onCancel}
|
||||
/>
|
||||
<PrimaryButton label="Cancel" variant={VARIANTS.OUTLINED} onClick={onCancel} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
<script>
|
||||
export let value;
|
||||
export let label;
|
||||
<script lang="ts">
|
||||
export let value: string | Date;
|
||||
export let label: string;
|
||||
export let type = 'text';
|
||||
export let name = 'text';
|
||||
export let handleLabelButton;
|
||||
export let handleInputButton;
|
||||
export let handleLabelButton: undefined | (() => void);
|
||||
export let handleInputButton: undefined | (() => void);
|
||||
</script>
|
||||
|
||||
<div class="mb-3">
|
||||
{#if label}
|
||||
<p
|
||||
class="dark:text-white p-0 m-0 mb-1 uppercase text-sm font-bold text-gray-600"
|
||||
>
|
||||
<p class="dark:text-white p-0 m-0 mb-1 uppercase text-sm font-bold text-gray-600">
|
||||
{label}
|
||||
|
||||
{#if typeof handleLabelButton === 'function'}
|
||||
<button class="text-xl px-3 ml-5" on:click={handleLabelButton}>
|
||||
+
|
||||
</button>
|
||||
<button class="text-xl px-3 ml-5" on:click={handleLabelButton}> + </button>
|
||||
{/if}
|
||||
</p>
|
||||
{/if}
|
||||
@@ -32,9 +28,7 @@
|
||||
{/if}
|
||||
|
||||
{#if typeof handleInputButton === 'function'}
|
||||
<button class="text-xl px-3 ml-5" on:click={handleInputButton}>
|
||||
-
|
||||
</button>
|
||||
<button class="text-xl px-3 ml-5" on:click={handleInputButton}> - </button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
</div>
|
||||
|
||||
<Label>Responses</Label>
|
||||
{#each poll.options as option, index}
|
||||
{#each poll.options as option}
|
||||
<div class="border-b p-5">
|
||||
<p class="dark:text-white">
|
||||
{option.label}
|
||||
@@ -140,7 +140,7 @@
|
||||
{:else}
|
||||
{#each poll.options as option, index}
|
||||
<button
|
||||
class="bg-white dark:bg-black rounded-md border-2 border-gray-500 {didUserSelect(
|
||||
class="bg-white dark:bg-black rounded-md border-2 border-gray-500 h-[50px] {didUserSelect(
|
||||
option
|
||||
) &&
|
||||
'focus:border-primary-700 border-primary-700'} text-black p-2 w-full mb-3 text-left relative"
|
||||
@@ -153,9 +153,11 @@
|
||||
: 'bg-gray-300'} h-full bg-opacity-25"
|
||||
style="width: {calculatePercent(poll.options, option)}%;"
|
||||
/>
|
||||
<strong class="mr-3">{calculatePercent(poll.options, option)}%</strong>
|
||||
{/if}
|
||||
<p class="absolute top-3 text-black left-2">
|
||||
{option.label}
|
||||
({calculatePercent(poll.options, option)}%)
|
||||
</p>
|
||||
</button>
|
||||
{/each}
|
||||
<div class="flex items-center">
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
];
|
||||
|
||||
let selectedTab = 0;
|
||||
let userId = users[0].value;
|
||||
let userId = 'satoshi-nakamoto';
|
||||
let shouldCreatePoll = false;
|
||||
let polls = [
|
||||
{
|
||||
@@ -92,7 +92,11 @@
|
||||
polls = [
|
||||
{
|
||||
...poll,
|
||||
author: users.find((u) => u.value === userId)
|
||||
author: {
|
||||
label: 'Satoshi Nakamoto',
|
||||
value: 'satoshi-nakamoto',
|
||||
avatar: 'https://i.pravatar.cc/150?img=4'
|
||||
}
|
||||
},
|
||||
...polls
|
||||
];
|
||||
@@ -122,7 +126,11 @@
|
||||
// Select if already selected
|
||||
option.selectedBy = [
|
||||
...option.selectedBy,
|
||||
users.find((user) => user.value === userId)
|
||||
{
|
||||
label: 'Satoshi Nakamoto',
|
||||
value: 'satoshi-nakamoto',
|
||||
avatar: 'https://i.pravatar.cc/150?img=4'
|
||||
}
|
||||
];
|
||||
}
|
||||
} else if (option.selectedBy.find((user) => user.value === userId)) {
|
||||
@@ -147,7 +155,7 @@
|
||||
</div>
|
||||
</PageNav>
|
||||
|
||||
<div class="m-2 overlow-y-auto min-w-[300px]">
|
||||
<div class="m-2 overlow-y-auto min-w-[350px]">
|
||||
{#if shouldCreatePoll}
|
||||
<CreatePollForm onSubmit={handlePollCreate} onCancel={handleCreatePoll} />
|
||||
{:else}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
export type Poll = {
|
||||
question: string;
|
||||
authorId: string; // groupmember_id
|
||||
isPublic: boolean;
|
||||
expiration: string | Date;
|
||||
options: {
|
||||
label: string;
|
||||
selectedBy: {
|
||||
id: string;
|
||||
fullname: string;
|
||||
avatarUrl: string;
|
||||
}[];
|
||||
}[];
|
||||
};
|
||||
@@ -170,6 +170,9 @@
|
||||
_isLoading?: boolean,
|
||||
lessonId?: string
|
||||
) {
|
||||
// don't autosave on view mode
|
||||
if (mode === MODES.view) return;
|
||||
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
console.log('autosaving');
|
||||
if (!initAutoSave) {
|
||||
|
||||
Reference in New Issue
Block a user