Test MVP #86

Merged
matthieu42morin merged 8 commits from master into deploy/prod 2023-04-27 17:08:59 +00:00
10 changed files with 92 additions and 38 deletions
Showing only changes of commit 16ae34ad08 - Show all commits

View File

@ -1,13 +1,15 @@
<script lang="ts"> <script lang="ts">
import './main.scss' import './main.scss'
import { i18n, isLoading as localeLoading } from '$lib/locales' import { i18n, isLoading as localeLoading } from '$lib/locales'
import { isLoading as authLoading, user } from '$lib/appwrite' import client, { isLoading as authLoading, databases, user } from '$lib/appwrite'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import Routes from './__routes.svelte' import Routes from './__routes.svelte'
/** import CookiesPopUp from '$lib/components/Cookies/CookiesPopUp.svelte' */ /** import CookiesPopUp from '$lib/components/Cookies/CookiesPopUp.svelte' */
import { navigate } from '$lib/router' import { navigate } from '$lib/router'
import LocationRequest from '$lib/components/Map/LocationRequest.svelte' import LocationRequest from '$lib/components/Map/LocationRequest.svelte'
import { Models } from 'appwrite'
import { UsersAnswersDocument } from '$lib/TStypes/experiences'
let isMounted = false let isMounted = false
$: isReady = $localeLoading === false && $authLoading === false && isMounted $: isReady = $localeLoading === false && $authLoading === false && isMounted

View File

@ -6,13 +6,12 @@
export let href: string = '' export let href: string = ''
export let disabled: boolean = false export let disabled: boolean = false
export let primary: boolean = false export let primary: boolean = false
export let style: string = ''
let className = '' let className = ''
export { className as class } export { className as class }
</script> </script>
<button {disabled} class:disabled {style} on:click={() => navigate(href)} on:click={() => dispatch('submit', true)} on:click class={className} class:primary> <button {disabled} class:disabled on:click={() => navigate(href)} on:click={() => dispatch('submit', true)} on:click class={className} class:primary>
<slot /> <slot />
</button> </button>

View File

@ -0,0 +1,21 @@
<script lang="ts">
import { Alert } from 'flowbite-svelte'
export let color: 'red' | 'yellow' | 'green' | 'purple' | 'pink' | 'blue' | 'light' | 'dark' = 'green'
export let dismissable = false
let className = ''
export { className as class }
</script>
<Alert {...$$restProps} {dismissable} class="mt-4 ml-2 mr-2 absolute top-0 z-50 {className}" {color}>
<span slot="icon"><slot name="icon" {color} /></span>
<span class="text-lg font-medium"><slot name="title" {color} /></span>
<div slot="extra">
<div class="mt-2 mb-4 text-sm">
<slot {color} />
</div>
<div class="flex gap-2">
<slot name="buttons" {color} />
</div>
</div>
</Alert>

View File

@ -3,7 +3,7 @@
import Map from './Map.svelte' import Map from './Map.svelte'
import { navigate } from 'svelte-routing' import { navigate } from 'svelte-routing'
import NavigationBarLayout from '../Layouts/NavigationBarLayout.svelte' import NavigationBarLayout from '../Layouts/NavigationBarLayout.svelte'
import { createEventDispatcher, onMount } from 'svelte' import { createEventDispatcher } from 'svelte'
import LocationRequest from './LocationRequest.svelte' import LocationRequest from './LocationRequest.svelte'
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -12,8 +12,6 @@
export let mapComponent = null export let mapComponent = null
export let userLocation = { lat: 0, lng: 0 } export let userLocation = { lat: 0, lng: 0 }
$: console.log(userLocation, center)
let className = '' let className = ''
export { className as class } export { className as class }
/*;(() => { /*;(() => {

View File

@ -94,7 +94,7 @@ const saveAnswerIntoDatabase = async (experienceId: string, checkPointId: string
experience: experienceId, experience: experienceId,
attemptCount: 1, attemptCount: 1,
}, },
[Permission.read(Role.user(user.$id)), Permission.update(Role.user(user.$id))], [Permission.read(Role.user(user.$id)), Permission.update(Role.user(user.$id)), Permission.delete(Role.user(user.$id))],
) )
} }
} else { } else {
@ -148,8 +148,6 @@ export const getUserProgress = async (experienceId: string) => {
Query.offset(0), Query.offset(0),
]) ])
console.log({ total })
const allOtherDocuments = ( const allOtherDocuments = (
await Promise.all( await Promise.all(
new Array(Math.ceil((total - 25) / 25) > 0 ? Math.ceil((total - 25) / 25) : 0) new Array(Math.ceil((total - 25) / 25) > 0 ? Math.ceil((total - 25) / 25) : 0)
@ -165,8 +163,6 @@ export const getUserProgress = async (experienceId: string) => {
) )
).flatMap((list) => list.documents) ).flatMap((list) => list.documents)
console.log({ allOtherDocuments })
return [...documents, ...allOtherDocuments] return [...documents, ...allOtherDocuments]
} }
export const getUserProgressAsStore = (experienceId: string) => { export const getUserProgressAsStore = (experienceId: string) => {

View File

@ -46,7 +46,13 @@
{/if} {/if}
</div> </div>
{#if control === 'not-control' || control === 'correct' || control === 'wrong-secondTime'} {#if control === 'not-control' || control === 'correct' || control === 'wrong-secondTime'}
<Button on:submit={() => dispatch('nextQuestion')} primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 m-10 relative">Na další otázku</Button> <Button on:submit={() => dispatch('nextQuestion')} primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 m-10 relative">
{#if loading}
<Loading />
{:else}
Na další otázku
{/if}
</Button>
{:else if control === 'wrong-firstTime' || control === null} {:else if control === 'wrong-firstTime' || control === null}
<Button disabled={loading} on:submit primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 m-10 relative"> <Button disabled={loading} on:submit primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 m-10 relative">
{#if loading} {#if loading}

View File

@ -6,7 +6,6 @@
export let gameData: Experience export let gameData: Experience
export let client export let client
let score = (client.points / client.possiblePointsToSeize) * 100 let score = (client.points / client.possiblePointsToSeize) * 100
console.log(score)
</script> </script>
<LayoutImg img={gameData.ExpImage}> <LayoutImg img={gameData.ExpImage}>
@ -23,6 +22,6 @@
{/if} {/if}
</span> </span>
</div> </div>
<Button class="w-80 mt-8 " on:click={() => navigate(-1)}>ukončit hru</Button> <Button class="w-80 mt-8 " on:click={() => navigate('/')}>ukončit hru</Button>
</div> </div>
</LayoutImg> </LayoutImg>

View File

@ -7,9 +7,6 @@
export let checkPoint: CheckPoint export let checkPoint: CheckPoint
export let myAnswer export let myAnswer
export let clear: false | true = false
$: if (clear) myAnswers = new Array(checkPoint.CPOptions.length).fill(false)
let myAnswers = new Array(checkPoint.CPOptions.length).fill(false) let myAnswers = new Array(checkPoint.CPOptions.length).fill(false)
$: myAnswer = checkPoint.CPOptions.filter((item, i) => { $: myAnswer = checkPoint.CPOptions.filter((item, i) => {
if (myAnswers[i] === true) return item if (myAnswers[i] === true) return item

View File

@ -18,6 +18,7 @@
import LayoutImg from '$lib/components/Layouts/LayoutImg.svelte' import LayoutImg from '$lib/components/Layouts/LayoutImg.svelte'
import { Models } from 'appwrite' import { Models } from 'appwrite'
import { Writable } from 'svelte/store' import { Writable } from 'svelte/store'
import { Button as FlowbiteButton } from 'flowbite-svelte'
const components = { const components = {
TEXT: TextForm, TEXT: TextForm,
@ -32,7 +33,8 @@
export let control: AnswerState = null export let control: AnswerState = null
let view: 'question' | 'map' | 'end' | 'start' | 'start-map' = 'start-map' let view: 'question' | 'map' | 'end' | 'start' | 'start-map' = 'start-map'
export let gameData: Experience //data export let gameData: Experience //data
$: [userProgress, userProgressLoading] = getUserProgressAsStore(gameData.$id) export let userProgress
//$: [userProgress, userProgressLoading] = getUserProgressAsStore(gameData.$id)
let client = { let client = {
//user data about game //user data about game
@ -45,15 +47,15 @@
}), }),
} }
$: if (client.pos < $userProgress?.length - 1 + 1) { $: if (client.pos < userProgress?.length - 1 + 1) {
// nastaví na continue // nastaví na continue
client.pos = $userProgress?.length - 1 + 1 client.pos = userProgress?.length - 1 + 1
client.points = $userProgress?.map((i) => (i.correct ? 2 : 0))?.reduce((accumulator, currentValue) => accumulator + currentValue) client.points = userProgress?.map((i) => (i.correct ? 2 : 0))?.reduce((accumulator, currentValue) => accumulator + currentValue)
view = 'map' view = 'map'
} }
$: if (gameData.checkPoints[client.pos].CPType === 'INFO' && !$userProgressLoading) control = 'not-control' $: if (gameData.checkPoints[client.pos].CPType === 'INFO') control = 'not-control'
const nextQuestion = () => { const nextQuestion = () => {
//další otázka //další otázka
@ -99,14 +101,26 @@
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }
myAnswer = ''
answerLoading = false answerLoading = false
} }
const admins = [
'641b2cd262519fdd33ec',
'643bfde664ea0c643112',
'643bfdd8c64e75d0b8ea',
'6427218926d6ab7f8e52',
'641d5642c8fa96066cf2',
'641b42847ac86f9a306c',
'63daafd3355edb14483d',
]
</script> </script>
<input type="number" bind:value={client.pos} />
<button on:click={() => (view = view === 'start-map' ? 'start' : 'question')}>disappear map</button>
{#if view === 'map' || view === 'start-map'} {#if view === 'map' || view === 'start-map'}
{#if admins.includes($user.$id)}<!--only if admin-->
<FlowbiteButton class="absolute z-50" color="red" on:click={() => (view = view === 'start-map' ? 'start' : 'question')}>disappear map</FlowbiteButton>
{/if}
<Erantmap bind:userLocation class="w-full h-full"> <Erantmap bind:userLocation class="w-full h-full">
<Marker on:enter={() => (view = view === 'start-map' ? 'start' : 'question')} {lat} {lng} {userLocation} /> <Marker on:enter={() => (view = view === 'start-map' ? 'start' : 'question')} {lat} {lng} {userLocation} />
</Erantmap> </Erantmap>

View File

@ -6,34 +6,56 @@
import IconStar from '../../lib/svg/Star.svelte' import IconStar from '../../lib/svg/Star.svelte'
import IconPoint from '../../lib/svg/Point.svelte' import IconPoint from '../../lib/svg/Point.svelte'
import Loading from '../../lib/components/Common/Loading.svelte' import Loading from '../../lib/components/Common/Loading.svelte'
import { data } from '../../lib/stores/stores'
import GeolocateControl from '@beyonk/svelte-mapbox/src/lib/map/controls/GeolocateControl.svelte'
import Map from '../../lib/components/Map/Map.svelte' import Map from '../../lib/components/Map/Map.svelte'
import Renderer from './Forms/Renderer.svelte' import Renderer from './Forms/Renderer.svelte'
import Marker from '../../lib/components/Map/Marker.svelte' import Marker from '../../lib/components/Map/Marker.svelte'
import { onMount } from 'svelte' import { getExperienceIdByUrlAsStore, getUserProgressAsStore, loadAsStore } from '$lib/utils/database/experience'
import { getExperienceIdByUrl, getExperienceIdByUrlAsStore, getUserProgress, getUserProgressAsStore, load, loadAsStore } from '$lib/utils/database/experience'
import { getLocationDataFromLatAndLong } from '$lib/utils/locations' import { getLocationDataFromLatAndLong } from '$lib/utils/locations'
import { navigate } from '$lib/router'
import { Experience } from '$lib/TStypes/experiences' import { Experience } from '$lib/TStypes/experiences'
import Progressbar from '$lib/components/erant/Progressbar.svelte' import Progressbar from '$lib/components/erant/Progressbar.svelte'
import { writable } from 'svelte/store' import { writable } from 'svelte/store'
import Alert from '$lib/components/Common/Alert.svelte'
import { Button as FlowbiteButton } from 'flowbite-svelte'
import { databases, user } from '$lib/appwrite'
import { Query } from 'appwrite'
export let params: { gameurl: string } export let params: { gameurl: string }
let gameData = writable<Experience>(null) let gameData = writable<Experience>(null)
let [id] = getExperienceIdByUrlAsStore(params.gameurl) let [id] = getExperienceIdByUrlAsStore(params.gameurl)
$: [userProgress] = $gameData ? getUserProgressAsStore($id) : [] $: [userProgress, userProgressLoading] = $gameData ? getUserProgressAsStore($id) : []
$: [gameData] = $gameData ? [] : loadAsStore(params.gameurl) $: [gameData] = $gameData ? [] : loadAsStore(params.gameurl)
$: if ($gameData) view = 'experience-preview' $: if ($gameData && !$userProgressLoading) view = 'experience-preview'
let view: 'experience-play' | 'experience-loading' | 'experience-preview' = 'experience-loading' let view: 'experience-play' | 'experience-loading' | 'experience-preview' = 'experience-loading'
const deleteProgress = () => {} const deleteProgress = async () => {
const documentsToDelete = $userProgress.map(({ $id }) => databases.deleteDocument('63cef30d6da945dd4250', 'users-answers', $id))
const res = await Promise.all(documentsToDelete)
deleteProgressAlertVisible = false
$userProgress = []
}
let deleteProgressAlertVisible = false
</script> </script>
{#if deleteProgressAlertVisible}
<Alert color="red" let:color>
<span slot="title">Delete your progress</span>
<div class="text-black">
<span>Are you sure that you want to delete your progress in experience {$gameData?.ExpName}</span>
<span>Experience Id: {$gameData?.$id}</span>
<span>Your current score is: {$userProgress?.length} checkPoints</span>
</div>
<div slot="buttons">
<FlowbiteButton on:click={deleteProgress} {color}>Yes I'm sure</FlowbiteButton>
<FlowbiteButton on:click={() => (deleteProgressAlertVisible = false)} outline {color}>No, I missed clicked</FlowbiteButton>
</div>
</Alert>
{/if}
{#if view === 'experience-loading'} {#if view === 'experience-loading'}
<h1 class="flex items-center justify-center flex-col"> <h1 class="flex items-center justify-center flex-col h-full">
<span>Experience is loading...</span> <span>Experience is loading...</span>
<Loading /> <Loading />
</h1> </h1>
@ -88,11 +110,11 @@
<Button on:click={() => (view = 'experience-play')} primary>{$userProgress.length ? 'Pokračovat' : 'Hrát'}</Button> <Button on:click={() => (view = 'experience-play')} primary>{$userProgress.length ? 'Pokračovat' : 'Hrát'}</Button>
{/if} {/if}
{#if $userProgress.length} {#if $userProgress.length}
<Button on:click={() => deleteProgress()} primary>resetovat progress</Button> <Button class="!bg-red-500" on:click={() => (deleteProgressAlertVisible = true)} primary>resetovat progress</Button>
{/if} {/if}
</Overlay> </Overlay>
{:else if view === 'experience-play'} {:else if view === 'experience-play'}
<Renderer gameData={$gameData} /> <Renderer userProgress={$userProgress} gameData={$gameData} />
{/if} {/if}
<style> <style>