Skip to content

Commit

Permalink
Merge pull request #104 from REAN-Foundation/notifications_change
Browse files Browse the repository at this point in the history
Notifications change
  • Loading branch information
dattatraya-inflection authored Dec 16, 2024
2 parents 4571f22 + 8effefd commit 45e91c9
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/lib/options/aha.options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const Options: FeatureOptions[] = [
},
//..............................
{
Name: 'Miscellaneous',
Name: 'Add-ons',
Enabled: true
},
{
Expand All @@ -147,7 +147,7 @@ export const Options: FeatureOptions[] = [
},
{
Name: 'Newsfeeds',
Enabled: true
Enabled: false
},
//..............................
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib/options/gmu.options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const Options: FeatureOptions[] = [
},
//..............................
{
Name: 'Miscellaneous',
Name: 'Add-ons',
Enabled: false
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/lib/options/rean.options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const Options: FeatureOptions[] = [
},
//..............................
{
Name: 'Miscellaneous',
Name: 'Add-ons',
Enabled: true
},
{
Expand Down
22 changes: 22 additions & 0 deletions src/lib/types/notification.topics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export enum NotificationTopics {
All_Users = 'All Users',
Cholesterol = 'Cholesterol',
Stroke = 'Stroke',
SMBP = 'SMBP',
CholesterolMini = 'Cholesterol Mini',
HFMotivator = 'HF Motivator',
KenyaMaternityPhase2 = 'Kenya Maternity Phase 2',
HeartFailure = 'Heart Failure'
}

export enum NotificationTypes{
General = 'General',
Email = 'Email',
SMS = 'SMS',
WebPush = 'Web Push',
MobilePush = 'Mobile Push',
Webhook = 'Webhook',
WhatsApp = 'Whats App',
Telegram = 'Telegram',
Slack = 'Slack',
}
19 changes: 19 additions & 0 deletions src/routes/api/services/reancare/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,22 @@ export const deleteNotification = async (sessionId: string, notificationId: stri
const url = BACKEND_API_URL + `/general/notifications/${notificationId}`;
return await del(sessionId, url, true, API_CLIENT_INTERNAL_KEY);
};

export const sendNotification = async (
sessionId: string,
topic:string,
title: string,
Body: string,
type: string,
url: string
) => {
const body = {
Topic: topic,
Title: title,
Body: Body ? Body : null,
Type: type ? type : null,
url: url ? url : null
};
const backendUrl = BACKEND_API_URL + '/user-device-details/notificaion-topic';
return await post(sessionId, backendUrl, body, true, API_CLIENT_INTERNAL_KEY);
};
87 changes: 72 additions & 15 deletions src/routes/users/[userId]/notifications/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,82 @@
import type { RequestEvent } from '@sveltejs/kit';
import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import { searchNotifications } from '../../../api/services/reancare/notifications';
import { createNotification, searchNotifications, sendNotification } from '../../../api/services/reancare/notifications';

////////////////////////////////////////////////////////////////////////////

export const load: PageServerLoad = async (event: RequestEvent) => {
const sessionId = event.cookies.get('sessionId');
// export const load: PageServerLoad = async (event: RequestEvent) => {
// const sessionId = event.cookies.get('sessionId');

try {
const response = await searchNotifications(sessionId);
if (response.Status === 'failure' || response.HttpCode !== 200) {
throw error(response.HttpCode, response.Message);
// try {
// const response = await searchNotifications(sessionId);
// if (response.Status === 'failure' || response.HttpCode !== 200) {
// throw error(response.HttpCode, response.Message);
// }
// const notification = response.Data.NotificationRecords;
// return {
// notification,
// sessionId,
// message: response.Message
// };
// } catch (error) {
// console.error(`Error retriving notification: ${error.message}`);
// }
// };

import { redirect } from 'sveltekit-flash-message/server';
import { z } from 'zod';
import { zfd } from 'zod-form-data';
import { errorMessage, successMessage } from '$lib/utils/message.utils';

/////////////////////////////////////////////////////////////////////////

const createNotificationSchema = zfd.formData({
topic: z.string(),
title: z.string().min(2).max(50),
body: z.string().min(2).max(150),
type: z.string().optional(),
url: z.string().optional()
});

export const actions = {
createNotificationAction: async (event: RequestEvent) => {
const request = event.request;
const userId = event.params.userId;
const sessionId = event.cookies.get('sessionId');
const formData = Object.fromEntries(await request.formData());
type NotificationSchema = z.infer<typeof createNotificationSchema>;
let result: NotificationSchema = {};
console.log('result', result);
try {
result = createNotificationSchema.parse(formData);
console.log('result', result);
} catch (err: any) {
const { fieldErrors: errors } = err.flatten();
console.log(errors);
const { ...rest } = formData;
return {
data: rest,
errors
};
}
const notification = response.Data.NotificationRecords;
return {
notification,
const response = await sendNotification(
sessionId,
message: response.Message
};
} catch (error) {
console.error(`Error retriving notification: ${error.message}`);
}
result.topic,
result.title,
result.body,
result.type,
result.url
);

if (response.Status === 'failure' || response.HttpCode !== 201) {
throw redirect(303, `/users/${userId}/notifications`, errorMessage(response.Message), event);
}
throw redirect(
303,
`/users/${userId}/notifications`,
successMessage(`Notification sent successfully!`),
event
);
}
};
164 changes: 155 additions & 9 deletions src/routes/users/[userId]/notifications/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<script lang="ts">
<!-- <script lang="ts">
import { browser } from '$app/environment';
import { page } from '$app/stores';
import BreadCrumbs from '$lib/components/breadcrumbs/breadcrums.svelte';
Expand Down Expand Up @@ -113,8 +113,8 @@
headers: { 'content-type': 'application/json' }
});
}
</script>

</script> -->
<!--
<BreadCrumbs crumbs={breadCrumbs} />
<div class="flex flex-wrap gap-2 mt-1">
Expand All @@ -133,8 +133,8 @@
class="input w-auto grow"
/>
<a href={createRoute} class="btn variant-filled-secondary">Add New</a>
</div>

</div> -->
<!--
<div class="table-container my-2 !border !border-secondary-100 dark:!border-surface-700">
<table class="table" role="grid">
<thead class="!variant-soft-secondary">
Expand Down Expand Up @@ -181,7 +181,7 @@
</a>
</td>
<td>
<!-- svelte-ignore missing-declaration -->
<Confirm
confirmTitle="Delete"
cancelTitle="Cancel"
Expand All @@ -202,8 +202,8 @@
{/if}
</tbody>
</table>
</div>

</div> -->
<!--
<div class="w-full variant-soft-secondary rounded-lg p-2">
<Paginator
bind:settings={paginationSettings}
Expand All @@ -214,4 +214,150 @@
controlVariant = 'rounded-full text-primary-500 '
controlSeparator = 'fill-primary-400'
/>
</div>
</div> -->

<script lang="ts">
import { enhance } from '$app/forms';
import { afterNavigate } from '$app/navigation';
import { page } from '$app/stores';
import BreadCrumbs from '$lib/components/breadcrumbs/breadcrums.svelte';
import { NotificationTopics, NotificationTypes } from '$lib/types/notification.topics.js';
import { showMessage } from '$lib/utils/message.utils';
import Icon from '@iconify/svelte';
////////////////////////////////////////////////////////////////////////////////////
export let form;
const userId = $page.params.userId;
const createRoute = `/users/${userId}/notifications/create`;
const notificationRoute = `/users/${userId}/notifications`;
const breadCrumbs = [
{ name: 'Notifications', path: notificationRoute, home: true }
// { name: 'Create', path: createRoute }
];
let topic: string, title: string, body: string, url: string;
const init = () => {
topic = 'All_Users';
title = '';
body = '';
url = '';
}
init();
afterNavigate(({from, to}) => {
init();
});
</script>

<BreadCrumbs crumbs={breadCrumbs} />

<form
method="post"
action="?/createNotificationAction"
class="table-container my-2 border border-secondary-100 dark:!border-surface-700"
use:enhance
>
<table class="table">
<thead class="!variant-soft-secondary">
<tr>
<th>Send Notification</th>
<th class="text-end">
<a
href={notificationRoute}
class="btn p-2 -my-2 variant-soft-secondary"
>
<Icon
icon="material-symbols:close-rounded"
class="text-lg"
/>
</a>
</th>
</tr>
</thead>
<tbody class="!bg-white dark:!bg-inherit">
<tr class="!border-b !border-b-secondary-100 dark:!border-b-surface-700">
<td>Topic *</td>
<td>
<select
class="select w-full"
name="topic"
placeholder="Select topic here..."
bind:value={topic}
>
{#each Object.entries(NotificationTopics) as [key, value]}
<option
value={key}
selected={key === 'All_Users'}>{value}</option
>
{/each}
</select>
</td>
</tr>
<tr class="!border-b !border-b-secondary-100 dark:!border-b-surface-700">
<td>Title *</td>
<td>
<input
type="text"
name="title"
required
bind:value={title}
placeholder="Enter title here..."
class="input w-full {form?.errors?.title ? 'border-error-300 text-error-500' : ''}"
minlength="2"
maxlength="50"
/>
{#if form?.errors?.title}
<p class="text-error-500 text-xs">{form?.errors?.title[0]}</p>
{/if}
</td>
</tr>
<tr class="!border-b !border-b-secondary-100 dark:!border-b-surface-700">
<td class="align-top">Body *</td>
<td>
<textarea
name="body"
placeholder="Enter body here..."
class="textarea"
required
bind:value={body}
minlength="2"
maxlength="150"
/>
</td>
</tr>
<!-- <tr class="!border-b !border-b-secondary-100 dark:!border-b-surface-700">
<td>Type *</td>
<td>
<select class="select w-full" name="type" placeholder="Select type here...">
{#each Object.entries(NotificationTypes) as [key, value]}
<option value={key} selected={key === 'General'}>{value}</option>
{/each}
</select>
</td>
</tr> -->
<tr class="!border-b !border-b-secondary-100 dark:!border-b-surface-700">
<td>Url</td>
<td>
<input
type="url"
name="url"
class="input w-full"
bind:value={url}
/>
</td>
</tr>
</tbody>
</table>
<div class="flex p-2 justify-end">
<button
type="submit"
class="btn variant-filled-secondary">Submit</button
>
</div>
</form>

0 comments on commit 45e91c9

Please sign in to comment.