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
This commit is contained in:
parent
9aab42db08
commit
e56983dc4f
|
@ -1,13 +1,13 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
es2021: true,
|
es2021: true
|
||||||
},
|
},
|
||||||
extends: 'standard-with-typescript',
|
extends: 'standard-with-typescript',
|
||||||
overrides: [],
|
overrides: [],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaVersion: 'latest',
|
ecmaVersion: 'latest',
|
||||||
sourceType: 'module',
|
sourceType: 'module'
|
||||||
},
|
},
|
||||||
rules: {},
|
rules: {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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')
|
self.addEventListener('fetch', (e) => { })
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
})())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
})())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/preferences',
|
path: '/preferences',
|
||||||
component: () => import('$root/src/routes/onboarding/interestsPage.svelte'),
|
component: () => import('$root/src/routes/onboarding/preferencesPage.svelte'),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -2,10 +2,14 @@ import { Collection } from './appwrite'
|
||||||
|
|
||||||
const experiences = new Collection('63cef30d6da945dd4250', '63cef4bd210fdf2e5888')
|
const experiences = new Collection('63cef30d6da945dd4250', '63cef4bd210fdf2e5888')
|
||||||
const users = new Collection('63ded6c18e8493bffc83', 'Users')
|
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 {
|
export default {
|
||||||
experiences,
|
experiences,
|
||||||
users,
|
users,
|
||||||
categories,
|
interests,
|
||||||
|
travel_with,
|
||||||
|
recommended_by
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let preferences;
|
||||||
|
export let onPreferenceSelect;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="category-2-in-row">
|
||||||
|
{#each preferences as preference}
|
||||||
|
<div
|
||||||
|
class="preference"
|
||||||
|
style="background-image: url({preference.img})"
|
||||||
|
on:click={() => onPreferenceSelect(preference)}
|
||||||
|
>
|
||||||
|
<span>{preference.name}</span>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let preferences;
|
||||||
|
export let onPreferenceSelect;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="category-3-in-row">
|
||||||
|
{#each preferences as preference}
|
||||||
|
<div
|
||||||
|
class="preference"
|
||||||
|
style="background-image: url({preference.img})"
|
||||||
|
on:click={() => onPreferenceSelect(preference)}
|
||||||
|
>
|
||||||
|
<span>{preference.name}</span>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { ComponentType, SvelteComponentTyped } from 'svelte'
|
||||||
|
export let path: string
|
||||||
|
export let component: () => Promise<any>
|
||||||
|
export let loading: ComponentType<SvelteComponentTyped<any>> | null = null
|
||||||
|
import { Route } from '$lib/router'
|
||||||
|
import LazyRouteGuard from './LazyRouteGuard.svelte'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Route {path} let:location let:params>
|
||||||
|
<LazyRouteGuard {location} {params} {component} {loading} />
|
||||||
|
</Route>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { RouteLocation } from 'svelte-routing/types/Route'
|
||||||
|
import Redirect from './Redirect.svelte'
|
||||||
|
export let fallback: string
|
||||||
|
export let allow: boolean
|
||||||
|
export let location: RouteLocation
|
||||||
|
</script>
|
||||||
|
{#if allow}
|
||||||
|
<slot />
|
||||||
|
{:else}
|
||||||
|
<Redirect to={fallback} replace state={{ from: location.pathname }} />
|
||||||
|
{/if}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { ComponentType, SvelteComponentTyped } from 'svelte'
|
||||||
|
|
||||||
|
export interface Route {
|
||||||
|
component: () => Promise<any>,
|
||||||
|
path: string,
|
||||||
|
layout?: ComponentType<SvelteComponentTyped<any>>,
|
||||||
|
loading?: ComponentType<SvelteComponentTyped<any>>,
|
||||||
|
before?: () => any,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RouteDefinition {
|
||||||
|
component: () => Promise<any>,
|
||||||
|
path: string,
|
||||||
|
layout: ComponentType<SvelteComponentTyped<any>> | null,
|
||||||
|
loading: ComponentType<SvelteComponentTyped<any>> | null,
|
||||||
|
before: () => any | null,
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RouteConfig {
|
||||||
|
routes: Route[],
|
||||||
|
layout?: ComponentType<SvelteComponentTyped<any>> | null,
|
||||||
|
loading?: ComponentType<SvelteComponentTyped<any>> | 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
|
|
@ -2,7 +2,7 @@ import { databases } from '$lib/appwrite'
|
||||||
import { Query } from 'appwrite'
|
import { Query } from 'appwrite'
|
||||||
import database from 'svelte-appwrite-client/src/lib/database'
|
import database from 'svelte-appwrite-client/src/lib/database'
|
||||||
import { getLocationDataFromLatAndLong } from '../locations'
|
import { getLocationDataFromLatAndLong } from '../locations'
|
||||||
import { writable } from 'svelte/store'
|
import { writable } from '$lib/stores/stores'
|
||||||
import { CheckPoint, Experience } from '$lib/TStypes/experiences'
|
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
|
//Loading of checkpoints and rating is done in the same function to prevent multiple requests to the database
|
||||||
|
|
|
@ -1,25 +1,76 @@
|
||||||
import { databases } from '$lib/appwrite';
|
import { databases } from '$lib/appwrite';
|
||||||
import { Query } from 'appwrite';
|
import { Query } from 'appwrite';
|
||||||
|
|
||||||
export const getPreferences = async () => {
|
// typescript interfaces for objects return definitions
|
||||||
const { documents } = await databases.listDocuments('6417cf1de159d094b370', '6417cf29f2118829b3b4', [
|
interface Interest {
|
||||||
Query.orderAsc('Name')
|
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<Interest[]> => {
|
||||||
|
return ((await databases.listDocuments('6417cf1de159d094b370', '6417cf29f2118829b3b4')).documents as unknown as Interest[])};
|
||||||
|
|
||||||
export const addSelectedPreferences = async (userId, preferences) => {
|
|
||||||
|
// fetch travel buddies
|
||||||
|
export const getTravelBuddies = async (): Promise<TravelBuddies[]> => {
|
||||||
|
return ((await databases.listDocuments('6417cf1de159d094b370', '6417d0429843609a2f49')).documents as unknown as TravelBuddies[])};
|
||||||
|
|
||||||
|
// fetch recommendations
|
||||||
|
export const getRecommendations = async (): Promise<Recommendations[]> => {
|
||||||
|
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 { document: user } = await databases.getDocument('63ded6c18e8493bffc83', 'Users', userId);
|
||||||
|
|
||||||
const updatedUser = {
|
const updatedUser = {
|
||||||
...user,
|
...user,
|
||||||
userPreferences: preferences
|
userInterests: interests,
|
||||||
|
userTravelBuddy: travelBuddies,
|
||||||
|
userRecommended: recommendations
|
||||||
};
|
};
|
||||||
|
|
||||||
await databases.updateDocument('6417cf1de159d094b370', 'user-collection', user.$id, updatedUser);
|
await databases.updateDocument('63ded6c18e8493bffc83', 'Users', user.$id, updatedUser);
|
||||||
|
|
||||||
return updatedUser;
|
return 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];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ export default (question, questionType) => {
|
||||||
case 'choice':
|
case 'choice':
|
||||||
return question.split(/;\s*/).map((item) => ({
|
return question.split(/;\s*/).map((item) => ({
|
||||||
label: item.startsWith('*') ? item.substring(1) : item,
|
label: item.startsWith('*') ? item.substring(1) : item,
|
||||||
value: item.startsWith('*') ? true : false,
|
value: !!item.startsWith('*')
|
||||||
}))
|
}))
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
|
|
|
@ -2,7 +2,7 @@ import './app.css'
|
||||||
import App from './App.svelte'
|
import App from './App.svelte'
|
||||||
|
|
||||||
const app = new App({
|
const app = new App({
|
||||||
target: document.getElementById('app'),
|
target: document.getElementById('app')
|
||||||
})
|
})
|
||||||
|
|
||||||
export default app
|
export default app
|
||||||
|
|
|
@ -1,36 +1,43 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Loading from './../../lib/components/Common/Loading.svelte';
|
import Interests from './../../lib/components/Categories/interests.svelte';
|
||||||
// Import necessary modules and components
|
// Import necessary modules and components
|
||||||
import { user } from '$lib/appwrite';
|
import { user } from '$lib/appwrite';
|
||||||
import collections from '$lib/collections';
|
import collections from '$lib/collections';
|
||||||
import Loading from '$lib/components/Common/Loading.svelte';
|
import Loading from '$lib/components/Common/Loading.svelte';
|
||||||
import Category2InRow from '$lib/components/categories/Category2InRow.svelte';
|
import Category2InRow from '$lib/components/categories/Category2InRow.svelte';
|
||||||
import Category3InRow from '$lib/components/categories/Category3InRow.svelte';
|
import Category3InRow from '$lib/components/categories/Category3InRow.svelte';
|
||||||
import { getPreferences, addSelectedPreferences } from '$lib/utils/database/preferences';
|
import { getInterests, getTravelBuddies, getRecommendations, addSelectedPreferences } from '$lib/utils/database/preferences';
|
||||||
import { navigate } from '$lib/router'
|
import { navigate } from '$lib/router'
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
|
interface Preference {
|
||||||
|
name: string;
|
||||||
|
img: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
//define changing state for displaying different categories
|
||||||
|
let current_state = 0;
|
||||||
|
|
||||||
|
// Define variables to store the preferences
|
||||||
|
let interests: Array<Preference> | undefined;
|
||||||
|
let travelBuddies: Array<Preference> | undefined;
|
||||||
|
let recommendations: Array<Preference> | undefined;
|
||||||
|
|
||||||
// Define a variable to store the preferences
|
|
||||||
let preferences = [];
|
|
||||||
// Define a variable to store the selected preferences
|
// Define a variable to store the selected preferences
|
||||||
let selectedPreferences = [];
|
let selectedInterests = [];
|
||||||
|
let selectedTravelBuddies = [];
|
||||||
|
let selectedRecommendations = [];
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
preferences = await getPreferences();
|
interests = await getInterests();
|
||||||
|
travelBuddies = await getTravelBuddies();
|
||||||
|
recommendations = await getRecommendations();
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateSelectedPreferences(preference) {
|
|
||||||
if (selectedPreferences.includes(preference)) {
|
|
||||||
selectedPreferences = selectedPreferences.filter((item) => item !== preference);
|
|
||||||
} else {
|
|
||||||
selectedPreferences = [...selectedPreferences, preference];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Define a function to handle the form submission
|
// Define a function to handle the form submission
|
||||||
async function submitPreferences() {
|
async function submitPreferences() {
|
||||||
await addSelectedPreferences(user, selectedPreferences);
|
await addSelectedPreferences(user, selectedInterests, selectedTravelBuddies, selectedRecommendations);
|
||||||
selectedPreferences = [];
|
selectedInterests = [];
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -39,21 +46,21 @@
|
||||||
<div class="progress-bar"></div>
|
<div class="progress-bar"></div>
|
||||||
<h2>What are your interests?</h2>
|
<h2>What are your interests?</h2>
|
||||||
<Category3InRow
|
<Category3InRow
|
||||||
preferences={preferences.slice(0, 3)}
|
interests={interests.slice(0, 3)}
|
||||||
on:preferenceSelect={updateSelectedPreferences}
|
onPreferenceSelect={updateSelectedInterests}
|
||||||
/>
|
/>
|
||||||
<h2>Who do you like to travel with?</h2>
|
<h2>Who do you like to travel with?</h2>
|
||||||
<Category2InRow
|
<Category2InRow
|
||||||
preferences={preferences.slice(3, 5)}
|
preferences={preferences.slice(3, 5)}
|
||||||
on:preferenceSelect={updateSelectedPreferences}
|
onPreferenceSelect={updateSelectedInterests[Symbol]...}
|
||||||
/>
|
/>
|
||||||
<h2>What brought you to our app?</h2>
|
<h2>What brought you to our app?</h2>
|
||||||
<Category3InRow
|
<Category3InRow
|
||||||
preferences={preferences.slice(5)}
|
preferences={preferences.slice(5)}
|
||||||
on:preferenceSelect={updateSelectedPreferences}
|
onPreferenceSelect={updateSelected..........}
|
||||||
/>
|
/>
|
||||||
<button on:click={submitPreferences}>Submit Preferences</button>
|
<button on:click={submitPreferences}>Submit Preferences</button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<Loading>
|
<Loading />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import { client } from "$lib/appwrite";
|
||||||
|
import { navigate } from "svelte-routing";
|
||||||
|
import collections from "$lib/collections";
|
||||||
|
import { getInterests, getRecommendations, getTravelBuddies, addSelectedPreferences } from '$lib/utils/database/preferences'
|
||||||
|
|
||||||
|
let preferences = [];
|
||||||
|
|
||||||
|
let selectedPrefId = 1;
|
||||||
|
|
||||||
|
const handleOptionClick = (pref, option) => {
|
||||||
|
pref.selectedOption = option;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNextClick = () => {
|
||||||
|
selectedPrefId += 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
try {
|
||||||
|
const [interests, travelBuddies, recommendedBy] = await Promise.all([
|
||||||
|
getInterests(),
|
||||||
|
getTravelBuddies(),
|
||||||
|
getRecommendations(),
|
||||||
|
]);
|
||||||
|
preferences = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "Select your interests",
|
||||||
|
options: interests,
|
||||||
|
selectedOption: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "Select your travel buddies",
|
||||||
|
options: travelBuddies,
|
||||||
|
selectedOption: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: "Who recommended you to this app?",
|
||||||
|
options: recommendedBy,
|
||||||
|
selectedOption: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const userPreferences = {
|
||||||
|
userInterests: interests.map((interest) => interest.name),
|
||||||
|
userTravelBuddy: travelBuddies.map((travelBuddy) => travelBuddy.name),
|
||||||
|
userRecommended: recommendedBy.map((recommendations) => recommendations.name),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await addSelectedPreferences(userPreferences);
|
||||||
|
navigate("/");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
console.log(await collections.interests.listDocuments());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
setContext("selectedPrefIndex", selectedPrefIndex);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
{#each preferences as pref}
|
||||||
|
{#if pref.id === selectedPrefId}
|
||||||
|
<div class="container">
|
||||||
|
<div class="container_page">
|
||||||
|
<h2>{pref.title}</h2>
|
||||||
|
<div class="radio_container">
|
||||||
|
{#each pref.options as option}
|
||||||
|
<label class="item {selected: preferences[selectedPrefIndex].selectedOption === option}">
|
||||||
|
<input type="radio" name={`pref-${preferences[selectedPrefIndex].id}`} value={option.id} on:change={() => handleOptionClick(preferences[selectedPrefIndex], option)} checked={preferences[selectedPrefIndex].selectedOption === option} />
|
||||||
|
<div>
|
||||||
|
<img src={option.img} alt={option.name} />
|
||||||
|
<p>{option.name}</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{#if pref.selectedOption}
|
||||||
|
<button on:click={handleNextClick}>Next</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
{#if selectedPrefId === preferences.length && preferences.every(pref => pref.selectedOption)}
|
||||||
|
<button on:click={addSelectedPreferences}>Save Preferences</button>
|
||||||
|
{/if}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
scroll-snap-type: x mandatory;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container_page {
|
||||||
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
padding: 0px 22px;
|
||||||
|
scroll-snap-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio_container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-self: center;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 7px;
|
||||||
|
width: 145px;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 1px solid #4264eb00;
|
||||||
|
|
||||||
|
img {
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 18px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 17px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
div {
|
||||||
|
border: 1px dashed #4263eb;
|
||||||
|
p {
|
||||||
|
color: #4263eb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -50,7 +50,9 @@
|
||||||
.selected{
|
.selected{
|
||||||
transition-delay: 0.25s;
|
transition-delay: 0.25s;
|
||||||
width: 46px;
|
width: 46px;
|
||||||
background-color: #14A6AE;
|
outline: 8px solid #BBD1C5;
|
||||||
|
outline-color: #14A6AE;
|
||||||
|
border-radius: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ['./index.html', './src/**/*.{html,svelte,js,ts}', './node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'],
|
content: ['./index.html', './src/**/*.{html,svelte,js,ts}', './node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {}
|
||||||
},
|
},
|
||||||
plugins: [require('flowbite/plugin')],
|
plugins: [require('flowbite/plugin')],
|
||||||
darkMode: 'class',
|
darkMode: 'class'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue