fix: move feed state to a store and create feed loading UI (#189)
* style: Improved font size of the answers in the FAQ section of the landing page * feat: move all email to defer queue (#186) * fix: use relative part for defer func #185 * chore: move sendEmail into defer * fix: remove anon function to defer #185 * feat: implement batch email sending with defer.run #185 * chore: debug sendEmails #185 * chore: add robots.txt * chore: use promise.all in sendEmails * chore: debug defer sendEmails #185 * chore: try defer sendEmail without loop #105 * chore: comment code * chore: change loop style #185 * chore: use promise.all for vercel edge #185 * Moved the feed state to a store and added a loader * feat: add await to sendEmailNotification #185 * chore: use sendEmails #185 * fix: debug sendEmails #185 * fix: email not updating in LMS * fix: remove early return in sendEmails #185 * fixed the edit bug and moved the loader state to the file * added a loading state for the post button * change isDisabled to isLoading --------- Co-authored-by: Rotimi Best <best@classroomio.com>
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
toggleFeedIsPinned,
|
||||
fetchNewsFeedReaction
|
||||
} from '$lib/utils/services/newsfeed';
|
||||
import { newsFeed } from '$lib/components/Course/components/NewsFeed/store';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import { supabase } from '$lib/utils/functions/supabase';
|
||||
import { snackbar } from '$lib/components/Snackbar/store';
|
||||
@@ -28,11 +29,12 @@
|
||||
NOTIFICATION_NAME,
|
||||
triggerSendEmail
|
||||
} from '$lib/utils/services/notification/notification';
|
||||
|
||||
import NewsFeedLoader from '$lib/components/Course/components/NewsFeed/NewsFeedLoader.svelte';
|
||||
export let data;
|
||||
|
||||
let createdComment;
|
||||
let edit = false;
|
||||
let isLoading = false;
|
||||
let editFeed: Feed;
|
||||
let author = {
|
||||
id: '',
|
||||
@@ -40,14 +42,14 @@
|
||||
fullname: '',
|
||||
avatar_url: ''
|
||||
};
|
||||
let newsFeed: Feed[] = [];
|
||||
|
||||
let query = new URLSearchParams($page.url.search);
|
||||
let feedId = query.get('feedId') || '';
|
||||
|
||||
const onEdit = (id: string, content: string) => {
|
||||
handleEditFeed(id, content);
|
||||
|
||||
newsFeed = newsFeed.map((feed) => {
|
||||
$newsFeed = $newsFeed.map((feed) => {
|
||||
if (feed.id === id) {
|
||||
return { ...feed, content: content };
|
||||
}
|
||||
@@ -58,7 +60,7 @@
|
||||
|
||||
const deleteComment = (id: string) => {
|
||||
deleteNewsFeedComment(id);
|
||||
newsFeed = newsFeed.flatMap((feed) => ({
|
||||
$newsFeed = $newsFeed.flatMap((feed) => ({
|
||||
...feed,
|
||||
comment: feed.comment.filter((comment) => comment.id !== id)
|
||||
}));
|
||||
@@ -71,7 +73,7 @@
|
||||
|
||||
if (!data) return;
|
||||
|
||||
const reactedFeed = data || newsFeed.find((feed) => feed.id === feedId);
|
||||
const reactedFeed = data || $newsFeed.find((feed) => feed.id === feedId);
|
||||
|
||||
let reactedAuthorIds: string[] = reactedFeed.reaction[reactionType];
|
||||
|
||||
@@ -99,7 +101,7 @@
|
||||
return snackbar.error('An error occurred while reacting to news feed');
|
||||
}
|
||||
|
||||
newsFeed = newsFeed.map((feed) => {
|
||||
$newsFeed = $newsFeed.map((feed) => {
|
||||
if (feed.id === feedId) {
|
||||
feed.reaction = reactedFeed.reaction;
|
||||
}
|
||||
@@ -129,7 +131,7 @@
|
||||
comment
|
||||
});
|
||||
|
||||
newsFeed = newsFeed.map((feed) => {
|
||||
$newsFeed = $newsFeed.map((feed) => {
|
||||
if (feed.id === feedId) {
|
||||
const newComment = {
|
||||
id: createdComment.id,
|
||||
@@ -160,7 +162,7 @@
|
||||
return snackbar.error('Failed to toggle pinned feed');
|
||||
}
|
||||
|
||||
newsFeed = newsFeed.map((feed) => {
|
||||
$newsFeed = $newsFeed.map((feed) => {
|
||||
if (feed.id === feedId) {
|
||||
snackbar.success(`${newIsPinned ? 'Pinned' : 'Unpinned'} Successfully`);
|
||||
|
||||
@@ -175,28 +177,31 @@
|
||||
const deleteFeed = (id: string) => {
|
||||
deleteNewsFeed(id);
|
||||
|
||||
const deletedFeed = newsFeed.filter((feed) => feed.id !== id);
|
||||
const deletedFeed = $newsFeed.filter((feed) => feed.id !== id);
|
||||
snackbar.success('Feed deleted successfully');
|
||||
|
||||
newsFeed = deletedFeed;
|
||||
$newsFeed = deletedFeed;
|
||||
};
|
||||
|
||||
const initNewsFeed = async (courseId: string) => {
|
||||
if (!courseId) return;
|
||||
|
||||
const { data, error } = await fetchNewsFeeds(courseId);
|
||||
|
||||
if (error) {
|
||||
snackbar.error('Failed to fetch news feeds');
|
||||
return;
|
||||
try {
|
||||
isLoading = true;
|
||||
const { data, error } = await fetchNewsFeeds(courseId);
|
||||
if (error) {
|
||||
snackbar.error('Failed to fetch news feeds');
|
||||
}
|
||||
if (data) {
|
||||
$newsFeed = data.map((feedItem) => ({
|
||||
...feedItem,
|
||||
isPinned: feedItem.is_pinned
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
snackbar.error('An error occured while fetching feed');
|
||||
} finally {
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
if (!data) return;
|
||||
|
||||
newsFeed = data.map((feedItem) => ({
|
||||
...feedItem,
|
||||
isPinned: feedItem.is_pinned
|
||||
}));
|
||||
};
|
||||
|
||||
function setAuthor(groups, profileId) {
|
||||
@@ -214,7 +219,7 @@
|
||||
|
||||
$: setAuthor($group, $profile.id);
|
||||
|
||||
$: newsFeed = newsFeed.sort((a, b) => Number(b.isPinned) - Number(a.isPinned));
|
||||
$: $newsFeed = $newsFeed.sort((a, b) => Number(b.isPinned) - Number(a.isPinned));
|
||||
</script>
|
||||
|
||||
<CourseContainer bind:courseId={data.courseId}>
|
||||
@@ -234,13 +239,18 @@
|
||||
bind:edit
|
||||
bind:editFeed
|
||||
onSave={(newFeed) => {
|
||||
newsFeed = [newFeed, ...newsFeed];
|
||||
$newsFeed = [newFeed, ...$newsFeed];
|
||||
}}
|
||||
{onEdit}
|
||||
/>
|
||||
</RoleBasedSecurity>
|
||||
|
||||
{#if !newsFeed.length}
|
||||
{#if isLoading}
|
||||
<div>
|
||||
<NewsFeedLoader />
|
||||
<NewsFeedLoader />
|
||||
<NewsFeedLoader />
|
||||
</div>
|
||||
{:else if !$newsFeed.length}
|
||||
<Box>
|
||||
<div class="flex justify-between flex-col items-center w-[90%] md:w-96">
|
||||
<img src="/images/empty-lesson-icon.svg" alt="Lesson" class="my-2.5 mx-auto" />
|
||||
@@ -251,7 +261,7 @@
|
||||
</div>
|
||||
</Box>
|
||||
{:else}
|
||||
{#each newsFeed as feed}
|
||||
{#each $newsFeed as feed}
|
||||
{#if feed.isPinned}
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<PinFilled size={16} />
|
||||
|
||||
Reference in New Issue
Block a user