App update - MVP #1 #61

Merged
matthieu42morin merged 10 commits from master into deploy/prod 2023-03-04 20:35:45 +00:00
26 changed files with 444 additions and 344 deletions

11
LICENSE
View File

@ -1,13 +1,8 @@
MIT License
Proprietary License
Copyright (c) 2020 Ludvík Prokopec
Copyright (c) 2023 Erant, s.r.o.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to use the Software solely for the internal business purposes of Erant, s.r.o. Such use may include running the Software on company-owned or leased hardware, and allowing access to the Software by employees or contractors of Erant, s.r.o. No other use, reproduction, distribution, or modification of the Software or any part thereof is permitted without the prior written consent of Erant, s.r.o.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

View File

@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"appwrite": "docker compose -f ./appwrite/docker-compose.yml up"

View File

@ -5,14 +5,18 @@
import { onMount } from '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'
let isMounted = false
$: isReady = $localeLoading === false && $authLoading === false && isMounted
$: console.log($user)
$: if (isReady && !$user) {
if (!(location.pathname.startsWith('/login') || location.pathname.startsWith('/register'))) {
console.log('change')
if (!location.pathname.startsWith('/login') && !location.pathname.startsWith('/register')) {
navigate('/login')
}
}
@ -33,7 +37,7 @@
</script>
<main>
<CookiesPopUp />
<!-- <CookiesPopUp /> -->
<!-- you can display loading while app is not ready (waiting for user and i18n) -->
{#if isReady}

View File

@ -4,6 +4,7 @@
import Layout from '$src/__layout.svelte'
import Loading from '$src/__loading.svelte'
import Error from '$src/__error.svelte'
import NavigationBarLayout from '$lib/components/Layouts/NavigationBarLayout.svelte'
</script>
<Router
@ -14,6 +15,7 @@
{
path: '/',
component: () => import('$routes/homepage/homepage.svelte'),
layout: NavigationBarLayout,
},
{
path: '/error',
@ -34,14 +36,21 @@
{
path: '/explore',
component: () => import('$routes/explore/explore.svelte'),
layout: NavigationBarLayout,
},
{
path: '/profile',
path: '/profile/',
component: () => import('$src/__error.svelte'),
},
{
path: '/profile/:erantId',
component: () => import('$routes/profile/profile.svelte'),
layout: NavigationBarLayout,
},
{
path: '/profile/:function',
path: '/profile/setting/:function',
component: () => import('$routes/profile/profile-functions.svelte'),
layout: NavigationBarLayout,
},
{
path: '/login',
@ -55,6 +64,15 @@
path: '/register/failed',
component: () => import('$routes/register/registerFailed.svelte'),
},
{
path: '/register/emailverification/:erantId',
component: () => import('$routes/register/emailVerification.svelte'),
},
{
path: '/create/account/:erantId/',
component: () => import('$routes/register/createAccount.svelte'),
},
{
path: '/:gameurl',
component: () => import('$routes/game/game.svelte'),

View File

@ -1,7 +1,9 @@
import { Collection } from './appwrite'
const expiriences = new Collection('63cef30d6da945dd4250', '63cef4bd210fdf2e5888')
const experiences = new Collection('63cef30d6da945dd4250', '63cef4bd210fdf2e5888')
const users = new Collection('63ded6c18e8493bffc83', 'Users')
export default {
expiriences,
experiences,
users,
}

View File

@ -1,8 +1,14 @@
<script>
import { user } from '$lib/appwrite'
import collections from '$lib/collections'
import { Query } from 'appwrite'
import { navigate } from 'svelte-routing'
import FooterItem from '../Common/NavBar_Item.svelte'
let items = [
$: [userInfo] = collections.users.getDocument([Query.equal('userId', $user?.$id || '')])
$: console.log($user)
$: items = [
{
name: 'Home',
url: '/',
@ -23,7 +29,7 @@
},
{
name: 'Profile',
url: '/profile',
url: `/profile/${$userInfo?.erantId}`,
image_url:
"data:image/svg+xml,%3Csvg width='19' height='24' viewBox='0 0 19 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cmask id='mask0_1515_2027' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='0' y='14' width='19' height='10'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0.166626 14.9121H18.6465V23.5151H0.166626V14.9121Z' fill='white'/%3E%3C/mask%3E%3Cg mask='url(%23mask0_1515_2027)'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9.40767 16.6621C4.4365 16.6621 1.9165 17.5161 1.9165 19.2019C1.9165 20.9029 4.4365 21.7651 9.40767 21.7651C14.3777 21.7651 16.8965 20.9111 16.8965 19.2253C16.8965 17.5243 14.3777 16.6621 9.40767 16.6621ZM9.40767 23.5151C7.12217 23.5151 0.166504 23.5151 0.166504 19.2019C0.166504 15.3566 5.441 14.9121 9.40767 14.9121C11.6932 14.9121 18.6465 14.9121 18.6465 19.2253C18.6465 23.0706 13.3732 23.5151 9.40767 23.5151Z' fill='%2361646B'/%3E%3C/g%3E%3Cmask id='mask1_1515_2027' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='3' y='0' width='13' height='13'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3.21143 0.333008H15.6015V12.7214H3.21143V0.333008Z' fill='white'/%3E%3C/mask%3E%3Cg mask='url(%23mask1_1515_2027)'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9.40763 1.99901C6.9098 1.99901 4.87746 4.03017 4.87746 6.52801C4.8693 9.01767 6.88646 11.0477 9.3738 11.057L9.40763 11.89V11.057C11.9043 11.057 13.9355 9.02467 13.9355 6.52801C13.9355 4.03017 11.9043 1.99901 9.40763 1.99901ZM9.40763 12.7218H9.3703C5.9613 12.7113 3.1998 9.93117 3.21146 6.52451C3.21146 3.11201 5.99046 0.333008 9.40763 0.333008C12.8236 0.333008 15.6015 3.11201 15.6015 6.52801C15.6015 9.94401 12.8236 12.7218 9.40763 12.7218Z' fill='%2361646B'/%3E%3C/g%3E%3C/svg%3E ",
},
@ -32,14 +38,13 @@
let className = ''
export { className as class }
</script>
<div class="h-full w-full absolute">
<div class={'section w-full h-[calc(100%-100px)] overflow-auto ' + className}><slot /></div>
<div class="footer">
{#each items as { name, url, image_url }}
{#if location.pathname === url || location.pathname.includes(url + "/")}
{#if location.pathname === url || location.pathname.includes(url + '/')}
<FooterItem on:click={() => navigate(url)} active={true} {name} {url}>
<img alt="" style="filter: invert(44%) sepia(66%) saturate(6619%) hue-rotate(222deg) brightness(98%) contrast(88%);" src={image_url} />
</FooterItem>

View File

@ -2,9 +2,10 @@
import GeolocateControl from '@beyonk/svelte-mapbox/src/lib/map/controls/GeolocateControl.svelte'
import Map from './Map.svelte'
import { navigate } from 'svelte-routing'
import NavigationBarLayout from '../Layouts/NavigationBarLayout.svelte'
import { onMount } from 'svelte'
export let center
$: console.log(center)
export let center = null
export let mapComponent = null
export let user = { lat: null, lng: null }
@ -20,21 +21,24 @@
function showPosition(position) {
user.lat = position.coords.latitude
user.lng = position.coords.longitude
if (!center) center = user
}
const userCenter = () => document.getElementsByClassName('mapboxgl-ctrl-geolocate')[0].click()
</script>
<Map {center} bind:mapComponent class={className} on:move>
<NavigationBarLayout>
{#if center}
<Map on:ready={() => setTimeout(() => userCenter(), 40)} {center} bind:mapComponent class={className} on:move>
<slot />
<GeolocateControl
on:geolocate={(e) => {
const { latitude, longitude } = e.detail.coords
user = { lat: latitude, lng: longitude }
//console.log(user)
}}
/>
</Map>
<div class="on">
</Map>
<div class="on">
<button on:click={() => navigate('/scanner')}>
<svg viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
@ -45,7 +49,7 @@
/>
</svg>
</button>
<button on:click={() => document.getElementsByClassName('mapboxgl-ctrl-geolocate')[0].click()}>
<button on:click={() => userCenter()}>
<svg viewBox="0 0 29 39" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
@ -55,7 +59,9 @@
/>
</svg>
</button>
</div>
</div>
{/if}
</NavigationBarLayout>
<style>
.on {

View File

@ -2,6 +2,7 @@
import { Map, controls } from '@beyonk/svelte-mapbox'
import GeolocateControl from '@beyonk/svelte-mapbox/src/lib/map/controls/GeolocateControl.svelte'
import { createEventDispatcher, onMount } from 'svelte'
const dispatch = createEventDispatcher()
export let mapComponent = null
let geolocateControl
let className = ''
@ -21,7 +22,6 @@
alert("Can't load your location!")
}
}*/
$: console.log([center.lat, center.lng])
</script>
<div class={className} class:radius>
@ -33,6 +33,7 @@
on:ready={() => {
mapComponent.resize()
mapComponent.setCenter([center.lng, center.lat], 14)
dispatch('ready')
}}
zoom={14}
>

View File

@ -37,7 +37,7 @@ export const answer = async (checkPointId: string, answer: any) => {
}
export const getExpiriences = async () => {
const expiriences = (await databases.listDocuments('63cef30d6da945dd4250', '63cef4bd210fdf2e5888')).documents
const expiriences = (await databases.listDocuments('63cef30d6da945dd4250', '63cef4bd210fdf2e5888', [Query.equal('ExpApproved', true)])).documents
let items: Array<{ location: string; name: string; link: string }> = []
for (const expirience of expiriences) {
items.push({

View File

@ -6,11 +6,9 @@
import Loading from '$lib/components/Common/Loading.svelte'
let Search: string
</script>
<NavigationBarLayout>
<div class="content">
<div class="content">
<Top bind:search_value={Search} />
<div class="results">
@ -24,11 +22,9 @@
{/each}
{/await}
<div class="end" />
</div>
</div>
</NavigationBarLayout>
</div>
<style lang="scss">
.content {

View File

@ -3,7 +3,7 @@
import Button from '../../../lib/components/Buttons/Button.svelte'
import Image from '../../../lib/components/Common/Image.svelte'
export let control: null | false | true | 'not-control'
export let control: 'wrong-firstTime' | 'wrong-secondTime' | 'correct' | 'not-control' | null
export let nextQuestion
export let imgSrc
</script>
@ -22,21 +22,30 @@
<span> Popis úkolu: </span>
<span> <slot name="about" /></span>
</div>
{#if control === 'wrong-firstTime' || control === 'wrong-secondTime'}
<div class="popis">
<span> Nápověda: </span>
<span> <slot name="hint" /></span>
</div>
{/if}
<div class="flex items-center justify-center flex-col w-full gap-6">
<span class="relative"> <slot name="answers" /> </span>
{#if control !== null || control === 'not-control'}<!--jestli jsem už odpověděl-->
<Button on:submit={nextQuestion} primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 fixed m-10 relative">Na další otázku</Button>
{:else}<!--čeká na odpověd, na sejmutí-->
<Button on:submit primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 fixed m-10 relative">Vyhodnotit</Button>
{#if control === 'not-control' || control === 'correct' || control === 'wrong-secondTime'}
<Button on:submit={nextQuestion} primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 m-10 relative">Na další otázku</Button>
{:else if control === 'wrong-firstTime' || control === null}
<Button on:submit primary class="w-3/4 max-w-sm min-w-[400px] h-16 bottom-0 m-10 relative">Vyhodnotit</Button>
{/if}
</div>
</div>
<div class="w-full relative bottom-[170px] flex justify-center h-fit size">
{#if control === 'not-control' || control === null}
<span />
{:else if control}
{:else if control === 'correct'}
<span style="color:greenyellow">správně</span>
{:else}
{:else if control === 'wrong-firstTime'}
<span style="color:red">druhypokus</span>
{:else if control === 'wrong-secondTime'}
<span style="color:red">špatně</span>
{/if}
</div>

View File

@ -8,14 +8,19 @@
const { checkPoint, name } = data
let myAnswers = new Array(checkPoint.CPOptions.length).fill(false)
export let control = null
export let control: 'wrong-firstTime' | 'wrong-secondTime' | 'correct' | 'not-control' | null
export let nextQuestion
export let attempt: 1 | 2 = 1
const answerCheckBox = async () => {
const arr = checkPoint.CPOptions.filter((item, i) => {
if (myAnswers[i] === true) return item
})
control = await answer(checkPoint.$id, arr)
const res = await answer(checkPoint.$id, arr)
if (res) control = 'correct'
else if (attempt === 1) control = 'wrong-firstTime'
else control = 'wrong-secondTime'
attempt++
}
</script>
@ -30,6 +35,7 @@
>
<span slot="title">{name}</span>
<span slot="about">{@html checkPoint.CPText}</span>
<span slot="hint"> {@html checkPoint.CPHint} </span>
<div slot="answers">
{#each checkPoint.CPOptions as label, i}
<span class="self-baseline">

View File

@ -8,11 +8,16 @@
const { checkPoint, name } = data
let myAnswer = ''
export let control = null
export let control: 'wrong-firstTime' | 'wrong-secondTime' | 'correct' | 'not-control' | null
export let nextQuestion
export let attempt: 1 | 2 = 1
const answer_ = async () => {
control = await answer(checkPoint.$id, myAnswer)
const res = await answer(checkPoint.$id, myAnswer)
if (res) control = 'correct'
else if (attempt === 1) control = 'wrong-firstTime'
else control = 'wrong-secondTime'
attempt++
}
</script>
@ -27,6 +32,7 @@
>
<span slot="title">{name}</span>
<span slot="about">{@html checkPoint.CPText}</span>
<span slot="hint"> {@html checkPoint.CPHint} </span>
<div slot="answers">
<span class="self-baseline">
<Input type="number" bind:value={myAnswer} class="w-full min-w-[400px] max-w-[500px] h-12" />

View File

@ -22,8 +22,8 @@
INFO: Info,
}
let control = null // if true => spravne if false spatne
let view: 'question' | 'map' = 'map'
export let control: 'wrong-firstTime' | 'wrong-secondTime' | 'correct' | 'not-control' | null = null
let view: 'question' | 'map' | 'end' = 'map'
export let gameData: any = {} //data
$: console.log(gameData)
@ -31,32 +31,37 @@
let clientAnswers = {
//user data about game
pos: 0,
end: gameData.checkPoints.length, //kolik otázek
end: gameData.checkPoints.length - 1, //kolik otázek
points: 0, //body
}
$: if (control === true) clientAnswers.points += 2 //body bodování
$: console.log(clientAnswers.pos === clientAnswers.end + 1)
$: if (control === 'correct') clientAnswers.points += 2 //body bodování
const nextQuestion = () => {
//další otázka
if (control !== null) {
control = null
if (clientAnswers.pos === clientAnswers.end) view = 'end'
else {
clientAnswers.pos++
view = 'map'
}
}
}
//let answers
//$: if (clientAnswers.pos < clientAnswers.end) answers = parseQuestion(gameData.questions[clientAnswers.pos].answer, gameData.questions[clientAnswers.pos].type) //delete
let page = null
$: if (clientAnswers.pos < clientAnswers.end) page = components[gameData.checkPoints[clientAnswers.pos].CPType]
$: page = view === 'question' ? components[gameData.checkPoints[clientAnswers.pos].CPType] : null
let [lat, lng] = [null, null]
$: if (clientAnswers.pos < clientAnswers.end) [lat, lng] = $data.checkPoints[clientAnswers.pos].CPLocation
let user = { lat: null, lng: null }
$: console.log(page, gameData.checkPoints[clientAnswers.pos].CPType)
$: console.log(gameData.checkPoints[clientAnswers.pos].CPType, clientAnswers.pos, view)
/* //set user to localstorage
$: if (clientAnswers.pos !== clientAnswers.end && clientAnswers.pos !== 0) {
@ -76,18 +81,20 @@
}*/
</script>
{#if page && view === 'map'}
<Erantmap center={{ lat, lng }} bind:user class="w-full h-full">
<input type="number" bind:value={clientAnswers.pos} />
<button on:click={() => (view = 'question')}>disappear map</button>
{#if view === 'map'}
<Erantmap bind:user class="w-full h-full">
<Marker on:enter={() => (view = 'question')} {lat} {lng} {user} />
</Erantmap>
{/if}
{#if view === 'question'}
{#if clientAnswers.pos !== clientAnswers.end}
<svelte:component this={page} data={{ checkPoint: gameData.checkPoints[clientAnswers.pos], name: gameData.ExpName }} {nextQuestion} bind:control />
{:else}
{/if}
{#if view === 'end'}
<Finish img={gameData.thumbnail}>
<span> Získali jste {clientAnswers.points} / {clientAnswers.end * 2} bodů</span>
</Finish>
{/if}
{/if}

View File

@ -8,13 +8,16 @@
const { checkPoint, name } = data
let myAnswer = ''
$: console.log(data)
export let control = null
export let control: 'wrong-firstTime' | 'wrong-secondTime' | 'correct' | 'not-control' | null
export let nextQuestion
export let attempt: 1 | 2 = 1
const answer_ = async () => {
control = await answer(checkPoint.$id, myAnswer)
const res = await answer(checkPoint.$id, myAnswer)
if (res) control = 'correct'
else if (attempt === 1) control = 'wrong-firstTime'
else control = 'wrong-secondTime'
attempt++
}
</script>
@ -25,7 +28,7 @@
nextQuestion()
myAnswer = ''
}}
on:submit={() => (control = myAnswer !== '' ? answer_() : null)}
on:submit={() => (myAnswer !== '' ? answer_() : null)}
>
<span slot="title">{name}</span>
<span slot="about">{@html checkPoint.CPText}</span>

View File

@ -8,11 +8,16 @@
const { checkPoint, name } = data
let myAnswer = ''
export let control = null
export let control: 'wrong-firstTime' | 'wrong-secondTime' | 'correct' | 'not-control' | null
export let nextQuestion
export let attempt: 1 | 2 = 1
const answer_ = async () => {
control = await answer(checkPoint.$id, myAnswer)
const res = await answer(checkPoint.$id, myAnswer)
if (res) control = 'correct'
else if (attempt === 1) control = 'wrong-firstTime'
else control = 'wrong-secondTime'
attempt++
}
</script>
@ -27,6 +32,7 @@
>
<span slot="title">{name}</span>
<span slot="about">{@html checkPoint.CPText}</span>
<span slot="hint"> {@html checkPoint.CPHint} </span>
<div slot="answers">
<span class="self-baseline">
<Input type="text" bind:value={myAnswer} class="w-full min-w-[400px] max-w-[500px] h-12" />

View File

@ -1,14 +1,11 @@
<script>
import { navigate } from '$lib/router'
</script>
<div class="discover">
<h2>
Dicoveries around
</h2>
<h2>Dicoveries around</h2>
<button>
Start your trips!
</button>
<button on:click={() => navigate('/explore')}> Start your trips! </button>
</div>
<style>
@ -31,7 +28,7 @@
gap: 18px;
}
.discover > h2{
.discover > h2 {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
@ -40,10 +37,10 @@
margin: 0;
text-align: center;
}
.discover > button{
.discover > button {
text-align: center;
color: #110042;
background-color: #FFFFFF;
background-color: #ffffff;
font-family: 'Source Sans Pro';
font-style: normal;
@ -55,24 +52,25 @@
border-radius: 15px;
}
.discover > button:hover, .discover > button:active{
.discover > button:hover,
.discover > button:active {
opacity: 80%;
cursor: pointer;
}
@media screen and (max-width: 370px){
@media screen and (max-width: 370px) {
.discover {
width: calc(100% - 24px);
height: 33.5vw;
border-radius: 8vw;
}
.discover > button{
.discover > button {
font-size: 4.3vw;
line-height: 5.4vw;
padding: 2.2vw 14.8vw 2.2vw 14.8vw;
border-radius: 15px;
}
.discover > h2{
.discover > h2 {
font-size: 6.4vw;
line-height: 8.6vw;
}

View File

@ -37,7 +37,6 @@
</script>
{#if !fitstTime}
<NavigationBarLayout>
<Top headline={city + state} />
<Discover />
@ -53,7 +52,6 @@
{:then expiriences}
<Comparment items={expiriences} />
{/await}
</NavigationBarLayout>
{:else}
<div class="content">
<Animation />

View File

@ -7,13 +7,14 @@
export let purpose = 'login' //possible values login, register
let email = ''
let password = ''
let email = 'aaahoj@ahoj.ahoj'
let password = 'ahojahoj'
$: console.log($user)
const emailLogin = async () => {
await account.createEmailSession(email, password)
await user.createEmailSession(email, password)
//if (navigation.canGoBack) navigation.back()
navigate('/')
}
</script>
@ -48,7 +49,7 @@
<p>Continue with Google</p>
</button>
<button on:click={() => account.createOAuth2Session('facebook')}>
<button on:click={() => account.createOAuth2Session('facebook', `${location.origin}/create/account`, `${location.origin}/register/failed`)}>
<p>Continue with Facebook</p>
</button>
</div>

View File

@ -1,70 +1,71 @@
<script lang="ts">
import { user } from '$lib/appwrite'
import collections from '$lib/collections'
import HiddenInput from '$lib/components/Inputs/Hidden_Input_type2.svelte'
import { Query } from 'appwrite'
let c_password:string = ''
let n_password:string = ''
let nr_password:string = ''
let c_password: string = ''
let n_password: string = ''
let nr_password: string = ''
$: userName = $userInfo?.userName
$: [userInfo] = collections.users.getDocument([Query.equal('userId', $user.$id)])
</script>
<div class="container">
<div class="photo">
<div class="currentPhoto">
</div>
<button class="changePhoto">
Update your photo
</button>
<div class="currentPhoto" />
<button class="changePhoto"> Update your photo </button>
</div>
<form class="inputs">
<input type="text" placeholder="Your name">
<input type="email" placeholder="Your email">
<input type="text" bind:value={userName} placeholder="Your name" />
<input type="email" placeholder="Your email" />
<HiddenInput bind:value={c_password} placeholder="Your current password" />
<HiddenInput bind:value={n_password} placeholder="New password" />
<HiddenInput bind:value={nr_password} placeholder="Re-type new password" />
</form>
</div>
<style lang="scss">
.container{
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
.photo{
.photo {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
gap: 8px;
.currentPhoto{
.currentPhoto {
width: 100%;
aspect-ratio: 1/1;
/* background */
background: #EFEFF0;
background: #efeff0;
/* subtle-light */
border: 2px solid #AFB1B6;
border: 2px solid #afb1b6;
border-radius: 200px;
background-image: url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cmask id='mask0_1380_1768' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='0' y='0' width='20' height='20'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0.000488281 0H19.9601V19.9498H0.000488281V0Z' fill='white'/%3E%3C/mask%3E%3Cg mask='url(%23mask0_1380_1768)'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M5.65049 1.5C3.12949 1.5 1.50049 3.227 1.50049 5.899V14.051C1.50049 16.724 3.12949 18.45 5.65049 18.45H14.3005C16.8275 18.45 18.4605 16.724 18.4605 14.051V5.899C18.4605 3.227 16.8275 1.5 14.3005 1.5H5.65049ZM14.3005 19.95H5.65049C2.27049 19.95 0.000488281 17.579 0.000488281 14.051V5.899C0.000488281 2.371 2.27049 0 5.65049 0H14.3005C17.6855 0 19.9605 2.371 19.9605 5.899V14.051C19.9605 17.579 17.6855 19.95 14.3005 19.95Z' fill='%23AFB1B6'/%3E%3C/g%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3.28126 15.1799C3.09526 15.1799 2.91026 15.1119 2.76526 14.9739C2.46426 14.6899 2.45226 14.2139 2.73726 13.9149L4.26526 12.3019C5.07426 11.4429 6.43926 11.4009 7.30226 12.2109L8.26026 13.1829C8.52726 13.4529 8.96126 13.4579 9.22926 13.1939C9.33026 13.0749 11.5083 10.4299 11.5083 10.4299C11.9223 9.92789 12.5063 9.61789 13.1553 9.55389C13.8053 9.49689 14.4363 9.68589 14.9393 10.0989C14.9823 10.1339 15.0213 10.1679 17.2173 12.4229C17.5063 12.7189 17.5013 13.1939 17.2043 13.4829C16.9083 13.7739 16.4323 13.7649 16.1433 13.4689C16.1433 13.4689 14.0943 11.3659 13.9483 11.2239C13.7933 11.0969 13.5443 11.0229 13.2993 11.0469C13.0503 11.0719 12.8263 11.1909 12.6673 11.3839C10.3433 14.2029 10.3153 14.2299 10.2773 14.2669C9.41926 15.1089 8.03426 15.0949 7.19126 14.2349C7.19126 14.2349 6.26126 13.2909 6.24526 13.2719C6.01426 13.0579 5.60226 13.0719 5.35526 13.3329L3.82526 14.9459C3.67726 15.1019 3.47926 15.1799 3.28126 15.1799Z' fill='%23AFB1B6'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M6.55769 6.12891C6.00469 6.12891 5.55469 6.57891 5.55469 7.13291C5.55469 7.68691 6.00469 8.13791 6.55869 8.13791C7.11269 8.13791 7.56369 7.68691 7.56369 7.13291C7.56369 6.57991 7.11269 6.12991 6.55769 6.12891ZM6.55869 9.63791C5.17769 9.63791 4.05469 8.51391 4.05469 7.13291C4.05469 5.75191 5.17769 4.62891 6.55869 4.62891C7.94069 4.62991 9.06369 5.75391 9.06369 7.13291C9.06369 8.51391 7.93969 9.63791 6.55869 9.63791Z' fill='%23AFB1B6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
}
.changePhoto{
.changePhoto {
font-weight: 600;
font-size: 14px;
color: #FFFFFF;
color: #ffffff;
padding: 8px 12px;
background: #110042;
border-radius: 15px;
}
}
.inputs{
.inputs {
padding: 0 24px;
margin-top: 16px;
@ -76,17 +77,16 @@
gap: 16px;
input[type='text'], input[type='email']{
input[type='text'],
input[type='email'] {
padding: 12px 24px;
background: #EEEEEE;
background: #eeeeee;
width: 100%;
border-radius: 15px;
font-weight: 600;
font-size: 18px;
}
}
}
</style>

View File

@ -3,39 +3,42 @@
import { navigate } from 'svelte-routing'
import ArrowBack from '$lib/svg/ArrowBack.svelte'
import ProfileUpdate from './functions/Profile-Update.svelte';
import Setting from './functions/Setting.svelte';
import Cookies from './functions/Cookies.svelte';
import InterestsUpdate from './functions/Interests-Update.svelte';
import ProfileUpdate from './functions/Profile-Update.svelte'
import Setting from './functions/Setting.svelte'
import Cookies from './functions/Cookies.svelte'
import InterestsUpdate from './functions/Interests-Update.svelte'
const functions = [{name: "profile_update", display_name:"Update Your Profile", view: ProfileUpdate}, {name: "interests_update", display_name:"Update your interests", view: InterestsUpdate}, {name: "settings", display_name:"Setting", view: Setting}, {name: "cookies", display_name:"Cookies", view: Cookies}]
const functions = [
{ name: 'profile_update', display_name: 'Update Your Profile', view: ProfileUpdate },
{ name: 'interests_update', display_name: 'Update your interests', view: InterestsUpdate },
{ name: 'settings', display_name: 'Setting', view: Setting },
{ name: 'cookies', display_name: 'Cookies', view: Cookies },
]
export let params: { function: string }
let data = functions.find(element => element.name === params.function.toLowerCase()) || null
let data = functions.find((element) => element.name === params.function.toLowerCase()) || null
if (data === null){
if (data === null) {
window.location.href = '/profile'
}
</script>
<NavigationBarLayout class="p-4">
<div class="head">
<button on:click={() => {navigate("/profile")}}>
<div class="head">
<button
on:click={() => {
navigate('/profile')
}}
>
<ArrowBack />
</button>
<h1>{data.display_name}</h1>
</div>
</div>
<svelte:component this={data.view}/>
</NavigationBarLayout>
<svelte:component this={data.view} />
<style lang="scss">
.head{
.head {
display: flex;
align-items: center;
justify-content: center;
@ -44,7 +47,7 @@
margin-bottom: 20px;
position: relative;
h1{
h1 {
font-weight: 600;
font-size: 32px;
line-height: 40px;
@ -52,7 +55,7 @@
color: #000000;
margin: 0;
}
button{
button {
position: absolute;
left: 8px;
top: 50%;

View File

@ -1,4 +1,4 @@
<script>
<script lang="ts">
import Logout from './../../lib/svg/Logout.svelte'
import Help from './../../lib/svg/Help.svelte'
import Line from '$lib/components/Common/Line.svelte'
@ -13,6 +13,12 @@
import PointSmall from '$lib/svg/PointSmall.svelte'
import InputPicture from '$lib/components/Inputs/InputPicture.svelte'
import { account, user } from '$lib/appwrite'
import collections from '$lib/collections'
import { Query } from 'appwrite'
export let params: { erantId: string }
//
$: [userInfo] = collections.users.getDocument([Query.equal('erantId', params.erantId)])
$: console.log($user)
@ -20,34 +26,33 @@
{
title: 'Account',
itms: [
{ icon: Profile, text: 'Update Your Profile', link:"/profile/profile_update"},
{ icon: Pen, text: 'Update Your Interests', link:"/profile/interests_update"},
{ icon: Profile, text: 'Update Your Profile', link: '/profile/setting/profile_update' },
{ icon: Pen, text: 'Update Your Interests', link: '/profile/setting/interests_update' },
],
},
{
title: 'Settings',
itms: [
{ icon: Setting2, text: 'Setting', link:"/profile/settings"},
{ icon: CookieMonster, text: 'Cookies', link:"/profile/cookies"}
{ icon: Setting2, text: 'Setting', link: '/profile/setting/settings' },
{ icon: CookieMonster, text: 'Cookies', link: '/profile/setting/cookies' },
],
},
{
title: 'Legal',
itms: [
{ icon: Help, text: 'Help', link:"/"},
{ icon: Warning, text: 'Terms & Condition', link:"/"},
{ icon: Logout, text: 'Log out', link: () => user.deleteSessions() },,
{ icon: Help, text: 'Help', link: '/' },
{ icon: Warning, text: 'Terms & Condition', link: '/' },
{ icon: Logout, text: 'Log out', link: () => user.deleteSessions() },
,
],
},
]
</script>
<NavigationBarLayout class="p-4">
{#if $userInfo}
<div class="w-full h-[188px] flex flex-wrap flex-col gap-4 justify-center items-center mb-8">
<InputPicture />
<span class="font-semibold text-[24px]">User name</span>
<span class="font-semibold text-[24px]">{$userInfo.userName}</span>
<SettingRow class="w-auto gap-2">
<PointSmall />
<span class="text-[16px] text-[#61646B]">Prague, Czechia</span>
@ -58,11 +63,11 @@
<div class="w-full h-auto flex flex-wrap flex-row mt-4 gap-4">
{#each items as { title, itms }}
<div class="mb-4 text-[18px] text-[#61646B]">{title}</div>
{#each itms as { icon, text, link}}
{#if (typeof link === 'function')}
{#each itms as { icon, text, link }}
{#if typeof link === 'function'}
<SettingRow>
<svelte:component this={icon} />
<button class="font-semibold text-[18px]" on:click={() => link()}>{text}</button>
<button class="font-semibold text-[18px]" on:click={link}>{text}</button>
</SettingRow>
{:else}
<SettingRow>
@ -71,8 +76,7 @@
</SettingRow>
<Line />
{/if}
{/each}
{/each}
</div>
</NavigationBarLayout>
{/if}

View File

@ -0,0 +1,23 @@
<script lang="ts">
import { user } from '$lib/appwrite'
import collections from '$lib/collections'
import Loading from '$lib/components/Common/Loading.svelte'
import { navigate } from '$lib/router'
import { Permission, Role } from 'appwrite'
export let params
;(async () => {
await collections.users.createDocument(
{
erantId: params.erantId,
userName: $user.name,
userId: $user.$id,
},
[Permission.delete(Role.user($user.$id)), Permission.update(Role.user($user.$id))],
)
navigate('/')
})()
</script>
<div class="w-full h-full flex items-center justify-center">
<Loading />
</div>

View File

@ -0,0 +1,24 @@
<script lang="ts">
import { user } from '$lib/appwrite'
import Loading from '$lib/components/Common/Loading.svelte'
import { navigate } from '$lib/router'
export let params
//register email verification
const urlParams = new URLSearchParams(location.search)
const userId = urlParams.get('userId')
const secret = urlParams.get('secret')
;(async () => {
try {
await user.updateVerification(userId, secret)
navigate(`/create/account/${params.erantId}`)
} catch (err) {
console.log(err)
}
})()
</script>
<div class="w-full h-full flex items-center justify-center">
<Loading />
</div>

View File

@ -1,91 +1,76 @@
<script>
import { account } from '$lib/appwrite'
<script lang="ts">
import { account, user } from '$lib/appwrite'
import Loading from '$lib/components/Common/Loading.svelte'
import { navigate } from '$lib/router'
import Error from '$root/src/__error.svelte'
import { ID } from 'appwrite'
import HiddenInput from '../../lib/components/Inputs/Hidden_Input.svelte'
import GoogleLogo from '../../lib/svg/GoogleLogo.svelte'
import TopImage from '../../lib/svg/Top-Image.svelte'
export let purpose = 'register' //possible values login, register
let email = 'otaprokopec@gmail.com'
let password = 'aaaaaaaa'
let repeatPassword = 'aaaaaaaa'
let name = 'test'
let erantId = '@otik'
let email = ''
let password = ''
let repeatPassword = ''
let name = ''
let state: 'email-sent' | 'register' | 'loading' = 'register'
const register = async () => {
//if (password === repeatPassword || name.length < 8 || email.length < 8) throw new Error('conditions are not fine')
await account.create(ID.unique(), email, password, name)
await account.createEmailSession(email, password, name)
await account.createVerification(`${location.origin}/`)
}
//register email verification
/*const urlParams = new URLSearchParams(location.search)
const userId = urlParams.get('userId')
const secret = urlParams.get('secret')
;(async () => {
try {
await account.updateVerification(userId, secret)
navigate('/')
} catch (err) {
console.log(err)
state = 'loading'
await account.create(ID.unique(), email, password, name)
await account.createEmailSession(email, password)
await account.createVerification(`${location.origin}/register/emailverification/${erantId}`)
state = 'email-sent'
} catch (error) {
state = 'register'
}
}
})()*/
</script>
<div class="main">
<!--Top image static link form lib/svg-->
{#if state === 'register'}
<div class="main">
<div class="top-image">
<TopImage />
</div>
<!--Welcome sign 2 options for Log in and for register-->
<h1 class="headline">
{#if purpose === 'login'}
Welcome Back
{:else}
Register
{/if}
</h1>
<h1 class="headline">Register</h1>
<!--2 forms from components-->
<div class="form">
{#if purpose === 'login'}
<form>
<input type="text" placeholder="E-mail" autocomplete="email" required />
<HiddenInput placeholder="Password" />
<input type="submit" value="Sign in" />
</form>
{:else}
<form>
<input bind:value={name} type="text" placeholder="Name" autocomplete="full-name" required />
<input bind:value={email} type="text" placeholder="E-mail" autocomplete="email" required />
<input bind:value={erantId} type="text" placeholder="E-mail" autocomplete="email" required />
<HiddenInput bind:value={password} placeholder="Password" />
<HiddenInput bind:value={repeatPassword} placeholder="Re-type password" />
<input class="cursor-pointer" on:click={() => register()} type="submit" value="Sign up" />
<input class="cursor-pointer" on:click={() => register()} type="button" value="Sign up" />
</form>
{/if}
</div>
<div class="continue_with">
<button on:click={() => account.createOAuth2Session('google', '/', '/register/failed')}>
<button on:click={() => account.createOAuth2Session('google', location.origin, `${location.origin}/register/failed`)}>
<GoogleLogo />
<p>Continue with Google</p>
</button>
<button on:click={() => account.createOAuth2Session('facebook', '/', '/register/failed')}>
<button on:click={() => account.createOAuth2Session('facebook', `${location.origin}/`, `${location.origin}/register/failed`)}>
<p>Continue with Facebook</p>
</button>
</div>
<div class="LR_switch">
<!--LR switch = login / register switch-->
{#if purpose === 'login'}
<p>Dont have an account? <a href="/register">Sign-up</a></p>
{:else}
<p>Already have an account? <a href="/login">Log In</a></p>
{/if}
</div>
</div>
</div>
{:else if state === 'email-sent'}
<div class="w-full h-full flex justify-center items-center">email has been sent</div>
{:else if state === 'loading'}
<div class="w-full h-full flex items-center justify-center">
<Loading />
</div>
{/if}
<style lang="scss">
$gap: 20px;
@ -217,7 +202,7 @@
line-height: 28px;
}
input[type='submit'] {
input[type='button'] {
background-color: #4263eb;
color: white;