From e56983dc4f50814b5f9b7082d45bdf5b8f889473 Mon Sep 17 00:00:00 2001 From: matthieu42morin Date: Wed, 22 Mar 2023 07:20:30 +0100 Subject: [PATCH] preferencesPage updated - solved fetching, selection functionality needed Changes to be committed: modified: .eslintrc.cjs modified: public/serviceworker.js modified: public/serviceworker_notused.js modified: src/__routes.svelte modified: src/lib/collections.ts modified: src/lib/components/Categories/category2InRow.svelte modified: src/lib/components/Categories/category3InRow.svelte new file: src/lib/router/LazyRoute.svelte new file: src/lib/router/ProtectedRouteGuard.svelte new file: src/lib/router/routes.ts modified: src/lib/utils/database/experience.ts modified: src/lib/utils/database/preferences.ts modified: src/lib/utils/parseQuestion.js modified: src/main.js modified: src/routes/onboarding/interestsPage.svelte new file: src/routes/onboarding/preferencesPage.svelte modified: src/routes/profile/functions/Interests-Update.svelte modified: tailwind.config.cjs --- .eslintrc.cjs | 22 +-- public/serviceworker.js | 54 +----- public/serviceworker_notused.js | 55 +++++- src/__routes.svelte | 2 +- src/lib/collections.ts | 8 +- .../Categories/category2InRow.svelte | 17 ++ .../Categories/category3InRow.svelte | 17 ++ src/lib/router/LazyRoute.svelte | 12 ++ src/lib/router/ProtectedRouteGuard.svelte | 12 ++ src/lib/router/routes.ts | 29 +++ src/lib/utils/database/experience.ts | 2 +- src/lib/utils/database/preferences.ts | 81 ++++++-- src/lib/utils/parseQuestion.js | 26 +-- src/main.js | 2 +- src/routes/onboarding/interestsPage.svelte | 49 +++-- src/routes/onboarding/preferencesPage.svelte | 181 ++++++++++++++++++ .../profile/functions/Interests-Update.svelte | 4 +- tailwind.config.cjs | 12 +- 18 files changed, 459 insertions(+), 126 deletions(-) create mode 100644 src/lib/router/LazyRoute.svelte create mode 100644 src/lib/router/ProtectedRouteGuard.svelte create mode 100644 src/lib/router/routes.ts create mode 100644 src/routes/onboarding/preferencesPage.svelte diff --git a/.eslintrc.cjs b/.eslintrc.cjs index ceaea72..35e5471 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,13 +1,13 @@ module.exports = { - env: { - browser: true, - es2021: true, - }, - extends: 'standard-with-typescript', - overrides: [], - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - }, - rules: {}, + env: { + browser: true, + es2021: true + }, + extends: 'standard-with-typescript', + overrides: [], + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module' + }, + rules: {} } diff --git a/public/serviceworker.js b/public/serviceworker.js index 1565554..47999f8 100644 --- a/public/serviceworker.js +++ b/public/serviceworker.js @@ -1,54 +1,4 @@ -// This is the service worker with the combined offline experience (Offline page + Offline copy of pages) -import workbox from 'workbox-sw' -const CACHE = 'pwabuilder-offline-page' +self.addEventListener('install', (e) => { }) -importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.4/workbox-sw.js') - -// TODO: replace the following with the correct offline fallback page i.e.: const offlineFallbackPage = "offline.html"; -const offlineFallbackPage = '/offline.html' - -self.addEventListener('message', (event) => { - if (event.data && event.data.type === 'SKIP_WAITING') { - self.skipWaiting() - } -}) - -self.addEventListener('install', async (event) => { - event.waitUntil( - caches.open(CACHE) - .then((cache) => cache.add(offlineFallbackPage)) - ) -}) - -if (workbox.navigationPreload.isSupported()) { - workbox.navigationPreload.enable() -} - -workbox.routing.registerRoute( - /\/*/, - new workbox.strategies.StaleWhileRevalidate({ - cacheName: CACHE - }) -) - -self.addEventListener('fetch', (event) => { - if (event.request.mode === 'navigate') { - event.respondWith((async () => { - try { - const preloadResp = await event.preloadResponse - - if (preloadResp) { - return preloadResp - } - - const networkResp = await fetch(event.request) - return networkResp - } catch (error) { - const cache = await caches.open(CACHE) - const cachedResp = await cache.match(offlineFallbackPage) - return cachedResp - } - })()) - } -}) +self.addEventListener('fetch', (e) => { }) diff --git a/public/serviceworker_notused.js b/public/serviceworker_notused.js index e1b62bc..3a1ae7e 100644 --- a/public/serviceworker_notused.js +++ b/public/serviceworker_notused.js @@ -1,4 +1,55 @@ -//self.addEventListener("install", (e) => { }) +// This is the service worker with the combined offline experience (Offline page + Offline copy of pages) +import workbox from 'workbox-sw' -//self.addEventListener('fetch', (e) => { }) +const CACHE = 'pwabuilder-offline-page' + +importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.4/workbox-sw.js') + +// TODO: replace the following with the correct offline fallback page i.e.: const offlineFallbackPage = "offline.html"; +const offlineFallbackPage = '/offline.html' + +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting() + } +}) + +self.addEventListener('install', async (event) => { + event.waitUntil( + caches.open(CACHE) + .then((cache) => cache.add(offlineFallbackPage)) + ) +}) + +if (workbox.navigationPreload.isSupported()) { + workbox.navigationPreload.enable() +} + +workbox.routing.registerRoute( + /\/*/, + new workbox.strategies.StaleWhileRevalidate({ + cacheName: CACHE + }) +) + +self.addEventListener('fetch', (event) => { + if (event.request.mode === 'navigate') { + event.respondWith((async () => { + try { + const preloadResp = await event.preloadResponse + + if (preloadResp) { + return preloadResp + } + + const networkResp = await fetch(event.request) + return networkResp + } catch (error) { + const cache = await caches.open(CACHE) + const cachedResp = await cache.match(offlineFallbackPage) + return cachedResp + } + })()) + } +}) diff --git a/src/__routes.svelte b/src/__routes.svelte index 147c622..d18bca5 100644 --- a/src/__routes.svelte +++ b/src/__routes.svelte @@ -102,7 +102,7 @@ }, { path: '/preferences', - component: () => import('$root/src/routes/onboarding/interestsPage.svelte'), + component: () => import('$root/src/routes/onboarding/preferencesPage.svelte'), }, ]} /> diff --git a/src/lib/collections.ts b/src/lib/collections.ts index 605ac88..115f385 100644 --- a/src/lib/collections.ts +++ b/src/lib/collections.ts @@ -2,10 +2,14 @@ import { Collection } from './appwrite' const experiences = new Collection('63cef30d6da945dd4250', '63cef4bd210fdf2e5888') const users = new Collection('63ded6c18e8493bffc83', 'Users') -const categories = new Collection('63cef30d6da945dd4250', '63cef4bd210fdf2e5888') +const interests = new Collection('6417cf1de159d094b370', '6417cf29f2118829b3b4') +const travel_with = new Collection('6417cf1de159d094b370', '6417d0429843609a2f49') +const recommended_by = new Collection('6417cf1de159d094b370', '6417d00e40701375978b') export default { experiences, users, - categories, + interests, + travel_with, + recommended_by } diff --git a/src/lib/components/Categories/category2InRow.svelte b/src/lib/components/Categories/category2InRow.svelte index e69de29..7b50c49 100644 --- a/src/lib/components/Categories/category2InRow.svelte +++ b/src/lib/components/Categories/category2InRow.svelte @@ -0,0 +1,17 @@ + + +
+ {#each preferences as preference} +
onPreferenceSelect(preference)} + > + {preference.name} +
+ {/each} +
+ \ No newline at end of file diff --git a/src/lib/components/Categories/category3InRow.svelte b/src/lib/components/Categories/category3InRow.svelte index e69de29..1308f43 100644 --- a/src/lib/components/Categories/category3InRow.svelte +++ b/src/lib/components/Categories/category3InRow.svelte @@ -0,0 +1,17 @@ + + +
+ {#each preferences as preference} +
onPreferenceSelect(preference)} + > + {preference.name} +
+ {/each} +
+ \ No newline at end of file diff --git a/src/lib/router/LazyRoute.svelte b/src/lib/router/LazyRoute.svelte new file mode 100644 index 0000000..55d8ec2 --- /dev/null +++ b/src/lib/router/LazyRoute.svelte @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/src/lib/router/ProtectedRouteGuard.svelte b/src/lib/router/ProtectedRouteGuard.svelte new file mode 100644 index 0000000..8669fff --- /dev/null +++ b/src/lib/router/ProtectedRouteGuard.svelte @@ -0,0 +1,12 @@ + +{#if allow} + +{:else} + +{/if} \ No newline at end of file diff --git a/src/lib/router/routes.ts b/src/lib/router/routes.ts new file mode 100644 index 0000000..53d3136 --- /dev/null +++ b/src/lib/router/routes.ts @@ -0,0 +1,29 @@ +import { ComponentType, SvelteComponentTyped } from 'svelte' + +export interface Route { + component: () => Promise, + path: string, + layout?: ComponentType>, + loading?: ComponentType>, + before?: () => any, +} + +interface RouteDefinition { + component: () => Promise, + path: string, + layout: ComponentType> | null, + loading: ComponentType> | null, + before: () => any | null, +} + +interface RouteConfig { + routes: Route[], + layout?: ComponentType> | null, + loading?: ComponentType> | null, +} + +const defineRoutes = (config: RouteConfig): RouteDefinition[] => { + return config.routes.map(route => ({ ...route, layout: route?.layout ?? config?.layout ?? null, loading: route?.loading ?? config?.loading ?? null, before: route?.before ?? null })) +} + +export default defineRoutes \ No newline at end of file diff --git a/src/lib/utils/database/experience.ts b/src/lib/utils/database/experience.ts index 665bc86..b8dff83 100644 --- a/src/lib/utils/database/experience.ts +++ b/src/lib/utils/database/experience.ts @@ -2,7 +2,7 @@ import { databases } from '$lib/appwrite' import { Query } from 'appwrite' import database from 'svelte-appwrite-client/src/lib/database' import { getLocationDataFromLatAndLong } from '../locations' -import { writable } from 'svelte/store' +import { writable } from '$lib/stores/stores' import { CheckPoint, Experience } from '$lib/TStypes/experiences' //Loading of checkpoints and rating is done in the same function to prevent multiple requests to the database diff --git a/src/lib/utils/database/preferences.ts b/src/lib/utils/database/preferences.ts index 85ec74c..35548e1 100644 --- a/src/lib/utils/database/preferences.ts +++ b/src/lib/utils/database/preferences.ts @@ -1,25 +1,76 @@ import { databases } from '$lib/appwrite'; import { Query } from 'appwrite'; -export const getPreferences = async () => { - const { documents } = await databases.listDocuments('6417cf1de159d094b370', '6417cf29f2118829b3b4', [ - Query.orderAsc('Name') - ]); +// typescript interfaces for objects return definitions +interface Interest { + name: string; + img: string; + } + interface TravelBuddies { + name: string; + img: string; + } +interface Recommendations { + name: string; + img: string; + } - const preferences = documents.map(({ Name, Image }) => ({ name: Name, img: Image })); + // Define a variable to store the selected preferences + let selectedInterests = []; + let selectedTravelBuddies = []; + let selectedRecommendations = []; - return preferences; -}; +// fetch interests +export const getInterests = async (): Promise => { + return ((await databases.listDocuments('6417cf1de159d094b370', '6417cf29f2118829b3b4')).documents as unknown as Interest[])}; -export const addSelectedPreferences = async (userId, preferences) => { - const { document: user } = await databases.getDocument('63ded6c18e8493bffc83', 'Users', userId); - const updatedUser = { - ...user, - userPreferences: preferences +// fetch travel buddies +export const getTravelBuddies = async (): Promise => { + return ((await databases.listDocuments('6417cf1de159d094b370', '6417d0429843609a2f49')).documents as unknown as TravelBuddies[])}; + +// fetch recommendations +export const getRecommendations = async (): Promise => { + return ((await databases.listDocuments('6417cf1de159d094b370', '6417d00e40701375978b')).documents as unknown as Recommendations[])}; + + // add selected preferences to user +export const addSelectedPreferences = async (userId, interests, travelBuddies, recommendations) => { + const { document: user } = await databases.getDocument('63ded6c18e8493bffc83', 'Users', userId); + + const updatedUser = { + ...user, + userInterests: interests, + userTravelBuddy: travelBuddies, + userRecommended: recommendations + }; + + await databases.updateDocument('63ded6c18e8493bffc83', 'Users', user.$id, updatedUser); + + return updatedUser; }; - await databases.updateDocument('6417cf1de159d094b370', 'user-collection', user.$id, updatedUser); +// // Function to update Interests +// function updateSelectedInterests(preference) { +// if (selectedInterests.includes(preference)) { +// selectedInterests = selectedInterests.filter((item) => item !== preference); +// } else { +// selectedInterests = [...selectedInterests, preference]; +// } +// } +// // Function to update Travel Buddies +// function updateSelectedTravelBuddies(preference) { +// if (selectedTravelBuddies.includes(preference)) { +// selectedTravelBuddies = selectedTravelBuddies.filter((item) => item !== preference); +// } else { +// selectedTravelBuddies = [...selectedTravelBuddies, preference]; +// } +// } +// // Function to update Recommendations +// function updateSelectedRecommendations(preference) { +// if (selectedRecommendations.includes(preference)) { +// selectedRecommendations = selectedRecommendations.filter((item) => item !== preference); +// } else { +// selectedRecommendations = [...selectedRecommendations, preference]; +// } +// } - return updatedUser; -}; \ No newline at end of file diff --git a/src/lib/utils/parseQuestion.js b/src/lib/utils/parseQuestion.js index c6e0a00..35d728d 100644 --- a/src/lib/utils/parseQuestion.js +++ b/src/lib/utils/parseQuestion.js @@ -1,15 +1,15 @@ export default (question, questionType) => { - switch (questionType.toLowerCase()) { - case 'text': - return question - case 'number': - return Number.parseFloat(question) - case 'choice': - return question.split(/;\s*/).map((item) => ({ - label: item.startsWith('*') ? item.substring(1) : item, - value: item.startsWith('*') ? true : false, - })) - default: - return null - } + switch (questionType.toLowerCase()) { + case 'text': + return question + case 'number': + return Number.parseFloat(question) + case 'choice': + return question.split(/;\s*/).map((item) => ({ + label: item.startsWith('*') ? item.substring(1) : item, + value: !!item.startsWith('*') + })) + default: + return null + } } diff --git a/src/main.js b/src/main.js index 91f9d88..5c1f795 100644 --- a/src/main.js +++ b/src/main.js @@ -2,7 +2,7 @@ import './app.css' import App from './App.svelte' const app = new App({ - target: document.getElementById('app'), + target: document.getElementById('app') }) export default app diff --git a/src/routes/onboarding/interestsPage.svelte b/src/routes/onboarding/interestsPage.svelte index 376ba14..8606c9c 100644 --- a/src/routes/onboarding/interestsPage.svelte +++ b/src/routes/onboarding/interestsPage.svelte @@ -1,36 +1,43 @@ @@ -39,21 +46,21 @@

What are your interests?

Who do you like to travel with?

What brought you to our app?

{:else} - + {/if} diff --git a/src/routes/onboarding/preferencesPage.svelte b/src/routes/onboarding/preferencesPage.svelte new file mode 100644 index 0000000..1b818ce --- /dev/null +++ b/src/routes/onboarding/preferencesPage.svelte @@ -0,0 +1,181 @@ + + +
+ {#each preferences as pref} + {#if pref.id === selectedPrefId} +
+
+

{pref.title}

+
+ {#each pref.options as option} + + {/each} +
+ {#if pref.selectedOption} + + {/if} +
+
+ {/if} + {/each} + {#if selectedPrefId === preferences.length && preferences.every(pref => pref.selectedOption)} + + {/if} +
+ + + + \ No newline at end of file diff --git a/src/routes/profile/functions/Interests-Update.svelte b/src/routes/profile/functions/Interests-Update.svelte index e16531d..5be4bfd 100644 --- a/src/routes/profile/functions/Interests-Update.svelte +++ b/src/routes/profile/functions/Interests-Update.svelte @@ -50,7 +50,9 @@ .selected{ transition-delay: 0.25s; width: 46px; - background-color: #14A6AE; + outline: 8px solid #BBD1C5; + outline-color: #14A6AE; + border-radius: 16px; } } diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 129a8ec..b956c20 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -1,9 +1,9 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ['./index.html', './src/**/*.{html,svelte,js,ts}', './node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'], - theme: { - extend: {}, - }, - plugins: [require('flowbite/plugin')], - darkMode: 'class', + content: ['./index.html', './src/**/*.{html,svelte,js,ts}', './node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'], + theme: { + extend: {} + }, + plugins: [require('flowbite/plugin')], + darkMode: 'class' }