This commit is contained in:
Ota Prokopec 2023-01-08 18:35:33 +01:00
parent 5148f78ef7
commit c1cadd1fd5
99 changed files with 4397 additions and 348 deletions

View File

@ -9,6 +9,11 @@ charset = utf-8
trim_trailing_whitespace = false
quote_type = single
[*.{yml, md}]
[*.yml]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = false
quote_type = single

4
.gitignore vendored
View File

@ -23,5 +23,5 @@ dist-ssr
*.sln
*.sw?
# appwrite
appwrite
# php
public/api/vendor

282
README.md
View File

@ -1,278 +1,10 @@
# Svelte + Appwrite = 🚀
# Geohry
## Appwrite svelte template
Vzdělávejte se mimo lavice. Nechte se provést atraktivními lokacemi, vyřešte mnoho výzev a objevte nejednu geografickou zajímavost s bezplatnou mobilní aplikací.
Blazing fast development with done backend and fully-prepared frontend.
1. Hrací režim
2. QR kódy
3. Nacházení blízkých her do x km a jejich seznam
4. Přihlašování/registrace
CMS ready!
## Appwrite installation
[Appwrite installation](https://appwrite.io/docs/installation)
## Start
### Appwrite cli
```bash
npm install -g appwrite-cli
```
### Appwrite new project
```bash
appwrite init project
```
### Appwrite new collection
```bash
appwrite init collection
```
### Appwrite new function
```bash
appwrite init function
```
[Appwrite cli documentation](https://appwrite.io/docs/command-line)
## env
Edit `.env` file for config project id.
## Frontend included
* tailwind
* scss
* css reset
* typescript
* routing
* ready routes
* oauth
* files upload, download
* folder structure
* common components
* service worker
* path aliases
* database realtime subscribers
* database paginate, infinity scroll
* i18n
* cms
* cms forms components
* vite
* prettier
* editorconfig
* icons: [Feather icons](https://feathericons.com/)
## Database subscribers
```svelte
<script>
import { Collection } from '$lib/appwrite'
import { Query } from 'appwrite'
const collection = new Collection('[database-id]', '[collection-id]')
const [subscriber, loading] = collection.listDocuments(/* filters?: string[], offset?: number, limit?: number, orderType?: "ASC" | "DESC" */)
// listen changes (update, delete) in database and automatically rerender on change
// current data = [{ name: 'John', lastName: 'Doe' }, ...]
const [documentSubscriber, documentLoading] = collection.getDocument('[document-id]')
const [documentSubscriber, documentLoading] = collection.getDocument([Query.equal('name', 'John'), /*...*/])
// must be unique in collection, else throw error
const insertSubscriber = collection.listenInsert((item) => item.name !== 'John')
// listen changes (create/instert) in database and automatically rerender on change
// can be created with filter function
collection.createDocument({ name: 'John', lastname: 'Doe' }, [/* ...permissions */])
// creates a document in collection with data and permissions
collection.deleteDocument('[document-id]')
collection.deleteDocument($documentSubscriber)
// delete a document from collection by id or by the document
collection.updateDocument('[document-id]', { name: 'John', lastname: 'Doe' }, [/* ...permissions */])
collection.updateDocument($documentSubscriber, { name: 'John', lastname: 'Doe' }, [/* ...permissions */])
// update a document from collection by id or by the document
const [paginator, paginatorInitalLoading] = collection.createPaginate(10, [/* ...queries */])
// paginate the collection of documents with limit and automatically rerender on change
// paginator.next() makes the next request for items, paginator store automatically rerender on next load
const [scrollData, scrollDispatch] = collection.createInfinityScrollDispatcher(10, [/* ...queries */], { /* intersection observer options */ })
// load next data after scroll to anchor (scrollDispatch) element
</script>
<div>
{#if $loading}
<p>Loading data from database...</p>
{:else}
{#each [...$subscriber, ...$insertSubscriber] as item}
<p>{item.name}</p>
{/each}
{/if}
</div>
<!-- scroll dispatcher example -->
<div>
{#each $scrollData as item}
<p>{item.name}</p>
{/each}
<div use:scrollDispatch on:fetch={(e) => console.log(e) /* on every fetch from scroll dispatcher do some action */} />
</div>
```
## Files subscribers
```svelte
<script>
import { Bucket } from '$lib/appwrite'
import { Query } from 'appwrite'
const bucket = new Bucket('[bucket-id]')
const [files, loading] = bucket.createSubscriber([Query.limit(5) /*, ...queries */])
// listen changes (update, delete) in files and automatically rerender on change
const insertSubscriber = bucket.createObserver()
// listen changes (create) in files and automatically rerender on change
const [upload, dispatch] = storage.createUploadDispatcher(/* many files ? true : false, default = false */)
const [content, loading] = storage.getFileContent('6391f7c70ede82115575')
// get file content and automatically rerender on file update
</script>
<div>
<input type="file" use:upload />
<button on:click={() => dispatch().then(uploadedFile => console.log(uploadedFile))}>Upload</button>
</div>
```
## Routing
Routes can be added in `__routes.svelte` file. Every route is fetched lazyly.
```svelte
<script lang="ts">
import Router from '$lib/router/Router.svelte'
import Layout from '$src/__layout.svelte'
import Loading from '$src/__loading.svelte'
import Error from '$src/__error.svelte'
</script>
<Router
layout={Layout}
loading={Loading}
error={Error}
routes={[
{
path: '/',
component: () => import('$routes/index.svelte'),
},
{
path: '/oauth',
component: () => import('$routes/oauth/index.svelte'),
},
{
path: '/oauth/failure',
component: () => import('$routes/oauth/failure.svelte'),
},
{
path: '/oauth/success',
component: () => import('$routes/oauth/success.svelte'),
},
]}
/>
```
### Routes structure
`__layout.svelte` the default layout for every page
`__error.svelte` the error page (404 error)
`__loading.svelte` the default loading component
`__routes.svelte` the file includes all routes in application
## auth/user
```svelte
<script>
import { user } from '$lib/appwrite'
</script>
<div>
{#if $user}
user: {$user.name}
<button on:click={() => user.destroySession('current')}>Logout</button>
{:else}
<button on:click={() => user.createEmailSession('[email]', '[password]')}>Login</button>
{/if}
</div>
```
## i18n
Locale file `src/locales/en.json`
```json
{
"page": {
"home": {
"title": "Appwrite svelte rocket start 🚀"
}
}
}
```
```svelte
<script>
import { _, locale, locales } from 'svelte-i18n'
</script>
<div>
<h1>{$_('page.home.title')}</h1>
<div>
<p>Change language:</p>
<select bind:value={$locale}>
{#each $locales as locale}
<option value={locale}>{locale}</option>
{/each}
</select>
</div>
</div>
```
## path aliases
`$lib` = `src/lib`
`$root` = `/`
`$src` = `src`
`$routes` = `src/routes`
## commands
```bash
npm run dev
```
```bash
npm run build
```
```bash
npm run preview
```
```bash
npm run appwrite
```
https://www.figma.com/file/mEaF6SbE8aP1WCo95f8dlV/Erant

9
composer.json Normal file
View File

@ -0,0 +1,9 @@
{
"config": {
"vendor-dir": "public/api/vendor"
},
"require": {
"bramus/router": "1.5",
"catfan/medoo": "^2.1"
}
}

146
composer.lock generated Normal file
View File

@ -0,0 +1,146 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "df49ce8601cf8f4f5d004e144d8ecaa5",
"packages": [
{
"name": "bramus/router",
"version": "1.5",
"source": {
"type": "git",
"url": "https://github.com/bramus/router.git",
"reference": "6adc0182dc6b0ebc22fd10543f65a36de10d8c05"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bramus/router/zipball/6adc0182dc6b0ebc22fd10543f65a36de10d8c05",
"reference": "6adc0182dc6b0ebc22fd10543f65a36de10d8c05",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~2.14",
"phpunit/php-code-coverage": "~2.0",
"phpunit/phpunit": "~4.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Bramus": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Bram(us) Van Damme",
"email": "bramus@bram.us",
"homepage": "http://www.bram.us"
}
],
"description": "A lightweight and simple object oriented PHP Router",
"homepage": "https://github.com/bramus/router",
"keywords": [
"router",
"routing"
],
"support": {
"issues": "https://github.com/bramus/router/issues",
"source": "https://github.com/bramus/router/tree/1.5"
},
"time": "2020-10-26T09:50:48+00:00"
},
{
"name": "catfan/medoo",
"version": "v2.1.7",
"source": {
"type": "git",
"url": "https://github.com/catfan/Medoo.git",
"reference": "74be58f80d330d1075ef3bfd0fb3d057349597ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/catfan/Medoo/zipball/74be58f80d330d1075ef3bfd0fb3d057349597ae",
"reference": "74be58f80d330d1075ef3bfd0fb3d057349597ae",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"php": ">=7.3"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
},
"suggest": {
"ext-pdo_dblib": "For MSSQL or Sybase database on Linux/UNIX platform",
"ext-pdo_mysql": "For MySQL or MariaDB database",
"ext-pdo_oci": "For Oracle database",
"ext-pdo_pqsql": "For PostgreSQL database",
"ext-pdo_sqlite": "For SQLite database",
"ext-pdo_sqlsrv": "For MSSQL database on both Window/Liunx platform"
},
"type": "framework",
"autoload": {
"psr-4": {
"Medoo\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Angel Lai",
"email": "angel@medoo.in"
}
],
"description": "The lightweight PHP database framework to accelerate development",
"homepage": "https://medoo.in",
"keywords": [
"database",
"database library",
"lightweight",
"mariadb",
"mssql",
"mysql",
"oracle",
"php framework",
"postgresql",
"sql",
"sqlite"
],
"support": {
"issues": "https://github.com/catfan/Medoo/issues",
"source": "https://github.com/catfan/Medoo"
},
"funding": [
{
"url": "https://paypal.me/AngelaonLai",
"type": "custom"
},
{
"url": "https://opencollective.com/medoo",
"type": "open_collective"
}
],
"time": "2022-07-02T04:27:50+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.1.0"
}

View File

@ -3,12 +3,42 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" href="/favicon.ico" />
<link rel="manifest" href="/webmanifest.json" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Svelte + Appwrite</title>
<title>Erant</title>
<!-- Meta Pixel Code -->
<script>
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '541491674547104');
fbq('track', 'PageView');
</script>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=541491674547104&ev=PageView&noscript=1"
/></noscript>
<!-- End Meta Pixel Code -->
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XJMWVPP9DC"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XJMWVPP9DC');
</script>
</head>
<body>
<noscript>Tato stránka potřebuje Javascript.</noscript>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>

View File

@ -1,8 +1,8 @@
{
"compilerOptions": {
"moduleResolution": "Node",
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"target": "esnext",
"module": "esnext",
/**
* svelte-preprocess cannot figure out whether you have
* a value or a type, so tell TypeScript to enforce using
@ -19,6 +19,7 @@
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable this if you'd like to use dynamic types.

View File

@ -1,6 +1,6 @@
const autoprefixer = require('autoprefixer')
const tailwind = require('tailwindcss')
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
plugins: [tailwind(), autoprefixer()],
}

View File

@ -5,6 +5,7 @@
import { onMount } from 'svelte'
import Routes from './__routes.svelte'
import CookiesPopUp from '$lib/components/Cookies/CookiesPopUp.svelte'
let isMounted = false
$: isReady = $localeLoading === false && $authLoading === false && isMounted
@ -25,6 +26,8 @@
</script>
<div>
<CookiesPopUp />
<!-- you can display loading while app is not ready (waiting for user and i18n) -->
{#if isReady}
<Routes />

View File

@ -13,7 +13,43 @@
routes={[
{
path: '/',
component: () => import('$routes/index.svelte'),
component: () => import('$routes/homepage/homepage.svelte'),
},
{
path: '/error',
component: () => import('$routes/error.svelte'),
},
{
path: '/scanner',
component: () => import('$routes/qrscanner/qrscanner.svelte'),
},
{
path: '/test',
component: () => import('$routes/test.svelte'),
},
{
path: '/map',
component: () => import('$routes/map.svelte'),
},
{
path: '/explore',
component: () => import('$routes/explore/explore.svelte'),
},
{
path: '/profile',
component: () => import('$routes/profile/profile.svelte'),
},
{
path: '/login',
component: () => import('$routes/log_in.svelte'),
},
{
path: '/register',
component: () => import('$routes/log_in.svelte'),
},
{
path: '/:gameurl',
component: () => import('$routes/game/game.svelte'),
},
]}
/>

10
src/fonts.scss Normal file
View File

@ -0,0 +1,10 @@
@font-face {
font-family: "Source Sans Pro";
src: url("/assets/fonts/SourceSansPro-Regular.ttf") format("ttf");
}
@font-face {
font-family: "Source Sans Pro";
font-style: italic;
src: url("/assets/fonts/SourceSansPro-Italic.ttf") format("ttf");
}

View File

@ -0,0 +1,53 @@
<script>
import { navigate } from 'svelte-routing'
export let href = ''
import { createEventDispatcher } from 'svelte'
const dispatch = createEventDispatcher()
export let primary = false
export let style = ''
let className = ''
export { className as class }
</script>
<button {style} on:click={() => navigate(href)} on:click={() => dispatch('submit', true)} on:click class={className} class:primary>
<slot />
</button>
<style lang="scss">
button {
border-radius: 25px;
cursor: pointer;
display: inline-block;
font-size: 30px;
font-weight: 600;
line-height: 20px;
padding: 20px;
text-align: center;
outline: none;
box-shadow: none;
border: none;
transition: background-color 0.3s;
background-color: rgb(232, 232, 232);
color: #4263eb;
word-break: break-word;
overflow: auto;
&.primary {
color: white;
background-color: rgb(66, 99, 235);
&:hover {
background-color: rgba(66, 99, 235, 0.8);
}
}
&:hover {
background-color: rgb(232, 232, 232, 0.8);
}
}
</style>

View File

@ -0,0 +1,55 @@
<script>
export let shareData
const share = async () => {
if ('share' in window.navigator && navigator.canShare(shareData)) {
await navigator.share(shareData)
} else {
navigator.clipboard.writeText(shareData.url)
}
}
</script>
<button on:click={share}>
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g filter="url(#filter0_i_956_444)">
<rect width="42" height="42" fill="url(#share_svelteSvgPictureid)" />
</g>
<defs>
<filter id="filter0_i_956_444" x="0" y="0" width="42" height="42" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
<feOffset dx="436" dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix type="matrix" values="0 0 0 0 0.258824 0 0 0 0 0.388235 0 0 0 0 0.921569 0 0 0 1 0" />
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_956_444" />
</filter>
<pattern id="share_svelteSvgPictureid" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_956_444" transform="scale(0.00520833)" />
</pattern>
<image
id="image0_956_444"
width="192"
height="192"
xlink:href="data:image/png;base64,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"
/>
</defs>
</svg>
</button>
<style lang="scss">
button {
cursor: pointer;
background: #e8e8e8;
border-radius: 16px;
z-index: 6;
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
border: none;
outline: none;
}
</style>

View File

@ -0,0 +1,42 @@
<script>
const col = {
blue: '#4263EB',
white: 'white',
txt_blue: 'white',
txt_white: '#999999',
}
export let background
</script>
<div class="bubble" style={`background: ${col[background]}; color: ${col[`txt_${background}`]}`}>
<slot name="icon" />
<span class="text"><slot /></span>
</div>
<style>
.bubble {
border-radius: 20px;
width: fit-content;
height: 38px;
display: flex;
align-items: center;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 6px 10px;
gap: 10px;
border: 1px solid #4263eb;
font-size: 17px;
color: white;
}
.text {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
font-size: 20px;
line-height: 25px;
display: flex;
align-items: center;
text-align: center;
}
</style>

View File

@ -0,0 +1,266 @@
<script>
import { onMount } from 'svelte';
// 420 px
export var images = [{"color":"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg"}, {"color":"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg"}, {"color":"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg"}, {"color":"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg"}, {"color":"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg"}]
let default_index = 3
let x = 0
$: scrollProgress = parseFloat((x/width).toFixed(6))
let width = null
let height = null
let func = 0.1
let mp = [-3, -2, -1]
let nav = []
for (let i = 0; i < images.length + 3; i++)
{
mp.push(mp.at(-1) + 1)
}
for (let i = 0; i < images.length ; i++)
{
if (i === 0){
nav.push({"status":"active"})
}
else{
nav.push({"status":"wait"})
}
}
let carousel
onMount(() => {
onLoad(carousel)
window.onresize = () =>{onLoad(carousel)}
});
function onLoad(self) {
width = self.getBoundingClientRect().width/100*70
height = self.getBoundingClientRect().width/100*70 / 1.5
images=images;
if (self.getBoundingClientRect().width < 440){
func = 0.05
}
else{
func = 0.1
}
}
function getWidth(x){
var res = width - width*0.3*Math.abs(x)
if (res > 0){return res}
else{return 0}
}
function getMargin(x){
var m = 1000
if (x<=-1.75){
x = -(1.75+(x+1.75))
if (x>=0){
x=0
}
}
else if (x>=1.75){
x = 1.75-(x-1.75)
if (x<=0){
x=0
}
}
if (x > 0){
x = Math.abs(x)
return "margin-left: -"+ m*func*x +"px"
}
else if (x === 0){return "margin: 0px;"}
else{
x = Math.abs(x)
return "margin-right: -" + m*func*x +"px"
}
}
function zIndex(x){
if (x>-0.5&&x<0.5){
return 2
}
else if ((x>-1.5&&x<=-0.5)||(x>=0.5&&x<1.5))
{
return 1
}
else if ((x<=-2.5)||(x>=2.5))
{
return -1
}
else
{
return 0
}
}
</script>
<div class="container">
<div id=carousel bind:this={carousel} on:scroll={() => x=carousel.scrollLeft} style="height: {height}px;">
<div class="sticky">
{#each Array(default_index) as _, index (index)}
<div class="item fake" style="
display: {mp.at(index)-scrollProgress<=-3.5||mp.at(index)-scrollProgress>3.5 ? "none" : "block"};
min-width: {getWidth(mp.at(index)-scrollProgress)}px;
max-width: {getWidth(mp.at(index)-scrollProgress)}px;
min-height: {height + height*(-func*(mp.at(index)-scrollProgress)*(mp.at(index)-scrollProgress))}px;
z-index: {zIndex(mp.at(index)-scrollProgress)};
{getMargin(mp.at(index)-scrollProgress)};">
</div>
{/each}
{#each images as image, index (index)}
<div class="item real" style="text-align:center;
display: {mp.at(index+default_index)-scrollProgress<=-3.5||mp.at(index+default_index)-scrollProgress>3.5 ? "none" : "block"};
min-width: {getWidth(mp.at(index+default_index)-scrollProgress)}px;
max-width: {getWidth(mp.at(index+default_index)-scrollProgress)}px;
z-index: {zIndex(mp.at(index+default_index)-scrollProgress)};
{getMargin(mp.at(index+default_index)-scrollProgress)}">
<img src={image.color}>
</div>
{/each}
{#each Array(3) as _, index (index)}
<div class="item fake" style="
display: {mp.at(-default_index+index)-scrollProgress<=-3.5||mp.at(-default_index+index)-scrollProgress>3.5 ? "none" : "block"};
min-width: {getWidth(mp.at(-default_index+index)-scrollProgress)}px;
max-width: {getWidth(mp.at(-default_index+index)-scrollProgress)}px;
min-height: {height + height*(-func*(mp.at(-default_index+index)-scrollProgress)*(mp.at(-default_index+index)-scrollProgress))}px;
z-index: {zIndex(mp.at(-default_index+index)-scrollProgress)};
{getMargin(mp.at(-default_index+index)-scrollProgress)}">
</div>
{/each}
<div class="overlay">
</div>
</div>
{#each Array(images.length-1) as _}
<div class="scroll-guide" style="min-width: {(width)}px; min-height: 10px; scroll-snap-align: start end;">
</div>
{/each}
</div>
<div class="slide-navigation">
{#each Array(images.length) as _, index (index)}
{#if Math.round(scrollProgress) == index}
<span class="active"></span>
{:else}
<span></span>
{/if}
{/each}
</div>
</div>
<style>
.container{
display: flex;
flex-direction: column;
align-items: center;
}
#carousel{
margin-top: 20px;
margin-bottom: 10px;
display: flex;
flex-direction: row;
align-items: center;
max-width: 100%;
min-width: 100%;
width: 100%;
position: relative;
scroll-snap-type: x mandatory;
overflow-x: scroll;
scroll-behavior: auto;
}
/* Hide scrollbar for Chrome, Safari and Opera */
#carousel::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
#carousel {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
#carousel > .sticky{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
position: sticky;
left: 0;
top: 0;
gap: 0px;
min-width: 100%;
max-width: 100%;
width: 100%;
overflow: hidden;
scroll-snap-align: end;
}
#carousel > .sticky > .item{
border-radius: 10px;
min-width: 0;
color: white;
overflow: hidden;
}
#carousel > .sticky > .overlay{
position: absolute;
left: 0px;
top: 0;
width: 100%;
height: 100%;
/* Mask */
background: linear-gradient(270deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.1) 20%, rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 50.56%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0.1) 80%, rgba(255, 255, 255, 0.6) 100%);
transform: matrix(1, 0, 0, -1, 0, 0);
z-index: 10;
}
#carousel > .sticky > .real{
display: flex;
align-items: stretch;
justify-content: stretch;
position: relative;
}
#carousel > .sticky > .real > img{
flex-grow: 1;
}
#carousel > .sticky > .fake {
background-color: white;
}
.slide-navigation{
height: fit-content;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-evenly;
gap: 5px;
width: 80px;
}
.slide-navigation > span{
width: 6px;
height: 6px;
border-radius: 6px;
background-color: #999999;
}
.slide-navigation > .active{
background-color: #7B61FF;
}
</style>

View File

@ -0,0 +1,14 @@
<div>
<slot />
</div>
<style>
div {
width: 100vw;
position: relative;
left: 50%;
right: 50%;
margin-left: -50vw;
margin-right: -50vw;
}
</style>

View File

@ -0,0 +1,17 @@
<script>
export let src
let className
export { className as class }
</script>
<section class={className} style="--bg: url({src});" />
<style lang="scss">
section {
border-radius: 26px;
background-image: var(--bg);
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
</style>

View File

@ -0,0 +1,35 @@
<script>
import Image from './Image.svelte'
export let images
let windowsize
let overflow = 'hidden'
const nextImages = () => {
overflow = 'auto'
images = images
windowsize = Infinity
}
</script>
<div style="overflow-y: {overflow}" bind:offsetWidth={windowsize} class="imageSlider">
{#each images as image, i}
<!--{#if Math.floor(windowsize / (94 + 10)) >= i + 1}-->
<div>
<Image src={image} class="w-24 h-24" />
<!--{#if Math.floor(windowsize / (94 + 10)) === i + 1 && images.length !== i + 1}
<span on:click={nextImages} class="imageCounter">{`+${images.length - Math.floor(windowsize / (94 + 10))}`}</span>
{/if}-->
</div>
<!--{/if}-->
{/each}
</div>
<style>
.imageSlider {
display: flex;
justify-content: space-between;
width: 100%;
gap: 10px;
position: relative;
}
</style>

View File

@ -0,0 +1,12 @@
<script>
let className = ''
export { className as class }
</script>
<div class={'w-full h-min ' + className} />
<style>
div {
border-top: 1px solid #efeff0;
}
</style>

View File

@ -0,0 +1,42 @@
<script lang="ts">
export let active: boolean = false
export let name: string = ''
export let url: string = ''
</script>
<button on:click>
<slot />
{#if active}
<p class="active" style="color:#4263EB">{name}</p>
{:else}
<p>{name}</p>
{/if}
</button>
<style>
@import url('https://fonts.googleapis.com/css2?family=Work+Sans:wght@500&display=swap');
button {
height: 54px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
}
button:hover,
button:active {
opacity: 70%;
}
button > p {
font-family: 'Work Sans';
font-style: normal;
font-weight: 500;
font-size: 11px;
line-height: 16px;
text-align: center;
color: #61646b;
}
</style>

View File

@ -0,0 +1,9 @@
<script>
import { onMount } from 'svelte'
import { navigate } from 'svelte-routing'
export let to = '/'
export let replace = false
onMount(() => navigate(to, { replace }))
</script>

View File

@ -0,0 +1,36 @@
<script>
export let style = ''
export let title = ''
let className = ''
export { className as class }
</script>
<section class={className} {style}>
<h2><slot name="title">{title}</slot></h2>
<div><slot /></div>
</section>
<style lang="scss">
section {
display: flex;
flex-direction: column;
row-gap: 20px;
width: 100%;
h2 {
font-style: normal;
font-weight: 600;
font-size: 24px;
line-height: 30px;
color: #110042;
}
div {
font-style: normal;
font-weight: 400;
font-size: 20px;
line-height: 25px;
}
}
</style>

View File

@ -0,0 +1,8 @@
<script>
let className = ''
export { className as class }
</script>
<div class={'w-full h-auto flex flex-wrap flex-row justify-normal items-center gap-4 ' + className}>
<slot />
</div>

View File

@ -0,0 +1,61 @@
<script>
import Times from './../../svg/Times.svelte'
import Setting from './../../svg/Setting.svelte'
import { navigate } from 'svelte-routing'
import { onMount } from 'svelte'
let showCookiePopUp = localStorage.getItem('cookies') !== 'dismissed'
let animation = false
let url = window.location.href
onMount(() => {
if (url.replace(window.location.origin, "") === "/"){
if (localStorage.getItem("ErantFirstTime") == null){
animation = true
setTimeout(() => {
animation = false
localStorage.setItem('ErantFirstTime', "false");
}, 5000)
}
}
})
</script>
{#if showCookiePopUp && !animation}
<div class="cookies">
<div
class="shadow w-[calc(var(--max-viewport-width))] max-w-[98%] h-auto rounded-[6px] overflow-hidden absolute bottom-0 bg-white gap-4 z-50 mb-[10px] flex flex-wrap flex-row justify-self-center"
>
<div class="w-full h-min grid grid-cols-[min-content_auto_min-content] gap-4 p-[16px]">
<button on:click={() => navigate('cookies/settings')} class="w-min h-min flex-grow-0"><Setting /></button>
<div class="flex flex-wrap flex-row gap-2">
<div class="text-[28px] font-semibold">Cookies settings</div>
<div>Our website uses cookies to operate, by continuing you agree to our <a class="text-[#4263EB]" href="/cookies/policy">cookie policy</a>.</div>
</div>
<button on:click={() => (showCookiePopUp = false)} class="w-min h-min relative flex-grow-0"><Times /></button>
</div>
<div class="w-full h-auto flex justify-end bg-[#F3F4F6] p-[16px]">
<button
on:click={() => {
showCookiePopUp = false
localStorage.setItem('cookies', 'dismissed')
}}
class="w-[84px] h-[37px] bg-[#09205D] text-white rounded-[8px] text-[18px]">Dismiss</button
>
</div>
</div>
</div>
{/if}
<style lang="scss">
.cookies{
width: 100%;
height: 100vh;
position: absolute;
z-index: 9999;
backdrop-filter: blur(5px) brightness(60%);
}
.shadow {
box-shadow: 0 0 1px;
left: 50%;
transform: translate(-50%, 0);
}
</style>

View File

@ -0,0 +1,39 @@
<script>
import { idGenerator } from '$lib/utils/IdGenerator'
const id = idGenerator()
export let checked = true
</script>
<div class="cover h-14">
<div class="h-14 w-14 flex justify-center items-center">
<input
{id}
bind:checked
type="checkbox"
class="relative w-[3.25rem] h-7 bg-gray-100 checked:bg-none checked:bg-[#96ddff] border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 border border-transparent ring-1 ring-transparent focus:border-[#96ddff] focus:ring-[#96ddff] ring-offset-white focus:outline-none appearance-none before:inline-block before:w-6 before:h-6 before:bg-white checked:before:bg-[var(--blue)] before:translate-x-0 checked:before:translate-x-full before:shadow before:rounded-full before:transform before:ring-0 before:transition before:ease-in-out before:duration-20"
/>
</div>
<label for={id}><slot /></label>
</div>
<style>
.cover {
height: 100%;
width: fit-content;
background: white;
display: grid;
grid-template-columns: 56px auto;
gap: 20px;
padding: 4px;
}
label {
font-size: 100%;
width: 100%;
height: 100%;
display: flex;
align-items: center;
font-size: 140%;
}
</style>

View File

@ -0,0 +1,65 @@
<script>
import Eye from '../../svg/Eye.svelte'
export let name = ''
export let placeholder = ''
let input
let vissible = false
function changeVisibility(i) {
if (!vissible) {
i.type = 'text'
vissible = true
} else {
i.type = 'password'
vissible = false
}
}
</script>
<div>
<input bind:this={input} type="password" {name} {placeholder} minlength="8" class="input" required />
<button type="button" on:click={changeVisibility(input)}>
<Eye active={vissible} />
</button>
</div>
<style lang="scss">
div {
width: 100%;
position: relative;
button {
position: absolute;
right: 25px;
top: 50%;
transform: translateY(-50%);
}
button:hover {
opacity: 50%;
}
}
.input {
width: calc(100%);
padding: 12px 24px;
border-radius: 15px;
background-color: #eeeeee;
font-size: 18px;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
line-height: 28px;
@media screen and (max-height: 720px) {
padding: 8px 24px;
}
}
::placeholder {
color: #8f8f8f;
font-size: 18px;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
line-height: 28px;
}
</style>

View File

@ -0,0 +1,31 @@
<script>
export let value = ''
export let type = 'text'
export let placeholder = ''
let className
export { className as class }
function typeAction(node) {
node.type = type
}
</script>
<input bind:value class="input {className}" use:typeAction {placeholder} on:input />
<style>
input {
background-color: rgb(232, 232, 232);
color: var(--blue);
background: white;
border: 4px solid var(--blue);
border-radius: 25px;
text-align: left;
font-size: 30px;
font-weight: 600;
line-height: 20px;
padding: 28px 20px;
outline: none;
appearance: none;
}
</style>

View File

@ -0,0 +1,7 @@
<script>
import InputPicture from '$lib/svg/InputPicture.svelte'
</script>
<div>
<InputPicture />
</div>

View File

@ -0,0 +1,52 @@
<script>
import { idGenerator } from '../../utils/IdGenerator'
const id = idGenerator()
export let group = false
export let value
</script>
<div class="cover h-14 cursor-pointer">
<div class="h-14 w-14 flex justify-center items-center">
<input {id} bind:group {value} type="radio" class="w-6 h-6 absolute flex justify-center items-center text-red-600 bg-gray-100 border-gray-300" />
</div>
<label for={id}><slot /></label>
</div>
<style lang="scss">
.cover {
height: 100%;
width: fit-content;
background: white;
display: grid;
grid-template-columns: 56px auto;
gap: 20px;
padding: 4px;
label {
font-size: 100%;
width: 100%;
height: 100%;
display: flex;
align-items: center;
font-size: 140%;
}
input:checked {
appearance: none;
background-color: var(--blue);
border-radius: 100%;
border: 2px solid black;
}
input:checked::before {
content: '';
height: 40%;
width: 40%;
background: black;
position: absolute;
border-radius: 100%;
}
}
/*border: 4px solid var(--blue);
box-shadow: 0 0 4px var(--blue), 0 0 1px var(--blue) inset;
border-radius: var(--border-radius);*/
</style>

View File

@ -0,0 +1,33 @@
<script>
</script>
<div class="cover h-14">
<div class="h-14 w-14 flex justify-center items-center">
<input type="range" min="1" max="11" step="2" />
</div>
<span><slot /></span>
</div>
<style lang="scss">
.cover {
height: 100%;
width: fit-content;
background: white;
display: grid;
grid-template-columns: 56px auto;
gap: 20px;
padding: 4px;
span {
font-size: 100%;
width: 100%;
height: 100%;
display: flex;
align-items: center;
font-size: 140%;
}
}
/*border: 4px solid var(--blue);
box-shadow: 0 0 4px var(--blue), 0 0 1px var(--blue) inset;
border-radius: var(--border-radius);*/
</style>

View File

@ -0,0 +1,72 @@
<script>
import Sharebutton from '../Buttons/Sharebutton.svelte'
export let img = null
export let shareData = null
export let alt = 'background image'
</script>
<div class="h-full w-full overflow-auto">
<section class="wraper">
{#if img}
<img src={img} {alt} />
{/if}
{#if shareData !== null && shareData !== false}
<div class="shareButton">
<Sharebutton {shareData} />
</div>
{/if}
<section class="overlay">
<slot />
</section>
</section>
</div>
<style lang="scss">
.wraper {
position: relative;
height: 100%;
width: 100%;
clip-path: inset(0);
overflow: auto;
.overlay {
min-height: 75vh;
height: auto;
width: 100%;
overflow-y: auto;
position: absolute;
top: 25%;
border-radius: 70px 70px 0 0;
padding: 52px;
display: flex;
flex-direction: column;
row-gap: 35px;
z-index: 7;
background-color: white;
}
img {
z-index: 4;
width: 100%;
height: auto;
position: absolute;
}
.shareButton {
width: 100%;
height: calc(100% - 75%);
display: flex;
justify-content: flex-end;
align-items: center;
position: absolute;
top: 0;
padding: 50px;
background: none;
clip-path: inset(0);
z-index: 6;
@media (min-width: 768px) {
position: absolute;
}
}
}
</style>

View File

@ -0,0 +1,86 @@
<script>
import { navigate } from 'svelte-routing'
import FooterItem from '../common/NavBar_Item.svelte'
let items = [
{
name: 'Home',
url: '/',
image_url:
"data:image/svg+xml,%3Csvg width='23' height='24' viewBox='0 0 23 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.1572 22.2352V18.6679C8.1572 17.7573 8.90083 17.019 9.81813 17.019H13.1713C13.6118 17.019 14.0343 17.1928 14.3458 17.502C14.6573 17.8112 14.8323 18.2306 14.8323 18.6679V22.2352C14.8295 22.6138 14.979 22.9779 15.2477 23.2465C15.5164 23.5152 15.882 23.6663 16.2634 23.6663H18.5511C19.6195 23.6691 20.6452 23.2497 21.4017 22.5006C22.1581 21.7516 22.5833 20.7345 22.5833 19.6738V9.51101C22.5833 8.65421 22.2007 7.84149 21.5387 7.29179L13.7563 1.12152C12.4026 0.0396631 10.4629 0.0745936 9.14958 1.20448L1.54481 7.29179C0.85149 7.82529 0.437104 8.64042 0.416626 9.51101V19.6634C0.416626 21.8742 2.2219 23.6663 4.44883 23.6663H6.6843C7.47639 23.6663 8.12012 23.0319 8.12586 22.2456L8.1572 22.2352Z' fill='%2361646B'/%3E%3C/svg%3E%0A",
},
{
name: 'Explore',
url: '/explore',
image_url:
"data:image/svg+xml,%3Csvg width='26' height='25' viewBox='0 0 26 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11.58 11.0798L10.3585 14.9846L14.2622 13.7619L15.4848 9.85711L11.58 11.0798ZM9.02384 17.1931C8.79517 17.1931 8.57117 17.1033 8.40434 16.9376C8.17451 16.7066 8.09051 16.3671 8.18851 16.0579L10.047 10.1208C10.1322 9.84545 10.3468 9.63195 10.6198 9.54678L16.557 7.68828C16.8685 7.58911 17.2068 7.67428 17.4378 7.90411C17.6677 8.13511 17.7517 8.47461 17.6537 8.78378L15.7963 14.7209C15.7112 14.9951 15.4953 15.2098 15.2223 15.2949L9.28517 17.1534C9.19884 17.1803 9.11017 17.1931 9.02384 17.1931Z' fill='%2361646B'/%3E%3Cmask id='mask0_1515_2517' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='0' y='0' width='26' height='25'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0.833374 0.333008H25.0088V24.5083H0.833374V0.333008Z' fill='white'/%3E%3C/mask%3E%3Cg mask='url(%23mask0_1515_2517)'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12.921 2.08301C7.22063 2.08301 2.58313 6.72167 2.58313 12.4208C2.58313 18.1212 7.22063 22.7587 12.921 22.7587C18.6213 22.7587 23.2588 18.1212 23.2588 12.4208C23.2588 6.72167 18.6213 2.08301 12.921 2.08301M12.921 24.5087C6.2558 24.5087 0.83313 19.086 0.83313 12.4208C0.83313 5.75567 6.2558 0.333008 12.921 0.333008C19.5861 0.333008 25.0088 5.75567 25.0088 12.4208C25.0088 19.086 19.5861 24.5087 12.921 24.5087' fill='%2361646B'/%3E%3C/g%3E%3C/svg%3E ",
},
{
name: 'Map',
url: '/map',
image_url:
"data:image/svg+xml,%3Csvg width='18' height='24' viewBox='0 0 18 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0.833496 8.80925C0.833496 4.29425 4.48516 0.642578 9.00016 0.642578C13.5152 0.642578 17.1668 4.29425 17.1668 8.80925C17.1668 13.6742 12.0102 20.3826 9.8985 22.9376C9.43183 23.4976 8.58016 23.4976 8.1135 22.9376C5.99016 20.3826 0.833496 13.6742 0.833496 8.80925ZM6.0835 8.80925C6.0835 10.4192 7.39016 11.7259 9.00016 11.7259C10.6102 11.7259 11.9168 10.4192 11.9168 8.80925C11.9168 7.19924 10.6102 5.89258 9.00016 5.89258C7.39016 5.89258 6.0835 7.19924 6.0835 8.80925Z' fill='%2361646B' /%3E%3C/svg%3E%0A",
},
{
name: 'Trips',
url: '',
image_url:
"data:image/svg+xml,%3Csvg width='26' height='22' viewBox='0 0 26 22' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15.3662 5.53348C14.8832 5.53348 14.4912 5.14148 14.4912 4.65848V1.83398C14.4912 1.35098 14.8832 0.958984 15.3662 0.958984C15.8492 0.958984 16.2412 1.35098 16.2412 1.83398V4.65848C16.2412 5.14148 15.8492 5.53348 15.3662 5.53348Z' fill='%2361646B'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15.3662 20.8318C14.8832 20.8318 14.4912 20.4398 14.4912 19.9568V17.5967C14.4912 17.1125 14.8832 16.7217 15.3662 16.7217C15.8492 16.7217 16.2412 17.1125 16.2412 17.5967V19.9568C16.2412 20.4398 15.8492 20.8318 15.3662 20.8318Z' fill='%2361646B'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M15.3662 14.4634C14.8832 14.4634 14.4912 14.0714 14.4912 13.5884V7.96387C14.4912 7.48087 14.8832 7.08887 15.3662 7.08887C15.8492 7.08887 16.2412 7.48087 16.2412 7.96387V13.5884C16.2412 14.0714 15.8492 14.4634 15.3662 14.4634Z' fill='%2361646B'/%3E%3Cmask id='mask0_1515_513' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='0' y='0' width='26' height='22'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0.666626 0.666992H25.75V21.0833H0.666626V0.666992Z' fill='white'/%3E%3C/mask%3E%3Cg mask='url(%23mask0_1515_513)'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M2.41663 14.1467V16.4088C2.41663 18.0212 3.75013 19.3337 5.38929 19.3337H21.0273C22.6665 19.3337 24 18.0212 24 16.4088V14.1467C22.5405 13.7628 21.4601 12.4422 21.4601 10.8765C21.4601 9.30966 22.5393 7.99016 24 7.60633L23.9988 5.34183C23.9988 3.72949 22.6653 2.41699 21.0261 2.41699H5.39046C3.75129 2.41699 2.41779 3.72949 2.41779 5.34183L2.41663 7.69616C3.89479 8.05899 4.95646 9.32599 4.95646 10.8765C4.95646 12.4422 3.87613 13.7628 2.41663 14.1467ZM21.0273 21.0837H5.38929C2.78529 21.0837 0.666626 18.986 0.666626 16.4088V13.3848C0.666626 12.9018 1.05863 12.5098 1.54163 12.5098C2.45979 12.5098 3.20646 11.7772 3.20646 10.8765C3.20646 10.0015 2.49013 9.34116 1.54163 9.34116C1.30946 9.34116 1.08663 9.24899 0.923293 9.08449C0.758793 8.92116 0.666626 8.69716 0.666626 8.46616L0.667793 5.34183C0.667793 2.76466 2.78646 0.666992 5.39046 0.666992H21.0261C23.6301 0.666992 25.7488 2.76466 25.7488 5.34183L25.75 8.36816C25.75 8.59916 25.6578 8.82316 25.4933 8.98649C25.33 9.15099 25.1071 9.24316 24.875 9.24316C23.9568 9.24316 23.2101 9.97583 23.2101 10.8765C23.2101 11.7772 23.9568 12.5098 24.875 12.5098C25.358 12.5098 25.75 12.9018 25.75 13.3848V16.4088C25.75 18.986 23.6313 21.0837 21.0273 21.0837Z' fill='%2361646B'/%3E%3C/g%3E%3C/svg%3E ",
},
{
name: 'Profile',
url: '/profile',
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 ",
},
]
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}
<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>
{:else}
<FooterItem on:click={() => navigate(url)} active={false} {name} {url}>
<img alt="" src={image_url} />
</FooterItem>
{/if}
{/each}
</div>
</div>
<style>
.footer {
width: 100%;
height: 100px;
position: absolute;
background: white;
bottom: 0px;
left: 0px;
border-top: 1px solid #efeff0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
padding: 15px 10px 25px 10px;
}
@media screen and (max-width: 320px) {
.footer {
gap: 0px;
justify-content: space-around;
padding: 10px 0 15px 0;
}
}
</style>

View File

@ -0,0 +1,88 @@
<script>
import GeolocateControl from '@beyonk/svelte-mapbox/src/lib/map/controls/GeolocateControl.svelte'
import Map from './Map.svelte'
import { navigate } from 'svelte-routing'
export let center
//$: console.log(center)
export let mapComponent
export let user = { lat: null, lng: null }
let className = ''
export { className as class }
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition)
} else {
alert("Can't load your location!")
}
function showPosition(position) {
user.lat = position.coords.latitude
user.lng = position.coords.longitude
}
</script>
<Map {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">
<button on:click={() => navigate('/scanner')}>
<svg viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.77778 8.66765C5.77778 7.07876 7.07778 5.77876 8.66667 5.77876H14.4445C16.0333 5.77876 17.3333 4.47876 17.3333 2.88987C17.3333 1.30098 16.0333 0.000976562 14.4445 0.000976562H5.77778C2.6 0.000976562 0 2.60098 0 5.77876V14.4454C0 16.0343 1.3 17.3343 2.88889 17.3343C4.47778 17.3343 5.77778 16.0343 5.77778 14.4454V8.66765ZM2.88889 34.666C1.3 34.666 0 35.966 0 37.5549V46.2216C0 49.3994 2.6 51.9994 5.77778 51.9994H14.4445C16.0333 51.9994 17.3333 50.6994 17.3333 49.1105C17.3333 47.5216 16.0333 46.2216 14.4445 46.2216H8.66667C7.07778 46.2216 5.77778 44.9216 5.77778 43.3327V37.5549C5.77778 35.966 4.47778 34.666 2.88889 34.666ZM37.5553 0.000976562H46.222C49.3998 0.000976562 51.9998 2.60098 51.9998 5.77876V14.4454C51.9998 16.0343 50.6998 17.3343 49.1109 17.3343C47.522 17.3343 46.222 16.0343 46.222 14.4454V8.66765C46.222 7.07876 44.922 5.77876 43.3331 5.77876H37.5553C35.9664 5.77876 34.6664 4.47876 34.6664 2.88987C34.6664 1.30098 35.9664 0.000976562 37.5553 0.000976562ZM46.2221 43.3327C46.2221 44.9216 44.9221 46.2216 43.3332 46.2216H37.5554C35.9665 46.2216 34.6665 47.5216 34.6665 49.1105C34.6665 50.6994 35.9665 51.9994 37.5554 51.9994H46.2221C49.3998 51.9994 51.9998 49.3994 51.9998 46.2216V37.5549C51.9998 35.966 50.6998 34.666 49.111 34.666C47.5221 34.666 46.2221 35.966 46.2221 37.5549V43.3327ZM28.8881 23.1085H23.1104V28.8838H17.3345V34.6616H23.1123V28.8862H28.8881V23.1085ZM23.1123 28.8862V28.8838H23.1104V28.8862H23.1123ZM28.8912 28.8838H34.6689V34.6616H28.8912V28.8838ZM34.669 17.3302H28.8913V23.108H34.669V17.3302ZM17.3345 17.3301H23.1123V23.1079H17.3345V17.3301Z"
fill="#4263EB"
/>
</svg>
</button>
<button on:click={() => document.getElementsByClassName('mapboxgl-ctrl-geolocate')[0].click()}>
<svg viewBox="0 0 29 39" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M0.758179 14.1551C0.758179 6.53234 6.92333 0.367188 14.5461 0.367188C22.1688 0.367188 28.3339 6.53234 28.3339 14.1551C28.3339 22.3687 19.6279 33.6945 16.0627 38.0081C15.2748 38.9536 13.837 38.9536 13.0491 38.0081C9.46424 33.6945 0.758179 22.3687 0.758179 14.1551ZM9.62182 14.1551C9.62182 16.8733 11.8279 19.0793 14.5461 19.0793C17.2642 19.0793 19.4703 16.8733 19.4703 14.1551C19.4703 11.4369 17.2642 9.23083 14.5461 9.23083C11.8279 9.23083 9.62182 11.4369 9.62182 14.1551Z"
fill="#4263EB"
/>
</svg>
</button>
</div>
<style>
.on {
position: absolute;
display: flex;
flex-direction: column;
gap: 27px;
right: 23px;
bottom: 140px;
}
button {
width: 60px;
height: 60px;
border-radius: 25px;
position: relative;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
}
button:hover,
button:active {
opacity: 70%;
}
button > svg {
height: 56%;
width: auto;
}
</style>

View File

@ -0,0 +1,56 @@
<script>
import { Map, controls } from '@beyonk/svelte-mapbox'
import GeolocateControl from '@beyonk/svelte-mapbox/src/lib/map/controls/GeolocateControl.svelte'
import { createEventDispatcher, onMount } from 'svelte'
export let mapComponent
let geolocateControl
let className = ''
export { className as class }
export let radius = false
export let center = { lng: 0, lat: 0 }
/*export const geo = (e) => {
geolocateControl.dispatchEvent('geolocate')
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
const { latitude, longitude } = position.coords
user = { lat: latitude, lng: longitude }
dispatch('move', user)
})
} else {
alert("Can't load your location!")
}
}*/
</script>
<div class={className} class:radius>
<Map
class="h-full"
accessToken="pk.eyJ1IjoiZXJhbnQ0MiIsImEiOiJjbDdybXo4dmswZ3E5M3FwMnFsazdpb3VoIn0.wXblbreOUt3e8N81CAH0Wg"
style="mapbox://styles/mapbox/outdoors-v11"
bind:this={mapComponent}
on:ready={() => {
mapComponent.resize()
mapComponent.setCenter([center.lng, center.lat], 14)
}}
zoom={14}
>
<slot />
</Map>
</div>
<style lang="scss">
div {
overflow: hidden;
&.radius {
border-radius: 25px;
}
}
:global(.mapboxgl-ctrl-top-left) {
display: none;
}
:global(.mapboxgl-marker) {
cursor: pointer;
}
</style>

View File

@ -0,0 +1,48 @@
<script>
import { Marker } from '@beyonk/svelte-mapbox'
import { createEventDispatcher, getContext } from 'svelte'
const dispatch = createEventDispatcher()
export let lat = 0
export let lng = 0
export let user = { lat: 0, lng: 0 }
export let round = (1 / 110.574 / 1000) * 12 //cca 12m nutno pozměnit!!!!!!!!!! tento komentář nemazat
let Mlat = [lat - round, lat + round]
let Mlng = [lng - round, lng + round]
$: isIn = user ? user.lat > Mlat[0] && user.lat < Mlat[1] && user.lng > Mlng[0] && user.lng < Mlng[1] : null
$: isIn && dispatch('enter', { lat, lng, user })
</script>
<Marker popup={false} {lat} {lng}>
<svg width="28" height="27" viewBox="0 0 112 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M64.488 103.367L89.7283 62.4464C106.409 35.4037 86.9542 0.547852 55.1801 0.547852C22.7617 0.547852 3.42399 36.6756 21.4041 63.6502L48.0703 103.656C52.0131 109.571 60.7561 109.417 64.488 103.367Z"
fill="url(#paint0_radial_1068_1071)"
fill-opacity="0.4"
/>
<path
d="M63.4756 91.4251L82.4058 60.4583C94.9161 39.9936 80.3252 13.6162 56.4947 13.6162C32.1808 13.6162 17.6776 40.9562 31.1627 61.3693L51.1623 91.644C54.1194 96.1203 60.6766 96.0037 63.4756 91.4251Z"
fill="url(#paint1_linear_1068_1071)"
/>
<circle cx="55.6164" cy="35.6164" r="11.6164" fill="white" />
<defs>
<radialGradient
id="paint0_radial_1068_1071"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(55.1781 54.2739) rotate(90.2138) scale(47.7265 37.7293)"
>
<stop offset="0.865366" stop-color="#FFD325" />
<stop offset="1" stop-color="#FFE066" stop-opacity="0.1" />
</radialGradient>
<linearGradient id="paint1_linear_1068_1071" x1="40.9078" y1="34.3967" x2="71.9265" y2="73.4203" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFBF00" />
<stop offset="1" stop-color="#DD8706" />
</linearGradient>
</defs>
</svg>
</Marker>

3
src/lib/stores/game.js Normal file
View File

@ -0,0 +1,3 @@
import { writable } from 'svelte/store'
export const data = writable(null)

8
src/lib/svg/Earth.svelte Normal file
View File

@ -0,0 +1,8 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M15 2.5C8.1 2.5 2.5 8.1 2.5 15C2.5 21.9 8.1 27.5 15 27.5C21.9 27.5 27.5 21.9 27.5 15C27.5 8.1 21.9 2.5 15 2.5ZM13.75 24.9125C8.8125 24.3 5 20.1 5 15C5 14.225 5.1 13.4875 5.2625 12.7625L11.25 18.75V20C11.25 21.375 12.375 22.5 13.75 22.5V24.9125ZM20 20C21.125 20 22.05 20.725 22.375 21.7375C24 19.9625 25 17.6 25 15C25 10.8125 22.4125 7.225 18.75 5.7375V6.25C18.75 7.625 17.625 8.75 16.25 8.75H13.75V11.25C13.75 11.9375 13.1875 12.5 12.5 12.5H10V15H17.5C18.1875 15 18.75 15.5625 18.75 16.25V20H20Z"
fill="#4263EB"
/>
</svg>

After

Width:  |  Height:  |  Size: 677 B

14
src/lib/svg/Eye.svelte Normal file
View File

@ -0,0 +1,14 @@
<script lang="ts">
export let active:boolean = false
</script>
{#if active}
<svg width="28" height="20" viewBox="0 0 28 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 0.625C7.75 0.625 2.4125 4.5125 0.25 10C2.4125 15.4875 7.75 19.375 14 19.375C20.25 19.375 25.5875 15.4875 27.75 10C25.5875 4.5125 20.25 0.625 14 0.625ZM14 16.25C10.55 16.25 7.75 13.45 7.75 10C7.75 6.55 10.55 3.75 14 3.75C17.45 3.75 20.25 6.55 20.25 10C20.25 13.45 17.45 16.25 14 16.25ZM10.25 10C10.25 7.925 11.925 6.25 14 6.25C16.075 6.25 17.75 7.925 17.75 10C17.75 12.075 16.075 13.75 14 13.75C11.925 13.75 10.25 12.075 10.25 10Z" fill="black" fill-opacity="1"/>
</svg>
{:else}
<svg width="28" height="20" viewBox="0 0 28 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 0.625C7.75 0.625 2.4125 4.5125 0.25 10C2.4125 15.4875 7.75 19.375 14 19.375C20.25 19.375 25.5875 15.4875 27.75 10C25.5875 4.5125 20.25 0.625 14 0.625ZM14 16.25C10.55 16.25 7.75 13.45 7.75 10C7.75 6.55 10.55 3.75 14 3.75C17.45 3.75 20.25 6.55 20.25 10C20.25 13.45 17.45 16.25 14 16.25ZM10.25 10C10.25 7.925 11.925 6.25 14 6.25C16.075 6.25 17.75 7.925 17.75 10C17.75 12.075 16.075 13.75 14 13.75C11.925 13.75 10.25 12.075 10.25 10Z" fill="black" fill-opacity="0.3"/>
</svg>
{/if}

View File

@ -0,0 +1,16 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M23.04 12.2615C23.04 11.446 22.9668 10.6619 22.8309 9.90918H12V14.3576H18.1891C17.9225 15.7951 17.1123 17.013 15.8943 17.8285V20.714H19.6109C21.7855 18.7119 23.04 15.7637 23.04 12.2615Z" fill="#4285F4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9999 23.4996C15.1049 23.4996 17.7081 22.4698 19.6108 20.7134L15.8943 17.828C14.8645 18.518 13.5472 18.9257 11.9999 18.9257C9.00471 18.9257 6.46948 16.9028 5.56516 14.1846H1.72311V17.1641C3.61539 20.9225 7.50448 23.4996 11.9999 23.4996Z" fill="#34A853"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.56523 14.1855C5.33523 13.4955 5.20455 12.7584 5.20455 12.0005C5.20455 11.2425 5.33523 10.5055 5.56523 9.81548V6.83594H1.72318C0.944318 8.38844 0.5 10.1448 0.5 12.0005C0.5 13.8562 0.944318 15.6125 1.72318 17.165L5.56523 14.1855Z" fill="#FBBC05"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9999 5.07386C13.6883 5.07386 15.2043 5.65409 16.3961 6.79364L19.6945 3.49523C17.7029 1.63955 15.0997 0.5 11.9999 0.5C7.50448 0.5 3.61539 3.07705 1.72311 6.83545L5.56516 9.815C6.46948 7.09682 9.00471 5.07386 11.9999 5.07386Z" fill="#EA4335"/>
</svg>
<style>
@media screen and (max-width: 330px) {
svg{
width: 7.2vw;
height: auto;
}
}
</style>

After

Width:  |  Height:  |  Size: 1.4 KiB

8
src/lib/svg/Help.svelte Normal file
View File

@ -0,0 +1,8 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M15 2.5C8.1 2.5 2.5 8.1 2.5 15C2.5 21.9 8.1 27.5 15 27.5C21.9 27.5 27.5 21.9 27.5 15C27.5 8.1 21.9 2.5 15 2.5ZM13.75 23.75V21.25H16.25V23.75H13.75ZM17.7125 15.2125L18.8375 14.0625C20.1125 12.7875 20.55 10.6 19.075 8.5625C17.95 7 16.1375 6.0125 14.2375 6.3125C12.3 6.6125 10.7375 8.0125 10.2 9.85C10 10.55 10.5 11.25 11.225 11.25H11.6C12.0875 11.25 12.475 10.9 12.625 10.4375C13.0375 9.25 14.325 8.4625 15.7125 8.85C16.5875 9.1 17.2875 9.8625 17.45 10.7625C17.6125 11.6375 17.3375 12.4625 16.7625 13.0125L15.2125 14.5875C14.6875 15.1125 14.275 15.7625 14.025 16.4875C13.85 17 13.75 17.55 13.75 18.125V18.75H16.25C16.25 18.175 16.3125 17.725 16.4125 17.325C16.6375 16.425 17.0875 15.85 17.7125 15.2125Z"
fill="#4263EB"
/>
</svg>

After

Width:  |  Height:  |  Size: 882 B

View File

@ -0,0 +1,27 @@
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="98" height="98" rx="49" fill="#EFEFF0" />
<mask id="mask0_1661_3075" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="40" y="40" width="20" height="20">
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.0005 40H59.9601V59.9498H40.0005V40Z" fill="white" />
</mask>
<g mask="url(#mask0_1661_3075)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M45.6505 41.5C43.1295 41.5 41.5005 43.227 41.5005 45.899V54.051C41.5005 56.724 43.1295 58.45 45.6505 58.45H54.3005C56.8275 58.45 58.4605 56.724 58.4605 54.051V45.899C58.4605 43.227 56.8275 41.5 54.3005 41.5H45.6505ZM54.3005 59.95H45.6505C42.2705 59.95 40.0005 57.579 40.0005 54.051V45.899C40.0005 42.371 42.2705 40 45.6505 40H54.3005C57.6855 40 59.9605 42.371 59.9605 45.899V54.051C59.9605 57.579 57.6855 59.95 54.3005 59.95Z"
fill="#AFB1B6"
/>
</g>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M43.2815 55.1799C43.0955 55.1799 42.9105 55.1119 42.7655 54.9739C42.4645 54.6899 42.4525 54.2139 42.7375 53.9149L44.2655 52.3019C45.0745 51.4429 46.4395 51.4009 47.3025 52.2109L48.2605 53.1829C48.5275 53.4529 48.9615 53.4579 49.2295 53.1939C49.3305 53.0749 51.5085 50.4299 51.5085 50.4299C51.9225 49.9279 52.5065 49.6179 53.1555 49.5539C53.8055 49.4969 54.4365 49.6859 54.9395 50.0989C54.9825 50.1339 55.0215 50.1679 57.2175 52.4229C57.5065 52.7189 57.5015 53.1939 57.2045 53.4829C56.9085 53.7739 56.4325 53.7649 56.1435 53.4689C56.1435 53.4689 54.0945 51.3659 53.9485 51.2239C53.7935 51.0969 53.5445 51.0229 53.2995 51.0469C53.0505 51.0719 52.8265 51.1909 52.6675 51.3839C50.3435 54.2029 50.3155 54.2299 50.2775 54.2669C49.4195 55.1089 48.0345 55.0949 47.1915 54.2349C47.1915 54.2349 46.2615 53.2909 46.2455 53.2719C46.0145 53.0579 45.6025 53.0719 45.3555 53.3329L43.8255 54.9459C43.6775 55.1019 43.4795 55.1799 43.2815 55.1799Z"
fill="#AFB1B6"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M46.5577 46.1289C46.0047 46.1289 45.5547 46.5789 45.5547 47.1329C45.5547 47.6869 46.0047 48.1379 46.5587 48.1379C47.1127 48.1379 47.5637 47.6869 47.5637 47.1329C47.5637 46.5799 47.1127 46.1299 46.5577 46.1289ZM46.5587 49.6379C45.1777 49.6379 44.0547 48.5139 44.0547 47.1329C44.0547 45.7519 45.1777 44.6289 46.5587 44.6289C47.9407 44.6299 49.0637 45.7539 49.0637 47.1329C49.0637 48.5139 47.9397 49.6379 46.5587 49.6379Z"
fill="#AFB1B6"
/>
<rect x="1" y="1" width="98" height="98" rx="49" stroke="#AFB1B6" stroke-width="2" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

26
src/lib/svg/Logout.svelte Normal file
View File

@ -0,0 +1,26 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g filter="url(#filter0_i_1625_3311)">
<rect width="30" height="30" fill="url(#pattern0)" />
</g>
<defs>
<filter id="filter0_i_1625_3311" x="0" y="0" width="30" height="30" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
<feOffset dx="61" dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix type="matrix" values="0 0 0 0 0.258824 0 0 0 0 0.388235 0 0 0 0 0.921569 0 0 0 1 0" />
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_1625_3311" />
</filter>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_1625_3311" transform="scale(0.0104167)" />
</pattern>
<image
id="image0_1625_3311"
width="96"
height="96"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAABmJLR0QA/wD/AP+gvaeTAAADqUlEQVR4nO2dvU8UQRyGH40KjYI22FnYGDpI7kSxM/gRjQmNBUGtLKz8+JNMsLAjojEaYwMROaWy0kRtjFbG00SjhVgMG+C8u5253ZnffbxPMoHA7s7c+8DezOzeDgghhBBCCJGcXQX3HwcmgDFgb/HmdMQf4AWwalR/coaA28A7YKOLykNgJOLr7gqqwEfsw25VluK9dHtmgV/Yh5xXqrECiMFuz+2qwD1gOGJbyuKUdQNC8BEwDNynN8IH91/QM/gIuAEcid2QElmxbkDZdFtvp115ECkDM8axDzUk/J7rhu7J+f2ExzH+4t6gPxVvTkd8wZ12akb1FyJPwGGPYywAV0toy0CS9ya83+MY78toyKDiOw4QkZAAYyTAGAkwRgKMkQBjJMAYCTBGAozJm4oYNKaAk5vfrwAvY1coAY4DuAnFCw0/XwLmgXqsinUKcjQLH+Ai8BQYjVWxBMBxmoefUQGeEEmCBMC0xzbRJEiAP1EkSAAsB2xbugQJgDXCLuaXKkECHFcIu6ZcmgQJcNSBGcIGXhXgGXCoSMUSsEUdOEuYhEncOKFjCRKwk0zCWsA+hSRIwP/UgTMkkiABzUkmQQJak0SCxWzoFHAC2GdQdyc8xwXrm9Uk8Bgn71vexikFjOJmHc8nrNOKbJwwQ85UdspT0KCEn1EB7uZtlErAFIMVfsYlnIiWpBLgM+Xbr7R97eoFGZNKQN99biuAttPdqQSsAo8S1dVNLAKv2m2Q8hQ0h3ucwKBQA67lbZRyHFDH3WVQxb0xjSWsuwgHgeuEPdikhhuI5d7OYjESXiNseG/JCG5AFRL+OnAOj1EwqBfUjiz8kGdPrONGv199d5CA5iQJHySgGcnCBwloJGn4IAHbSR4+SEDGCO5CSkj4NeA0BcIHCchYIGfWsoGsn+/V1WyHBOTfHd1IaeGDBEDYVHmp4YMEhFB6+CAB4Hd3dJTwQQIg/+7oaOGDBGTM01zCIq6fHyV80KckM76zdQF9GvcMumXgdeyKJWAnNRI/e06nIGMkwBgJMEYCjJEAYyTAGAkwRgKMkQBj8gT88DjG0TIaMqjkTUV89jjG3ObXNwXb0il9vY5YLy3g0LfriL3FPlzf0pfriN3CPtiQ0lPriPkwBHzAPljfcidODHHw6Yb+Bi7jVtHrBTasGxCLWeAn9n/hA3cK2k4Ft2aMdcitSt+tI9aMIeAm3dc76sl1xIou6HwM93CKMew+89XT64gJIYQQQghhwD+GY3D/XU+PSgAAAABJRU5ErkJggg=="
/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

8
src/lib/svg/Point.svelte Normal file
View File

@ -0,0 +1,8 @@
<svg width="20" height="26" viewBox="0 0 20 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M0.479126 9.35335C0.479126 4.19335 4.65246 0.0200195 9.8125 0.0200195C14.9725 0.0200195 19.1458 4.19335 19.1458 9.35335C19.1458 14.9133 13.2525 22.58 10.8391 25.5C10.3058 26.14 9.33246 26.14 8.79913 25.5C6.37246 22.58 0.479126 14.9133 0.479126 9.35335ZM6.47913 9.35335C6.47913 11.1933 7.97246 12.6867 9.8125 12.6867C11.6525 12.6867 13.1458 11.1933 13.1458 9.35335C13.1458 7.51335 11.6525 6.02002 9.8125 6.02002C7.97246 6.02002 6.47913 7.51335 6.47913 9.35335Z"
fill="#4263EB"
/>
</svg>

After

Width:  |  Height:  |  Size: 641 B

View File

@ -0,0 +1,19 @@
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M10.7086 7.08398C9.90441 7.08398 9.25024 7.73815 9.25024 8.54315C9.25024 9.34732 9.90441 10.0007 10.7086 10.0007C11.5127 10.0007 12.1669 9.34732 12.1669 8.54315C12.1669 7.73815 11.5127 7.08398 10.7086 7.08398ZM10.7086 11.2507C9.21524 11.2507 8.00024 10.0365 8.00024 8.54315C8.00024 7.04898 9.21524 5.83398 10.7086 5.83398C12.2019 5.83398 13.4169 7.04898 13.4169 8.54315C13.4169 10.0365 12.2019 11.2507 10.7086 11.2507Z"
fill="#61646B"
/>
<mask id="mask0_1624_3626" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="3" y="1" width="15" height="17">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.83325 1.66699H17.5828V17.917H3.83325V1.66699Z" fill="white" />
</mask>
<g mask="url(#mask0_1624_3626)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M10.7078 2.91699C7.6061 2.91699 5.08276 5.46449 5.08276 8.59449C5.08276 12.577 9.76943 16.457 10.7078 16.6637C11.6461 16.4562 16.3328 12.5762 16.3328 8.59449C16.3328 5.46449 13.8094 2.91699 10.7078 2.91699ZM10.7078 17.917C9.21276 17.917 3.83276 13.2903 3.83276 8.59449C3.83276 4.77449 6.91693 1.66699 10.7078 1.66699C14.4986 1.66699 17.5828 4.77449 17.5828 8.59449C17.5828 13.2903 12.2028 17.917 10.7078 17.917Z"
fill="#61646B"
/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,8 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M20 10C20 12.7625 17.7625 15 15 15C12.2375 15 10 12.7625 10 10C10 7.2375 12.2375 5 15 5C17.7625 5 20 7.2375 20 10ZM5 22.5C5 19.175 11.6625 17.5 15 17.5C18.3375 17.5 25 19.175 25 22.5V23.75C25 24.4375 24.4375 25 23.75 25H6.25C5.5625 25 5 24.4375 5 23.75V22.5Z"
fill="#4263EB"
/>
</svg>

After

Width:  |  Height:  |  Size: 440 B

22
src/lib/svg/Search.svelte Normal file
View File

@ -0,0 +1,22 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1648_1316" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="17" height="17">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.166626 0.666504H16.3973V16.8973H0.166626V0.666504Z" fill="white"/>
</mask>
<g mask="url(#mask0_1648_1316)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.28234 1.9165C4.4965 1.9165 1.4165 4.99567 1.4165 8.7815C1.4165 12.5673 4.4965 15.6473 8.28234 15.6473C12.0673 15.6473 15.1473 12.5673 15.1473 8.7815C15.1473 4.99567 12.0673 1.9165 8.28234 1.9165ZM8.28234 16.8973C3.80734 16.8973 0.166504 13.2565 0.166504 8.7815C0.166504 4.3065 3.80734 0.666504 8.28234 0.666504C12.7573 0.666504 16.3973 4.3065 16.3973 8.7815C16.3973 13.2565 12.7573 16.8973 8.28234 16.8973Z" fill="#61646B"/>
</g>
<mask id="mask1_1648_1316" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="12" y="13" width="6" height="5">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.8666 13.7559H17.0533V17.9348H12.8666V13.7559Z" fill="white"/>
</mask>
<g mask="url(#mask1_1648_1316)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.4285 17.9348C16.2693 17.9348 16.1093 17.874 15.9868 17.7523L13.0501 14.824C12.806 14.5798 12.8051 14.184 13.0493 13.9398C13.2926 13.694 13.6885 13.6957 13.9335 13.9382L16.8701 16.8673C17.1143 17.1115 17.1151 17.5065 16.871 17.7507C16.7493 17.874 16.5885 17.9348 16.4285 17.9348Z" fill="#61646B"/>
</g>
</svg>
<style>
svg{
height: 100%;
width: auto;
}
</style>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,20 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 24C0 10.7452 10.7452 0 24 0C37.2548 0 48 10.7452 48 24C48 37.2548 37.2548 48 24 48C10.7452 48 0 37.2548 0 24Z" fill="#F3F4F6" />
<mask id="mask0_1574_3130" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="14" y="14" width="20" height="21">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 14.001H33.2849V34.722H14V14.001Z" fill="white" />
</mask>
<g mask="url(#mask0_1574_3130)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M19.2022 29.441C19.4312 29.441 19.6602 29.47 19.8842 29.53C20.5602 29.712 21.1472 30.164 21.4952 30.771C21.7212 31.152 21.8462 31.597 21.8502 32.051C21.8502 32.701 22.3722 33.222 23.0142 33.222H24.2672C24.9062 33.222 25.4282 32.704 25.4312 32.065C25.4272 31.359 25.7032 30.688 26.2082 30.183C26.7062 29.685 27.4022 29.386 28.0982 29.406C28.5542 29.417 28.9932 29.54 29.3802 29.76C29.9372 30.079 30.6482 29.889 30.9702 29.339L31.6342 28.232C31.7822 27.977 31.8252 27.657 31.7462 27.362C31.6682 27.067 31.4722 26.811 31.2082 26.66C30.5902 26.304 30.1492 25.73 29.9662 25.042C29.7852 24.367 29.8842 23.63 30.2372 23.023C30.4672 22.623 30.8042 22.286 31.2082 22.054C31.7502 21.737 31.9402 21.028 31.6252 20.476C31.6122 20.454 31.6002 20.431 31.5902 20.407L31.0042 19.391C30.6852 18.836 29.9752 18.645 29.4182 18.962C28.8162 19.318 28.1002 19.42 27.4122 19.239C26.7252 19.061 26.1492 18.626 25.7902 18.012C25.5602 17.628 25.4352 17.181 25.4312 16.726C25.4402 16.384 25.3202 16.077 25.1022 15.852C24.8852 15.628 24.5802 15.501 24.2672 15.501H23.0142C22.7042 15.501 22.4142 15.622 22.1952 15.84C21.9772 16.059 21.8582 16.35 21.8602 16.66C21.8392 18.122 20.6442 19.299 19.1972 19.299C18.7332 19.294 18.2862 19.169 17.8982 18.937C17.3532 18.627 16.6412 18.818 16.3222 19.373L15.6452 20.486C15.3352 21.024 15.5252 21.735 16.0772 22.056C16.8962 22.53 17.4072 23.414 17.4072 24.362C17.4072 25.31 16.8962 26.193 16.0752 26.668C15.5262 26.986 15.3362 27.693 15.6542 28.243L16.2852 29.331C16.4412 29.612 16.6962 29.815 16.9912 29.898C17.2852 29.98 17.6092 29.945 17.8792 29.795C18.2762 29.562 18.7382 29.441 19.2022 29.441ZM24.2672 34.722H23.0142C21.5452 34.722 20.3502 33.528 20.3502 32.059C20.3482 31.878 20.2962 31.69 20.1992 31.527C20.0422 31.253 19.7882 31.057 19.4952 30.979C19.2042 30.901 18.8852 30.944 18.6232 31.096C17.9952 31.446 17.2562 31.531 16.5802 31.341C15.9052 31.15 15.3222 30.686 14.9802 30.071L14.3552 28.994C13.6242 27.726 14.0592 26.101 15.3252 25.369C15.6842 25.162 15.9072 24.776 15.9072 24.362C15.9072 23.948 15.6842 23.561 15.3252 23.354C14.0582 22.618 13.6242 20.989 14.3542 19.721L15.0322 18.608C15.7532 17.354 17.3832 16.912 18.6542 17.642C18.8272 17.745 19.0152 17.797 19.2062 17.799C19.8292 17.799 20.3502 17.285 20.3602 16.653C20.3562 15.956 20.6312 15.287 21.1322 14.782C21.6352 14.278 22.3032 14.001 23.0142 14.001H24.2672C24.9832 14.001 25.6792 14.295 26.1782 14.806C26.6762 15.32 26.9512 16.025 26.9302 16.74C26.9322 16.901 26.9852 17.087 27.0812 17.25C27.2402 17.52 27.4912 17.71 27.7892 17.788C28.0872 17.862 28.3992 17.822 28.6642 17.665C29.9442 16.934 31.5732 17.372 32.3042 18.642L32.9272 19.721C32.9432 19.75 32.9572 19.778 32.9692 19.807C33.6312 21.058 33.1892 22.633 31.9592 23.352C31.7802 23.455 31.6352 23.599 31.5352 23.773C31.3802 24.042 31.3372 24.362 31.4152 24.656C31.4952 24.956 31.6862 25.205 31.9552 25.359C32.5622 25.708 33.0152 26.296 33.1962 26.975C33.3772 27.653 33.2782 28.389 32.9252 28.996L32.2612 30.102C31.5302 31.358 29.9012 31.793 28.6342 31.061C28.4652 30.964 28.2702 30.911 28.0762 30.906H28.0702C27.7812 30.906 27.4842 31.029 27.2682 31.244C27.0492 31.463 26.9292 31.755 26.9312 32.065C26.9242 33.534 25.7292 34.722 24.2672 34.722Z"
fill="black"
/>
</g>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M23.6452 22.4746C22.6052 22.4746 21.7592 23.3216 21.7592 24.3616C21.7592 25.4016 22.6052 26.2466 23.6452 26.2466C24.6852 26.2466 25.5312 25.4016 25.5312 24.3616C25.5312 23.3216 24.6852 22.4746 23.6452 22.4746ZM23.6452 27.7466C21.7782 27.7466 20.2592 26.2286 20.2592 24.3616C20.2592 22.4946 21.7782 20.9746 23.6452 20.9746C25.5122 20.9746 27.0312 22.4946 27.0312 24.3616C27.0312 26.2286 25.5122 27.7466 23.6452 27.7466Z"
fill="black"
/>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,8 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M24.3777 15C24.3777 15.425 24.3402 15.825 24.2902 16.225L26.9277 18.2875C27.1652 18.475 27.2277 18.8125 27.0777 19.0875L24.5777 23.4125C24.4277 23.6875 24.1027 23.8 23.8152 23.6875L20.7027 22.4375C20.0527 22.925 19.3527 23.35 18.5902 23.6625L18.1152 26.975C18.0777 27.275 17.8152 27.5 17.5027 27.5H12.5027C12.1902 27.5 11.9277 27.275 11.8902 26.975L11.4152 23.6625C10.6527 23.35 9.95273 22.9375 9.30273 22.4375L6.19023 23.6875C5.91523 23.7875 5.57773 23.6875 5.42773 23.4125L2.92773 19.0875C2.77773 18.8125 2.84023 18.475 3.07773 18.2875L5.71523 16.225C5.66523 15.825 5.62773 15.4125 5.62773 15C5.62773 14.5875 5.66523 14.175 5.71523 13.775L3.07773 11.7125C2.84023 11.525 2.76523 11.1875 2.92773 10.9125L5.42773 6.5875C5.57773 6.3125 5.90273 6.2 6.19023 6.3125L9.30273 7.5625C9.95273 7.075 10.6527 6.65 11.4152 6.3375L11.8902 3.025C11.9277 2.725 12.1902 2.5 12.5027 2.5H17.5027C17.8152 2.5 18.0777 2.725 18.1152 3.025L18.5902 6.3375C19.3527 6.65 20.0527 7.0625 20.7027 7.5625L23.8152 6.3125C24.0902 6.2125 24.4277 6.3125 24.5777 6.5875L27.0777 10.9125C27.2277 11.1875 27.1652 11.525 26.9277 11.7125L24.2902 13.775C24.3402 14.175 24.3777 14.575 24.3777 15ZM10.6277 15C10.6277 17.4125 12.5902 19.375 15.0027 19.375C17.4152 19.375 19.3777 17.4125 19.3777 15C19.3777 12.5875 17.4152 10.625 15.0027 10.625C12.5902 10.625 10.6277 12.5875 10.6277 15Z"
fill="#4263EB"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

26
src/lib/svg/Share.svelte Normal file
View File

@ -0,0 +1,26 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g filter="url(#filter0_i_956_444)">
<rect width="42" height="42" fill="url(#share_svelteSvgPictureid)" />
</g>
<defs>
<filter id="filter0_i_956_444" x="0" y="0" width="42" height="42" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha" />
<feOffset dx="436" dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
<feColorMatrix type="matrix" values="0 0 0 0 0.258824 0 0 0 0 0.388235 0 0 0 0 0.921569 0 0 0 1 0" />
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_956_444" />
</filter>
<pattern id="share_svelteSvgPictureid" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_956_444" transform="scale(0.00520833)" />
</pattern>
<image
id="image0_956_444"
width="192"
height="192"
xlink:href="data:image/png;base64,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"
/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

6
src/lib/svg/Star.svelte Normal file
View File

@ -0,0 +1,6 @@
<svg width="27" height="26" viewBox="0 0 27 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M13.5 21.2792L19.725 25.0442C20.865 25.7342 22.26 24.7142 21.96 23.4242L20.31 16.3442L25.815 11.5742C26.82 10.7042 26.28 9.05416 24.96 8.94916L17.715 8.33416L14.88 1.64416C14.37 0.42916 12.63 0.42916 12.12 1.64416L9.28499 8.31916L2.03999 8.93416C0.719987 9.03916 0.179987 10.6892 1.18499 11.5592L6.68999 16.3292L5.03999 23.4092C4.73999 24.6992 6.13499 25.7192 7.27499 25.0292L13.5 21.2792Z"
fill="#FFBF00"
/>
</svg>

After

Width:  |  Height:  |  Size: 527 B

20
src/lib/svg/Times.svelte Normal file
View File

@ -0,0 +1,20 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M9.60253 15.1365C9.41053 15.1365 9.21853 15.0635 9.07253 14.9165C8.77953 14.6235 8.77953 14.1495 9.07253 13.8565L13.8645 9.06448C14.1575 8.77148 14.6315 8.77148 14.9245 9.06448C15.2175 9.35748 15.2175 9.83148 14.9245 10.1245L10.1325 14.9165C9.98653 15.0635 9.79453 15.1365 9.60253 15.1365Z"
fill="#212529"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M14.3966 15.1395C14.2046 15.1395 14.0126 15.0665 13.8666 14.9195L9.07058 10.1225C8.77758 9.82952 8.77758 9.35552 9.07058 9.06252C9.36458 8.76952 9.83858 8.76952 10.1306 9.06252L14.9266 13.8595C15.2196 14.1525 15.2196 14.6265 14.9266 14.9195C14.7806 15.0665 14.5876 15.1395 14.3966 15.1395Z"
fill="#212529"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.665 3.5C5.135 3.5 3.5 5.233 3.5 7.916V16.084C3.5 18.767 5.135 20.5 7.665 20.5H16.333C18.864 20.5 20.5 18.767 20.5 16.084V7.916C20.5 5.233 18.864 3.5 16.334 3.5H7.665ZM16.333 22H7.665C4.276 22 2 19.622 2 16.084V7.916C2 4.378 4.276 2 7.665 2H16.334C19.723 2 22 4.378 22 7.916V16.084C22 19.622 19.723 22 16.333 22V22Z"
fill="#212529"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 107 KiB

View File

@ -0,0 +1,8 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M25 5H5C3.6125 5 2.5125 6.1125 2.5125 7.5L2.5 22.5C2.5 23.8875 3.6125 25 5 25H25C26.3875 25 27.5 23.8875 27.5 22.5V7.5C27.5 6.1125 26.3875 5 25 5ZM23.75 22.5H6.25C5.5625 22.5 5 21.9375 5 21.25V15H25V21.25C25 21.9375 24.4375 22.5 23.75 22.5ZM5 10H25V8.75C25 8.0625 24.4375 7.5 23.75 7.5H6.25C5.5625 7.5 5 8.0625 5 8.75V10Z"
fill="#4263EB"
/>
</svg>

After

Width:  |  Height:  |  Size: 503 B

View File

@ -0,0 +1,8 @@
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.58741 25.6295H24.4124C26.3374 25.6295 27.5374 23.542 26.5749 21.8795L17.1624 5.61699C16.1999 3.95449 13.7999 3.95449 12.8374 5.61699L3.42491 21.8795C2.46241 23.542 3.66241 25.6295 5.58741 25.6295ZM14.9999 16.8795C14.3124 16.8795 13.7499 16.317 13.7499 15.6295V13.1295C13.7499 12.442 14.3124 11.8795 14.9999 11.8795C15.6874 11.8795 16.2499 12.442 16.2499 13.1295V15.6295C16.2499 16.317 15.6874 16.8795 14.9999 16.8795ZM13.7499 21.8795H16.2499V19.3795H13.7499V21.8795Z"
fill="#4263EB"
/>
</svg>

After

Width:  |  Height:  |  Size: 651 B

View File

@ -0,0 +1,3 @@
export const idGenerator = () => {
return JSON.stringify(Date.now() * Math.floor(Math.random() * 100000))
}

55
src/lib/utils/api.js Normal file
View File

@ -0,0 +1,55 @@
async function send({ method, path, body, token, headers }) {
const opts = { method, headers: new Headers(), mode: 'cors' }
opts.headers.append('Content-Type', 'application/json')
opts.headers.append('Access-Control-Allow-Origin', '*')
if (body) {
opts.body = JSON.stringify(body)
}
if (headers) {
for (const [k, v] of Object.entries(headers)) {
opts.headers.append(k, v)
}
}
if (token) {
opts.headers['Authorization'] = `Bearer ${token}`
}
const res = fetch(path, opts)
.then(async (r) => {
if (r.status >= 200 && r.status < 400) {
return await r.text()
} else {
return await r.text()
}
})
.then((str) => {
try {
return JSON.parse(str)
} catch (err) {
return str
}
})
return res
}
export function get(path, token = null) {
return send({ method: 'GET', path, body: null, token })
}
export function del(path, token = null) {
return send({ method: 'DELETE', path, body: null, token })
}
export function post(path, body, token = null) {
return send({ method: 'POST', path, body, token })
}
export function put(path, body, token = null, headers = []) {
return send({ method: 'PUT', path, body, token, headers })
}
export const hostName = 'https://erant.cz/api'

View File

@ -0,0 +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
}
}

83
src/lib/utils/stores.js Normal file
View File

@ -0,0 +1,83 @@
import { writable } from 'svelte/store'
import * as api from './api'
class FetchArray extends Array {
constructor(items, caller = () => null) {
super()
this.push(...items)
this.caller = caller
}
setFetch(caller) {
this.caller = caller
return this
}
fetch(fetchBody = {}, then = () => null) {
return this.caller(fetchBody, then)
}
}
export function fetchable(path, initBody = {}) {
const { subscribe, set } = writable(null)
return {
subscribe,
fetch(fetchBody = {}, then = () => null) {
const body = Object.assign(initBody, fetchBody)
api.post(path, body).then((result) => {
set(result)
then(result)
})
return this
}
}
}
export function loadable(path, initBody = {}) {
const fetcher = fetchable(path, initBody)
const fetchCaller = fetcher.fetch
const isFetching = writable(false)
fetcher.fetch = (fetchBody = {}, then = () => null) => {
isFetching.set(true)
fetchCaller(fetchBody, (result) => {
isFetching.set(false)
then(result)
})
return new FetchArray([fetcher, isFetching], fetcher.fetch)
}
return new FetchArray([fetcher, isFetching], fetcher.fetch)
}
export function mutable(path, callback = () => null) {
const isFetching = writable(false)
const { subscribe, set } = writable(null)
const mutateCall = async (fetchBody = {}) => {
isFetching.set(true)
const result = await api.post(path, fetchBody)
set(result)
isFetching.set(false)
return result
}
return [
{
subscribe,
mutate(fetchBody = {}) {
callback(mutateCall, fetchBody)
return this
}
},
isFetching
]
}

View File

View File

@ -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

View File

@ -1,16 +1,42 @@
*,
*::before,
*::after {
*:before,
*:after {
box-sizing: border-box;
}
@import url("normalize.scss");
@import url("fonts.scss");
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@600&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Work+Sans:wght@500&display=swap');
html,
body {
height: 100%;
width: 100%;
tab-size: 4;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
height: 100%;
padding: 0;
margin: 0;
font-family: 'Source Sans Pro', sans-serif;
}
#app {
width: 100%;
height: 100%;
justify-content: center;
display: flex;
}
.mapboxgl-ctrl-logo,
.mapboxgl-ctrl-bottom-right {
display: none !important;
}
:root {
--quizHeader: 300px;
--fontSize: 40px;
--blue: #96ddff;
--border-radius: 25px;
--grey: rgba(0, 0, 0, 0.4);
--max-viewport-width: 500px;
}

379
src/normalize.scss vendored Normal file
View File

@ -0,0 +1,379 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15;
/* 1 */
-webkit-text-size-adjust: 100%;
/* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box;
/* 1 */
height: 0;
/* 1 */
overflow: visible;
/* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace;
/* 1 */
font-size: 1em;
/* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none;
/* 1 */
text-decoration: underline;
/* 2 */
text-decoration: underline dotted;
/* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace;
/* 1 */
font-size: 1em;
/* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit;
/* 1 */
font-size: 100%;
/* 1 */
line-height: 1.15;
/* 1 */
margin: 0;
/* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input {
/* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select {
/* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box;
/* 1 */
color: inherit;
/* 2 */
display: table;
/* 1 */
max-width: 100%;
/* 1 */
padding: 0;
/* 3 */
white-space: normal;
/* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box;
/* 1 */
padding: 0;
/* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield;
/* 1 */
outline-offset: -2px;
/* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button;
/* 1 */
font: inherit;
/* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

17
src/routes/error.svelte Normal file
View File

@ -0,0 +1,17 @@
<script>
import Overlay from '../lib/Components/Layouts/LayoutImg.svelte'
import Section from '../lib/Components/common/Section.svelte'
import Button from '../lib/Components/Buttons/Button.svelte'
</script>
<Overlay img="/assets/images/main.jpg">
<div>
<span>Erant</span>
</div>
<Section title="Nastala chyba">
<p>Je nám líto ale tento zážitek nebyl nalezen.</p>
</Section>
<Button href="/" primary>Hlavní menu</Button>
</Overlay>

View File

@ -0,0 +1,32 @@
<script lang="ts">
export let name:string
</script>
<button class="filter">
{name}
</button>
<style lang="scss">
.filter{
display: block;
min-width: fit-content;
height: 36px;
/* surface */
background: #FAFAFA;
/* normal */
border: 2px solid #19191B;
border-radius: 20px;
padding: 8px 16px;
font-style: normal;
font-weight: 400;
font-size: 14px;
&:hover{
opacity: 50%;
}
}
</style>

View File

@ -0,0 +1,163 @@
<script>
export let price = "$0.00"
export let location = "Home"
export let name = "Kawa Ijen"
export let image = ""
</script>
<button>
<div class="image">
{#if image !== ""}
<img style="flex-grow: 1;" src={image}>
{/if}
<div class="bookmark">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1402_894" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="1" width="12" height="15">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 1.33301H13.3592V15.2308H2V1.33301Z" fill="white"/>
</mask>
<g mask="url(#mask0_1402_894)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.56133 2.33301C3.862 2.33301 3 2.98767 3 4.28034V14.0963C3 14.159 3.036 14.193 3.066 14.2103C3.096 14.229 3.14333 14.2423 3.198 14.2117L7.45267 11.825C7.60467 11.7403 7.79067 11.7397 7.94333 11.8257L12.1613 14.2083C12.2167 14.2403 12.264 14.2257 12.294 14.2077C12.324 14.1897 12.3593 14.1557 12.3593 14.093V4.40234C12.3593 3.89101 12.3593 2.33301 9.80067 2.33301H5.56133ZM3.13267 15.231C2.936 15.231 2.73933 15.1783 2.56067 15.073C2.20933 14.8683 2 14.5023 2 14.0963V4.28034C2 2.40701 3.298 1.33301 5.56133 1.33301H9.80067C12.062 1.33301 13.3593 2.45234 13.3593 4.40234V14.093C13.3593 14.4997 13.15 14.8657 12.798 15.0703C12.4473 15.2757 12.0247 15.2797 11.67 15.0797L7.69667 12.835L3.68667 15.0843C3.51333 15.1817 3.32333 15.231 3.13267 15.231Z" fill="white"/>
</g>
</svg>
</div>
</div>
<div class="info">
<h3>{name}</h3>
<div>
<svg width="12" height="14" viewBox="0 0 12 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.16667 4.66602C5.52333 4.66602 5 5.18935 5 5.83335C5 6.47668 5.52333 6.99935 6.16667 6.99935C6.81 6.99935 7.33333 6.47668 7.33333 5.83335C7.33333 5.18935 6.81 4.66602 6.16667 4.66602ZM6.16667 7.99935C4.972 7.99935 4 7.02802 4 5.83335C4 4.63802 4.972 3.66602 6.16667 3.66602C7.36133 3.66602 8.33333 4.63802 8.33333 5.83335C8.33333 7.02802 7.36133 7.99935 6.16667 7.99935Z" fill="#61646B"/>
<mask id="mask0_1402_1007" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="12" height="14">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.666504 0.333008H11.6662V13.333H0.666504V0.333008Z" fill="white"/>
</mask>
<g mask="url(#mask0_1402_1007)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.16602 1.33301C3.68468 1.33301 1.66602 3.37101 1.66602 5.87501C1.66602 9.06101 5.41535 12.165 6.16602 12.3303C6.91668 12.1643 10.666 9.06034 10.666 5.87501C10.666 3.37101 8.64735 1.33301 6.16602 1.33301V1.33301ZM6.16602 13.333C4.97002 13.333 0.666016 9.63167 0.666016 5.87501C0.666016 2.81901 3.13335 0.333008 6.16602 0.333008C9.19868 0.333008 11.666 2.81901 11.666 5.87501C11.666 9.63167 7.36202 13.333 6.16602 13.333V13.333Z" fill="#61646B"/>
</g>
</svg>
{location}
</div>
</div>
</button>
<style>
button{
width: 100%;
padding: 8px 8px 12px 8px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
justify-content: space-between;
position: relative;
border: 1px solid #EFEFF0;
border-radius: 20px;
}
button:hover, button:active{
opacity: 70%;
cursor: pointer;
}
button > .image{
width: 100%;
height: 250px;
/* background */
background-color: #EFEFF0;
/* subtle-light */
border: 2px solid #AFB1B6;
border-radius: 20px;
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_1402_2000' 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_1402_2000)'%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='%2361646B'/%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='%2361646B'/%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='%2361646B'/%3E%3C/svg%3E%0A");
background-repeat: no-repeat;
background-position: center;
position: relative;
display: flex;
flex-direction: row;
justify-content: stretch;
align-items: stretch;
overflow: hidden;
}
@media screen and (max-width: 400px){
button > .image{
height: 50vw;
}
}
button > .image > .bookmark{
position: absolute;
width: 28px;
height: 28px;
right: 12px;
top: 12px;
background: #4263EB;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
}
button > .image > .price{
position: absolute;
padding: 4px 8px 4px 8px;
height: 28px;
left: 12px;
bottom: 12px;
background: #4263EB;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-family: 'Work Sans';
font-style: normal;
font-weight: 500;
font-size: 14px;
line-height: 20px;
}
button > .info{
text-align: left;
width: 100%;
display: flex;
flex-direction: column;
gap: 8px;
}
button > .info > h3{
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 24px;
color: #19191B;
}
button > .info > div{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 8px;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 14px;
line-height: 20px;
color: #61646B;
}
</style>

View File

@ -0,0 +1,74 @@
<script lang="ts">
import Search from "../../../lib/svg/Search.svelte"
export let search_value
</script>
<div class="search">
<div class="search_content">
<Search />
<input type="text" name="search_input" id="search_input" placeholder="Where do you want to go?" bind:value={search_value}/>
</div>
<label for="search_input" class="label_input">
</label>
</div>
<style lang="scss">
.search{
flex-grow: 1;
height: 44px;
background: #EFEFF0;
border-radius: 20px;
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
.search_content{
max-width: 100%;
padding: 10px;
height: 100%;
position: relative;
display: flex;
flex-direction: row;
gap: 7px;
align-items: center;
justify-content: stretch;
input[type="text"]{
font-style: normal;
font-weight: 400;
font-size: 16px;
height: 100%;
width: 176px;
background: none;
flex-grow: 0;
transition: flex-grow 2s;
transition-delay: 2000ms;
&::placeholder{
color: #AFB1B6;
}
&:focus, &:focus-visible {
flex-grow: 1;
border: none;
outline: none;
}
}
}
.search_content:has(input[type="text"]:focus){
width: 100%;
}
.label_input{
position: absolute;
width: 100%;
height: 100%;
}
}
</style>

View File

@ -0,0 +1,88 @@
<script>
import Filter from "./Filter.svelte"
import Search from "./Search.svelte";
export let search_value
</script>
<div class="top">
<div class="actions">
<Search bind:search_value={search_value}/>
<button class="options">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.40006 15.4941H3.14923C2.80423 15.4941 2.52423 15.2141 2.52423 14.8691C2.52423 14.5241 2.80423 14.2441 3.14923 14.2441H8.40006C8.74506 14.2441 9.02506 14.5241 9.02506 14.8691C9.02506 15.2141 8.74506 15.4941 8.40006 15.4941Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.9924 7.41699H10.7424C10.3974 7.41699 10.1174 7.13699 10.1174 6.79199C10.1174 6.44699 10.3974 6.16699 10.7424 6.16699H15.9924C16.3374 6.16699 16.6174 6.44699 16.6174 6.79199C16.6174 7.13699 16.3374 7.41699 15.9924 7.41699Z" fill="black"/>
<mask id="mask0_1630_1934" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="4" width="6" height="6">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 4.16699H7.68817V9.32666H2.5V4.16699Z" fill="white"/>
</mask>
<g mask="url(#mask0_1630_1934)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.09398 5.4165C4.35315 5.4165 3.74982 6.01317 3.74982 6.74734C3.74982 7.48067 4.35315 8.0765 5.09398 8.0765C5.83565 8.0765 6.43815 7.48067 6.43815 6.74734C6.43815 6.01317 5.83565 5.4165 5.09398 5.4165ZM5.09398 9.3265C3.66398 9.3265 2.49982 8.16984 2.49982 6.74734C2.49982 5.32484 3.66398 4.1665 5.09398 4.1665C6.52482 4.1665 7.68815 5.32484 7.68815 6.74734C7.68815 8.16984 6.52482 9.3265 5.09398 9.3265Z" fill="black"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4898 13.5068C13.7481 13.5068 13.1448 14.1035 13.1448 14.8368C13.1448 15.571 13.7481 16.1668 14.4898 16.1668C15.2306 16.1668 15.8331 15.571 15.8331 14.8368C15.8331 14.1035 15.2306 13.5068 14.4898 13.5068ZM14.4898 17.4168C13.0589 17.4168 11.8948 16.2593 11.8948 14.8368C11.8948 13.4143 13.0589 12.2568 14.4898 12.2568C15.9198 12.2568 17.0831 13.4143 17.0831 14.8368C17.0831 16.2593 15.9198 17.4168 14.4898 17.4168Z" fill="black"/>
</svg>
</button>
</div>
<div class="filters">
<Filter name="Some filter" />
<Filter name="Some filter n.2" />
</div>
</div>
<style lang="scss">
.top{
width: 100%;
position: relative;
padding: 44px 16px 20px 16px;
display: flex;
flex-direction: column;
gap: 20px;
border-bottom: 1px solid #EFEFF0;
.actions{
display: flex;
flex-direction: row;
align-items: center;
justify-content: stretch;
gap:16px;
.options{
width: 44px;
height: 44px;
background: #EFEFF0;
border-radius: 228px;
display: flex;
align-items: center;
justify-content: center;
}
.options:hover{
opacity: 50%;
}
}
.filters{
display: flex;
flex-direction: row;
gap:12px;
max-width: 100%;
position: relative;
overflow: scroll;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
}
</style>

View File

@ -0,0 +1,50 @@
<script lang="ts">
import NavigationBarLayout from './../../lib/Components/Layouts/NavigationBarLayout.svelte'
import Result from './Components/Result.svelte'
import Top from './Components/Top.svelte'
let Search: string
function search(value: string) {
return [value, value, value]
}
</script>
<NavigationBarLayout>
<div class="content">
<Top bind:search_value={Search} />
<div class="results">
{#each search(Search) as result}
<Result name={result} />
{/each}
<div class="end" />
</div>
</div>
</NavigationBarLayout>
<style lang="scss">
.content {
width: 100%;
max-height: 100vh;
overflow-y: scroll;
.results {
width: 100%;
height: 60vh;
position: relative;
padding: 16px 16px 0px 16px;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
.end {
width: 20px;
min-height: 10vh;
}
}
}
</style>

View File

@ -0,0 +1,69 @@
<script>
import Section from '../../../lib/Components/common/Section.svelte'
import Button from '../../../lib/Components/Buttons/Button.svelte'
import Image from '../../../lib/Components/common/Image.svelte'
export let control, nextQuestion
export let imgSrc
</script>
<div>
<div class="wrap">
<div class="h-[var(--quizHeader)] w-full flex relative top-0 justify-center items-center">
<div class="flex justify-center items-center flex-col flex-wrap gap-3">
<span class="title"><slot name="title" /></span>
<span style="width: 100%"><Image class="w-full h-[200px]" src={imgSrc} /></span>
</div>
</div>
<Section style="height: calc(100% - var(--quizHeader)); position: relative">
<div class="flex items-center justify-center flex-col w-full gap-24 p-4">
<div class="popis">
<span> Popis úkolu: </span>
<span> <slot name="about" /></span>
</div>
<div class="flex items-center justify-center flex-col w-full gap-6">
<span class="relative"> <slot name="answers" /> </span>
{#if control !== null}<!--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}
</div>
</div>
<div class="w-full relative bottom-[170px] flex justify-center h-fit size">
{#if control}
<span style="color:greenyellow">správně</span>
{:else if control !== null}
<span style="color:red">špatně</span>
{/if}
</div>
</Section>
</div>
</div>
<style lang="scss">
.wrap {
height: 100%;
width: 100%;
display: flex;
flex-wrap: wrap;
flex-direction: column;
.title {
font-size: var(--fontSize);
font-weight: 600;
}
.popis {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
font-size: 24px;
font-weight: 700;
text-align: center;
gap: 8px;
color: var(--grey);
}
}
</style>

View File

@ -0,0 +1,12 @@
<script>
import LayoutImg from './../../../lib/Components/Layouts/LayoutImg.svelte'
import Button from '../../../lib/Components/Buttons/Button.svelte'
export let img
</script>
<LayoutImg {img}>
<div class="w-full h-full flex flex-wrap flex-row gap-4 justify-center">
<div class="h-full w-full flex justify-self-center justify-center text-[32px]"><slot /></div>
<Button class="w-80 absolute bottom-0 mb-6" href="/">ukončit hru</Button>
</div>
</LayoutImg>

View File

@ -0,0 +1,33 @@
<script>
import Layout from '../Components/Layout.svelte'
import Input from '../../../lib/Components/Inputs/Input.svelte'
let title = 'title' //exportovat ze zhora
export let params // { type: 'interval', correct: [0, 3], quesion: 'text otazky', description: '', options: null },
let myAnswer = ''
export let control = null
export let nextQuestion
export let gameData
function between(number, min, max) {
return number >= min && number <= max
}
</script>
<Layout
imgSrc={gameData.question.thumbnail}
{control}
nextQuestion={() => {
nextQuestion()
myAnswer = ''
}}
on:submit={() => (control = myAnswer !== '' ? between(myAnswer, params.correct[0], params.correct[1]) : null)}
>
<span slot="title">{title}</span>
<span slot="about">{params.quesion}</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" />
</span>
</div>
</Layout>

View File

@ -0,0 +1,46 @@
<script>
import Layout from '../Components/Layout.svelte'
import CheckBox from '../../../lib/Components/Inputs/Checkbox.svelte'
import parseQuestion from '$lib/utils/parseQuestion'
export let gameData
let answers = parseQuestion(gameData.question.answer, gameData.question.type)
let myAnswers = new Array(answers.length).fill(false)
export let control = null
export let nextQuestion
const controlMultiForm = () => {
for (let i = 0; i < myAnswers.length; i++) {
const answer = myAnswers[i]
const option = answers[i].label
const rightValue = answers[i].value
if (rightValue !== answer) {
control = false
return ''
}
}
if (control === null) control = true
}
</script>
<Layout
imgSrc={gameData.question.thumbnail}
nextQuestion={() => {
nextQuestion()
myAnswers = new Array(answers.length).fill(false)
}}
{control}
on:submit={controlMultiForm}
>
<span slot="title">{gameData.name}</span>
<span slot="about">{@html gameData.question.question}</span>
<div slot="answers">
{#each answers as { label }, i}
<span class="self-baseline">
<CheckBox bind:checked={myAnswers[i]}>{label}</CheckBox>
</span>
{/each}
</div>
</Layout>

View File

@ -0,0 +1,36 @@
<script>
import Layout from '../Components/Layout.svelte'
import Input from '../../../lib/Components/Inputs/Input.svelte'
import parseQuestion from '$lib/utils/parseQuestion'
export let gameData
let answer = parseQuestion(gameData.question.answer, gameData.question.type)
let myAnswer = ''
export let nextQuestion
export let control = null
</script>
<Layout
imgSrc={gameData.question.thumbnail}
nextQuestion={() => {
nextQuestion()
myAnswer = ''
}}
{control}
on:submit={() => (control = myAnswer !== '' ? myAnswer == answer : null)}
>
<span slot="title">{gameData.name}</span>
<span slot="about">{@html gameData.question.question}</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" />
</span>
</div>
</Layout>
<style lang="scss">
/*.input::-webkit-inner-spin-button {
background: blue;
}*/
</style>

View File

View File

@ -0,0 +1,108 @@
<script>
import parseQuestion from '../../../lib/utils/parseQuestion'
import Marker from '../../../lib/Components/Map/Marker.svelte'
import TextForm from './TextForm.svelte'
import NumberForm from './NumberForm.svelte'
import SingleForm from './SingleChoiceForm.svelte'
import MultiplyForm from './MultiChoiceForm.svelte'
import IntervalForm from './IntervalForm.svelte'
import QrCode from './QrCode.svelte'
import Finish from './Finish.svelte'
import { data } from '$lib/stores/game'
import Erantmap from '$src/lib/Components/Map/Erantmap.svelte'
const components = {
TEXT: TextForm,
NUMBER: NumberForm,
SINGLECHOICE: SingleForm,
MULTICHOICE: MultiplyForm,
interval: IntervalForm,
qrcode: QrCode,
}
let startQuestion = false
let control = null // if true => spravne if false spatne
export let gameData = {} //data
let clientAnswers = {
//user data about game
pos: 0,
end: gameData.questions.length, //kolik otázek
points: 0, //body
}
$: if (control === true) clientAnswers.points += 2 //body bodování
const nextQuestion = () => {
//další otázka
if (control !== null) {
control = null
clientAnswers.pos++
startQuestion = false
}
}
let answers
$: if (clientAnswers.pos < clientAnswers.end) answers = parseQuestion(gameData.questions[clientAnswers.pos].answer, gameData.questions[clientAnswers.pos].type) //delete
let page
$: if (clientAnswers.pos < clientAnswers.end) page = components[gameData.questions[clientAnswers.pos].type]
/*jen pro tedkon, pozdeji vymazat az bude singlechoise a multichoise oddelene*/
$: if (clientAnswers.pos < clientAnswers.end) page = gameData.questions[clientAnswers.pos].type === 'CHOICE' ? components[vals()] : page
const vals = () => {
let con = false
let result
answers.forEach((q) => {
if (q.value && con) {
result = 'MULTICHOICE'
return ''
}
if (q.value && !con) con = true
})
if (result === undefined) result = 'SINGLECHOICE'
return result
}
/*--------------- -----------------------------------------------------------*/
let lat
let lng
$: if (clientAnswers.pos < clientAnswers.end) lat = Number.parseFloat($data.questions[clientAnswers.pos].lat)
$: if (clientAnswers.pos < clientAnswers.end) lng = Number.parseFloat($data.questions[clientAnswers.pos].lng)
let user = { lat: null, lng: null }
//set user to localstorage
$: if (clientAnswers.pos !== clientAnswers.end && clientAnswers.pos !== 0) {
//nastaví
localStorage.setItem(`/${gameData.url}`, JSON.stringify(clientAnswers.pos))
localStorage.setItem('lastGame', `/${gameData.url}`)
} else {
//vymaže když jsi dohrál
localStorage.removeItem(`/${gameData.url}`)
localStorage.removeItem('lastGame')
}
//is user already in game
const userInGame = JSON.parse(localStorage.getItem(location.pathname))
if (userInGame) {
clientAnswers.pos = userInGame
}
</script>
{#if page && startQuestion}
<Erantmap center={{ lat, lng }} bind:user class="w-full h-full">
<Marker on:enter={() => (startQuestion = true)} {lat} {lng} {user} />
</Erantmap>
{/if}
{#if !startQuestion}
{#if clientAnswers.pos !== clientAnswers.end}
<svelte:component this={page} gameData={{ question: gameData.questions[clientAnswers.pos], name: gameData.name }} {nextQuestion} bind:control />
{:else}
<Finish img={gameData.thumbnail}>
<span> Získali jste {clientAnswers.points} / {clientAnswers.end * 2} bodů</span>
</Finish>
{/if}
{/if}

View File

@ -0,0 +1,41 @@
<script>
import Radio from '../../../lib/Components/Inputs/Radio.svelte'
import Layout from '../Components/Layout.svelte'
import parseQuestion from '$lib/utils/parseQuestion'
export let gameData
let answers = parseQuestion(gameData.question.answer, gameData.question.type)
let myAnswer = ''
export let control = null
export let nextQuestion
const rightAnswer = () => {
return answers.filter((item) => {
if (item.value) return item.label
})[0].label
}
</script>
<Layout
imgSrc={gameData.question.thumbnail}
{control}
nextQuestion={() => {
nextQuestion()
myAnswer = ''
}}
on:submit={() => (control = typeof myAnswer === 'string' && myAnswer !== '' ? myAnswer === rightAnswer() : null)}
>
<span slot="title">{gameData.name}</span>
<span slot="about">{@html gameData.question.question}</span>
<div slot="answers">
{#each answers as { label }}
<span class="self-baseline">
<Radio value={label} bind:group={myAnswer}>{label}</Radio>
</span>
{/each}
</div>
</Layout>
<style lang="scss">
</style>

View File

@ -0,0 +1,37 @@
<script>
import Layout from '../Components/Layout.svelte'
import Input from '../../../lib/Components/Inputs/Input.svelte'
import parseQuestion from '$lib/utils/parseQuestion'
export let gameData
let answer = parseQuestion(gameData.question.answer, gameData.question.type)
let myAnswer = ''
export let control = null
export let nextQuestion
const compare = (a, b) => {
if (a.localeCompare(b, 'cz', { sensitivity: 'variant' }) === 0) return true
else return false
}
</script>
<Layout
imgSrc={gameData.question.thumbnail}
{control}
nextQuestion={() => {
nextQuestion()
myAnswer = ''
}}
on:submit={() => (control = myAnswer !== '' ? compare(myAnswer, answer) : null)}
>
<span slot="title">{gameData.name}</span>
<span slot="about">{@html gameData.question.question}</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" />
</span>
</div>
</Layout>
<style lang="scss">
</style>

107
src/routes/game/game.svelte Normal file
View File

@ -0,0 +1,107 @@
<script>
import Overlay from '../../lib/Components/Layouts/LayoutImg.svelte'
import Section from '../../lib/Components/common/Section.svelte'
import Button from '../../lib/Components/Buttons/Button.svelte'
import Bubble from '../../lib/Components/common/Bubble.svelte'
import IconStar from '../../lib/svg/Star.svelte'
import IconPoint from '../../lib/svg/Point.svelte'
import Loading from '../../lib/Components/common/Loading.svelte'
import { loadable } from '../../lib/utils/stores'
import * as api from '../../lib/utils/api'
import { data } from '../../lib/stores/game'
import GeolocateControl from '@beyonk/svelte-mapbox/src/lib/map/controls/GeolocateControl.svelte'
import Map from '../../lib/Components/Map/Map.svelte'
import Renderer from './Forms/Renderer.svelte'
import Redirect from '../../lib/Components/common/Redirect.svelte'
import ImageSlider from '../../lib/Components/common/ImageSlider.svelte'
import Marker from '../../lib/Components/Map/Marker.svelte'
export let gameurl
const [gameData, loading] = loadable(`${api.hostName}/game/details`).fetch({ gameurl })
$: $data = $gameData?.success === true ? $gameData.data : null
$: assets = $gameData?.data?.questions
?.filter((q) => q.thumbnail !== null)
?.slice(0, 8)
?.map((q) => q.thumbnail)
let view = 'game-loading'
//is user already in game
const userInGame = JSON.parse(localStorage.getItem(location.pathname))
$: if ($gameData && userInGame) view = 'game-play'
</script>
{#if view === 'game-loading'}
{#if $loading}
<h1 class="flex items-center justify-center flex-col">
<span>Hra se načítá...</span>
<Loading />
</h1>
{:else if $gameData?.success === true}
<Overlay shareData={{ url: window.location.href }} img={$gameData.data.thumbnail}>
<div>
<span class="text-[36px]">{$gameData.data.name}</span>
<div class="bubbles">
<Bubble background="blue">
<span slot="icon"><IconStar /></span>
<span> {'5.0'} </span>
</Bubble>
<Bubble background="white">
<span slot="icon"><IconPoint /></span>
<span>{$gameData.data.district}</span>
</Bubble>
</div>
</div>
<Section title="Popis">
<span>
{@html $gameData.data.start}
</span>
</Section>
<Section title="Fotky">
<div class="w-full relative">
<div class="px-4 m-auto" style="max-width: var(--max-viewport-width);">
<ImageSlider images={assets} />
</div>
</div>
</Section>
<div class="w-full relative">
<div class="px-4 m-auto" style="max-width: var(--max-viewport-width);">
<Map radius class="w-full h-44" center={{ lng: $gameData.data.lng, lat: $gameData.data.lat }}>
{#each $gameData.data.questions as { lat, lng }}
<Marker {lat} {lng} />
{/each}
<GeolocateControl
on:geolocate={(e) => {
const { latitude, longitude } = e.detail.coords
const user = { lat: latitude, lng: longitude }
console.log(user)
}}
/>
</Map>
</div>
</div>
<Button on:click={() => (view = 'game-play')} primary>Hrát</Button>
</Overlay>
{:else}
<Redirect replace to="/error" />
{/if}
{:else if view === 'game-play'}
<Renderer gameData={$data} />
{/if}
<style>
.bubbles {
display: flex;
height: fit-content;
width: 100%;
align-items: center;
justify-content: flex-start;
gap: 15px;
}
</style>

View File

@ -0,0 +1,45 @@
<script>
import Category from './Category.svelte'
import Headline from './Headline.svelte'
</script>
<div class="categories">
<Headline content="Feeling Adventurous?" />
<div class="options">
<Category text="Beach" imgLink="" />
</div>
</div>
<style lang="scss">
.categories {
width: calc(100% - 24px);
margin: 0 0 20px auto;
display: flex;
flex-direction: column;
align-items: flex-start;
position: relative;
@media screen and (max-width: 370px) {
width: calc(100% - 12px);
}
.options {
display: flex;
flex-direction: row;
gap: 24px;
align-items: flex-start;
justify-content: flex-start;
text-align: center;
max-height: 100px;
max-width: 100%;
overflow-y: hidden;
overflow-x: scroll;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
}
}
</style>

View File

@ -0,0 +1,66 @@
<script>
export let text = ""
export let imgLink = ""
</script>
<button>
<div>
{#if imgLink !== ""}
<img style="flex-grow: 1" src={imgLink}>
{/if}
</div>
<h3>
{text}
</h3>
</button>
<style>
button{
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
color: #61646B;
}
button:active, button:hover{
opacity: 70%;
}
button > h3{
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 15px;
line-height: 20px;
}
button > div{
width: 64px;
height: 64px;
overflow: none;
background-color: #EFEFF0;
border-radius: 200px;
border: 2px solid #AFB1B6;
display: flex;
align-items: stretch;
justify-content: stretch;
overflow: hidden;
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;
}
@media screen and (max-width: 370px){
button {
gap: 2.5vw;
}
button > div {
width: 18vw;
height: 18vw;
}
}
</style>

View File

@ -0,0 +1,57 @@
<script>
import CompartmentItem from "./Compartment_Item.svelte"
import Headline from "./Headline.svelte";
export let items = []
</script>
<div class="section">
<Headline content="Inspiration on your trip"></Headline>
<div class="options">
{#each items as item }
<CompartmentItem price={item.price} location={item.location} name={item.name} image={item.image}></CompartmentItem>
{/each}
</div>
</div>
<style>
.section{
width: calc(100% - 24px);
margin: 0 0 20px auto;
display: flex;
flex-direction: column;
align-items: flex-start;
position: relative;
}
@media screen and (max-width: 370px){
.section {
width: calc(100% - 12px);
}
}
.section > .options{
display: flex;
flex-direction: row;
gap: 12px;
align-items: flex-start;
justify-content: flex-start;
text-align: center;
max-width: 100%;
overflow-y: hidden;
overflow-x: scroll;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none;
}
.section > .options::-webkit-scrollbar {
display: none;
}
</style>

View File

@ -0,0 +1,189 @@
<script>
export let price = "$0.00"
export let location = "Home"
export let name = "Kawa Ijen"
export let image = ""
</script>
<button>
<div class="image">
{#if image !== ""}
<img style="flex-grow: 1;" src={image}>
{/if}
<div class="bookmark">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_1402_894" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="1" width="12" height="15">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 1.33301H13.3592V15.2308H2V1.33301Z" fill="white"/>
</mask>
<g mask="url(#mask0_1402_894)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.56133 2.33301C3.862 2.33301 3 2.98767 3 4.28034V14.0963C3 14.159 3.036 14.193 3.066 14.2103C3.096 14.229 3.14333 14.2423 3.198 14.2117L7.45267 11.825C7.60467 11.7403 7.79067 11.7397 7.94333 11.8257L12.1613 14.2083C12.2167 14.2403 12.264 14.2257 12.294 14.2077C12.324 14.1897 12.3593 14.1557 12.3593 14.093V4.40234C12.3593 3.89101 12.3593 2.33301 9.80067 2.33301H5.56133ZM3.13267 15.231C2.936 15.231 2.73933 15.1783 2.56067 15.073C2.20933 14.8683 2 14.5023 2 14.0963V4.28034C2 2.40701 3.298 1.33301 5.56133 1.33301H9.80067C12.062 1.33301 13.3593 2.45234 13.3593 4.40234V14.093C13.3593 14.4997 13.15 14.8657 12.798 15.0703C12.4473 15.2757 12.0247 15.2797 11.67 15.0797L7.69667 12.835L3.68667 15.0843C3.51333 15.1817 3.32333 15.231 3.13267 15.231Z" fill="white"/>
</g>
</svg>
</div>
<div class="price">
{price}
</div>
</div>
<div class="info">
<h3>{name}</h3>
<div>
<svg width="12" height="14" viewBox="0 0 12 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.16667 4.66602C5.52333 4.66602 5 5.18935 5 5.83335C5 6.47668 5.52333 6.99935 6.16667 6.99935C6.81 6.99935 7.33333 6.47668 7.33333 5.83335C7.33333 5.18935 6.81 4.66602 6.16667 4.66602ZM6.16667 7.99935C4.972 7.99935 4 7.02802 4 5.83335C4 4.63802 4.972 3.66602 6.16667 3.66602C7.36133 3.66602 8.33333 4.63802 8.33333 5.83335C8.33333 7.02802 7.36133 7.99935 6.16667 7.99935Z" fill="#61646B"/>
<mask id="mask0_1402_1007" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="12" height="14">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.666504 0.333008H11.6662V13.333H0.666504V0.333008Z" fill="white"/>
</mask>
<g mask="url(#mask0_1402_1007)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.16602 1.33301C3.68468 1.33301 1.66602 3.37101 1.66602 5.87501C1.66602 9.06101 5.41535 12.165 6.16602 12.3303C6.91668 12.1643 10.666 9.06034 10.666 5.87501C10.666 3.37101 8.64735 1.33301 6.16602 1.33301V1.33301ZM6.16602 13.333C4.97002 13.333 0.666016 9.63167 0.666016 5.87501C0.666016 2.81901 3.13335 0.333008 6.16602 0.333008C9.19868 0.333008 11.666 2.81901 11.666 5.87501C11.666 9.63167 7.36202 13.333 6.16602 13.333V13.333Z" fill="#61646B"/>
</g>
</svg>
{location}
</div>
</div>
</button>
<style>
button{
padding: 8px 8px 12px 8px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
justify-content: space-between;
position: relative;
border: 1px solid #EFEFF0;
border-radius: 20px;
}
button:hover, button:active{
opacity: 70%;
cursor: pointer;
}
button > .image{
width: 240px;
height: 152px;
/* background */
background-color: #EFEFF0;
/* subtle-light */
border: 2px solid #AFB1B6;
border-radius: 20px;
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_1402_2000' 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_1402_2000)'%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='%2361646B'/%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='%2361646B'/%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='%2361646B'/%3E%3C/svg%3E%0A");
background-repeat: no-repeat;
background-position: center;
position: relative;
display: flex;
flex-direction: row;
justify-content: stretch;
align-items: stretch;
overflow: hidden;
}
@media screen and (max-width: 390px){
button > .image{
width: 61.5vw;
height: 39vw;
}
}
@media screen and (max-width: 330px){
button > .image{
border-radius: 18px;
}
}
button > .image > .bookmark{
position: absolute;
width: 28px;
height: 28px;
right: 12px;
top: 12px;
background: #4263EB;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
}
button > .image > .price{
position: absolute;
padding: 4px 8px 4px 8px;
height: 28px;
left: 12px;
bottom: 12px;
background: #4263EB;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-family: 'Work Sans';
font-style: normal;
font-weight: 500;
font-size: 14px;
line-height: 20px;
}
@media screen and (max-width: 370px){
button > .image > .bookmark{
width: 8vw;
height: 8vw;
right: 3vw;
top: 3vw;
border-radius: 2vw;
}
button > .image > .price{
padding: 1.2vw 2vw 1.2vw 2vw;
height: 8vw;
left: 3vw;
bottom: 3vw;
border-radius: 2vw;
font-size: 13px;
line-height: 18px;
}
}
button > .info{
text-align: left;
width: 100%;
display: flex;
flex-direction: column;
gap: 8px;
}
button > .info > h3{
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 24px;
color: #19191B;
}
button > .info > div{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 8px;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 14px;
line-height: 20px;
color: #61646B;
}
</style>

View File

@ -0,0 +1,80 @@
<script>
</script>
<div class="discover">
<h2>
Dicoveries around
</h2>
<button>
Start your trips!
</button>
</div>
<style>
/*min 370px*/
.discover {
background-color: #110042;
color: white;
width: calc(100% - 48px);
height: 124px;
border-radius: 32px;
margin: 0px auto 0px auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 18px;
}
.discover > h2{
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 24px;
line-height: 32px;
margin: 0;
text-align: center;
}
.discover > button{
text-align: center;
color: #110042;
background-color: #FFFFFF;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 20px;
padding: 8px 55px 8px 55px;
border-radius: 15px;
}
.discover > button:hover, .discover > button:active{
opacity: 80%;
cursor: pointer;
}
@media screen and (max-width: 370px){
.discover {
width: calc(100% - 24px);
height: 33.5vw;
border-radius: 8vw;
}
.discover > button{
font-size: 4.3vw;
line-height: 5.4vw;
padding: 2.2vw 14.8vw 2.2vw 14.8vw;
border-radius: 15px;
}
.discover > h2{
font-size: 6.4vw;
line-height: 8.6vw;
}
}
</style>

View File

@ -0,0 +1,33 @@
<script>
export let content = ""
</script>
<h1>
{content}
</h1>
<style>
h1{
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 24px;
line-height: 30px;
text-align: left;
margin-top: 0;
}
@media screen and (max-width: 370px)
{
h1 {
font-size: 6.4vw;
line-height: 8.6vw;
}
}
@media screen and (max-width: 300px)
{
h1 {
font-size: 19px;
line-height: 25px;
}
}
</style>

View File

@ -0,0 +1,97 @@
<script>
import { navigate } from 'svelte-routing'
export let headline = 'Paris, Les Invalides'
</script>
<div class="top">
<button on:click={() => navigate('/scanner')}>
<svg viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M5.77778 8.66765C5.77778 7.07876 7.07778 5.77876 8.66667 5.77876H14.4445C16.0333 5.77876 17.3333 4.47876 17.3333 2.88987C17.3333 1.30098 16.0333 0.000976562 14.4445 0.000976562H5.77778C2.6 0.000976562 0 2.60098 0 5.77876V14.4454C0 16.0343 1.3 17.3343 2.88889 17.3343C4.47778 17.3343 5.77778 16.0343 5.77778 14.4454V8.66765ZM2.88889 34.666C1.3 34.666 0 35.966 0 37.5549V46.2216C0 49.3994 2.6 51.9994 5.77778 51.9994H14.4445C16.0333 51.9994 17.3333 50.6994 17.3333 49.1105C17.3333 47.5216 16.0333 46.2216 14.4445 46.2216H8.66667C7.07778 46.2216 5.77778 44.9216 5.77778 43.3327V37.5549C5.77778 35.966 4.47778 34.666 2.88889 34.666ZM37.5553 0.000976562H46.222C49.3998 0.000976562 51.9998 2.60098 51.9998 5.77876V14.4454C51.9998 16.0343 50.6998 17.3343 49.1109 17.3343C47.522 17.3343 46.222 16.0343 46.222 14.4454V8.66765C46.222 7.07876 44.922 5.77876 43.3331 5.77876H37.5553C35.9664 5.77876 34.6664 4.47876 34.6664 2.88987C34.6664 1.30098 35.9664 0.000976562 37.5553 0.000976562ZM46.2221 43.3327C46.2221 44.9216 44.9221 46.2216 43.3332 46.2216H37.5554C35.9665 46.2216 34.6665 47.5216 34.6665 49.1105C34.6665 50.6994 35.9665 51.9994 37.5554 51.9994H46.2221C49.3998 51.9994 51.9998 49.3994 51.9998 46.2216V37.5549C51.9998 35.966 50.6998 34.666 49.111 34.666C47.5221 34.666 46.2221 35.966 46.2221 37.5549V43.3327ZM28.8881 23.1085H23.1104V28.8838H17.3345V34.6616H23.1123V28.8862H28.8881V23.1085ZM23.1123 28.8862V28.8838H23.1104V28.8862H23.1123ZM28.8912 28.8838H34.6689V34.6616H28.8912V28.8838ZM34.669 17.3302H28.8913V23.108H34.669V17.3302ZM17.3345 17.3301H23.1123V23.1079H17.3345V17.3301Z"
fill="#4263EB"
/>
</svg>
</button>
<div>
<h1>
{headline}
</h1>
</div>
<button>
<svg viewBox="0 0 62 62" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M39.2319 37.3851H41.2728L52.2261 48.3901C53.2853 49.4492 53.2853 51.1801 52.2261 52.2392C51.1669 53.2984 49.4361 53.2984 48.3769 52.2392L37.3978 41.2601V39.2192L36.7003 38.4959C33.0836 41.5959 28.1494 43.1976 22.9053 42.3192C15.7236 41.1051 9.98861 35.1117 9.11027 27.8784C7.76694 16.9509 16.9636 7.75425 27.8911 9.09758C35.1244 9.97591 41.1178 15.7109 42.3319 22.8926C43.2103 28.1367 41.6086 33.0709 38.5086 36.6876L39.2319 37.3851ZM14.1478 25.7601C14.1478 32.1926 19.3403 37.3851 25.7728 37.3851C32.2053 37.3851 37.3978 32.1926 37.3978 25.7601C37.3978 19.3276 32.2053 14.1351 25.7728 14.1351C19.3403 14.1351 14.1478 19.3276 14.1478 25.7601Z"
fill="#4263EB"
/>
</svg>
</button>
</div>
<style>
button:hover,
button:active {
opacity: 70%;
cursor: pointer;
}
.top {
width: calc(100% - 48px);
height: 62px;
margin: 30px auto 20px auto;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
position: relative;
}
.top h1 {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 24px;
line-height: 30px;
}
.top > button {
height: 100%;
position: relative;
}
.top > button > svg {
height: 90%;
width: auto;
}
@media screen and (max-width: 370px) {
.top {
width: calc(100% - 24px);
}
}
@media screen and (max-width: 440px) {
.top {
height: 14vw;
}
.top h1 {
font-size: 5.5vw;
line-height: 6.8vw;
}
}
@media screen and (max-width: 310px) {
.top {
height: 14vw;
}
.top h1 {
font-size: 18px;
line-height: 21px;
}
}
</style>

View File

@ -0,0 +1,77 @@
<script>
import NavigationBarLayout from '../../lib/Components/Layouts/NavigationBarLayout.svelte'
import Discover from './Components/Discover.svelte'
import Top from './Components/Top.svelte'
import Categories from './Components/Categories.svelte'
import Comparment from './Components/Comparment.svelte' //do budoucna bych to udělal pomocí komponent
import { onMount } from 'svelte'
import Animation from './Components/Animation.svelte'
let fitstTime = false
onMount(() => {
if (localStorage.getItem("ErantFirstTime") == null){
fitstTime = true
setTimeout(() => {
fitstTime = false
localStorage.setItem('ErantFirstTime', "false");
}, 5000)
}
})
</script>
{#if !fitstTime}
<NavigationBarLayout>
<Top />
<Discover />
<div class="line" />
<Categories />
<Comparment
items={[
{ price: '$10.00', location: 'Prag, Czech Republic', name: 'Hometown', image: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg' },
{ price: '$10.00', location: 'Prag, Czech Republic', name: 'Hometown', image: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg' },
{ price: '$10.00', location: 'Prag, Czech Republic', name: 'Hometown', image: 'https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg' },
]}
/>
</NavigationBarLayout>
{:else}
<div class="content">
<Animation />
</div>
{/if}
<style>
.content {
height: calc(100% - 94px);
width: 100%;
margin-bottom: 94px;
overflow-y: scroll;
overflow-x: hidden;
position: relative;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none;
}
.content::-webkit-scrollbar {
display: none;
}
.line {
width: calc(100% - 48px);
height: 1px;
background-color: #efeff0;
margin: 20px auto 20px auto;
}
@media screen and (max-width: 370px) {
.line {
width: calc(100% - 24px);
margin: 5.4vw auto 5.4vw auto;
}
}
</style>

View File

@ -1,41 +0,0 @@
<script lang="ts">
import { user } from '$lib/appwrite'
import { Button } from '$lib/components/Common'
import { _ } from 'svelte-i18n'
</script>
<div class="flex flex-col mt-20">
<h1 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl mb-5">
<span class="block text-indigo-600">{$_('page.home.title')}</span>
<p>
<Button class="underline" href="https://appwrite.io/">Appwrite</Button>
</p>
<p>
<Button class="underline" href="https://github.com/lewis-wow/appwrite-svelte-rocket-start">Repository</Button>
</p>
</h1>
<div class="text-xl font-bold tracking-tight text-gray-900">
{#if $user}
<div>
<p>
<Button class="underline" on:click={() => user.deleteSession('current')}>Logout</Button>
</p>
<p>
<b>user:</b>
{$user.email}
</p>
</div>
{:else}
<div>
<p>
<Button class="underline" on:click={() => user.createAccount('example@example.com', 'password')}>Register</Button>
</p>
<p>
<Button class="underline" on:click={() => user.createEmailSession('example@example.com', 'password')}>Login</Button>
</p>
</div>
{/if}
</div>
</div>

244
src/routes/log_in.svelte Normal file
View File

@ -0,0 +1,244 @@
<script>
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 = 'login' //possible values login, register
</script>
<div class="main">
<!--Top image static link form lib/svg-->
<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>
<!--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 type="text" placeholder="Name" autocomplete="full-name" required />
<input type="text" placeholder="E-mail" autocomplete="email" required />
<HiddenInput placeholder="Password" />
<HiddenInput placeholder="Re-type password" />
<input type="submit" value="Sign up" />
</form>
{/if}
</div>
<div class="continue_with">
<button>
<GoogleLogo />
<p>Continue with Google</p>
</button>
<button>
<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>
<style lang="scss">
$gap: 20px;
.main {
width: 100%;
max-height: 100vh;
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: $gap;
padding: 30px 0 0 0;
@media screen and (max-height: 990px) {
gap: 2vh;
}
.top-image {
display: flex;
align-items: center;
justify-content: center;
}
.headline {
text-align: center;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 40px;
margin: 0px;
@media screen and (max-height: 750px) {
font-size: 5.3vh;
}
}
.continue_with {
width: calc(100% - 48px);
margin: 0 auto 0 auto;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
@media screen and (max-width: 410px) {
width: calc(100% - 24px);
}
button {
height: 60px;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 16px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.084), 0px 2px 3px rgba(0, 0, 0, 0.168);
@media screen and (max-width: 410px) {
gap: 3.5vw;
}
p {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 28px;
line-height: 36px;
color: rgba(0, 0, 0, 0.54);
@media screen and (max-width: 400px) {
font-size: 7.3vw;
}
}
}
button:hover {
opacity: 70%;
}
}
.form {
width: calc(100% - 48px);
position: relative;
margin: 0 auto 0 auto;
@media screen and (max-width: 410px) {
width: calc(100% - 24px);
}
form {
display: flex;
flex-direction: column;
align-items: center;
gap: $gap;
@media screen and (max-height: 990px) {
gap: 2vh;
}
width: 100%;
position: relative;
input[type='text'] {
width: calc(100%);
padding: 12px 24px;
border-radius: 15px;
background-color: #eeeeee;
font-size: 18px;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
line-height: 28px;
@media screen and (max-height: 720px) {
padding: 8px 24px;
}
}
::placeholder {
color: #8f8f8f;
font-size: 18px;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
line-height: 28px;
}
input[type='submit'] {
background-color: #4263eb;
color: white;
width: 100%;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 32px;
line-height: 40px;
padding: 12px 0px;
border-radius: 15px;
@media screen and (max-height: 820px) {
font-size: 3.9vh;
line-height: 4.8vh;
padding: 1.4vh 0px;
}
}
}
}
.LR_switch {
width: calc(100% - 48px);
padding-bottom: 30px;
text-align: center;
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
font-size: 24px;
letter-spacing: 0.5px;
color: rgba(0, 0, 0, 0.4);
@media screen and (max-width: 410px) {
width: calc(100% - 24px);
font-size: 5.8vw;
}
@media screen and (max-width: 320px) {
font-size: 18px;
}
a {
color: #4263eb;
}
a:hover {
opacity: 50%;
}
}
}
</style>

15
src/routes/map.svelte Normal file
View File

@ -0,0 +1,15 @@
<script>
import Erantmap from '$lib/Components/Map/Erantmap.svelte'
import NavigationBarLayout from '$lib/Components/Layouts/NavigationBarLayout.svelte'
let user = { lat: 50.073658, lng: 14.41854 }
const lastGame = localStorage.getItem('lastGame')
if (lastGame) {
location.href = lastGame
}
</script>
<NavigationBarLayout>
<Erantmap class="w-full h-full" center={{ lng: user.lng, lat: user.lat }} bind:user />
</NavigationBarLayout>

View File

@ -0,0 +1,64 @@
<script>
import Logout from './../../lib/svg/Logout.svelte'
import Help from './../../lib/svg/Help.svelte'
import Line from '$lib/Components/common/Line.svelte'
import SettingRow from '$lib/Components/common/SettingRow.svelte'
import Profile from '$lib/svg/Profile.svelte'
import Wallet from '$lib/svg/Wallet.svelte'
import Setting2 from '$lib/svg/Setting2.svelte'
import { Link } from 'svelte-routing'
import NavigationBarLayout from './../../lib/Components/Layouts/NavigationBarLayout.svelte'
import Earth from '$lib/svg/Earth.svelte'
import Warning from '$lib/svg/Warning.svelte'
import Point from '$lib/svg/Point.svelte'
import PointSmall from '$lib/svg/PointSmall.svelte'
import InputPicture from '$lib/Components/Inputs/InputPicture.svelte'
const items = [
{
title: 'Account',
itms: [
{ icon: Profile, text: 'Your Profile' },
{ icon: Wallet, text: 'Payment History' },
{ icon: Setting2, text: 'Preferences' },
],
},
{
title: 'Settings',
itms: [{ icon: Earth, text: 'Language' }],
},
{
title: 'Legal',
itms: [
{ icon: Help, text: 'Help' },
{ icon: Warning, text: 'Terms & Conditions' },
{ icon: Logout, text: 'Log out' },
],
},
]
</script>
<NavigationBarLayout class="p-4">
<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>
<SettingRow class="w-auto gap-2">
<PointSmall />
<span class="text-[16px] text-[#61646B]">Prague, Czechia</span>
</SettingRow>
</div>
<Line />
<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 }}
<SettingRow>
<svelte:component this={icon} />
<Link class="font-semibold text-[18px]" to={'/'}>{text}</Link>
</SettingRow>
<Line />
{/each}
{/each}
</div>
</NavigationBarLayout>

View File

@ -0,0 +1,16 @@
<script>
let className = ''
export { className as class }
</script>
<div class={'h-[80px] w-[450px] max-w-[90%] p-6 bg-[#282828] flex flex-wrap flex-col m-3 gap-[5px] rounded-[30px] ' + className}>
<button on:click class="h-full w-auto">
<svg width="35" height="34" viewBox="0 0 35 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24.2192" height="6.08178" rx="3.04089" transform="matrix(0.716773 -0.697307 -0.716773 -0.697307 4.35938 21.1992)" fill="#4263EB" />
<rect width="24.3271" height="6.0548" rx="3.0274" transform="matrix(-0.716773 -0.697307 -0.716773 0.697307 21.791 29.7002)" fill="#4263EB" />
</svg>
</button>
<span class="text-[#8A8A8A] flex text-center items-center h-full w-[85%]">
<slot />
</span>
</div>

View File

@ -0,0 +1,15 @@
<script>
import { createEventDispatcher } from 'svelte'
const dispatch = createEventDispatcher()
let className = ''
export { className as class }
let value = ''
</script>
<div class={'h-auto w-full relative flex justify-center gap-4 flex-wrap flex-col items-center p-[20px] ' + className}>
<div class="h-[300px] w-[300px] max-w-[75vw] rounded-[20px] bg-white flex justify-center items-center">
<!--image-->
</div>
<input bind:value type="text" placeholder="The code..." class="block p-3 border rounded-[15px] h-[52px] max-w-[75vw] w-[383px] mt-4" />
<button class="w-[383px] max-w-[75vw] rounded-[15px] bg-white z-10 h-[52px] bg-[#4263EB] text-white text-[24px]" on:click={() => dispatch('submit', value)}>Continue</button>
</div>

View File

@ -0,0 +1,48 @@
<script>
import { Html5Qrcode } from 'html5-qrcode'
import { createEventDispatcher, onMount } from 'svelte'
const dispatch = createEventDispatcher()
let className = ''
export { className as class }
onMount(() => {
const bodyHeight = document.body.offsetHeight
const bodyWidth = document.body.offsetWidth
const readerWidth = document.getElementById('reader').offsetWidth
const readerHeight = document.getElementById('reader').offsetHeight
const aspectRatio = readerWidth / readerHeight
const reverseAspectRatio = readerHeight / readerWidth
const mobileAspectRatio = reverseAspectRatio > 1.5 ? reverseAspectRatio + (reverseAspectRatio * 12) / 100 : reverseAspectRatio
const config = {
fps: 20,
qrbox: { width: (3 / 4) * readerWidth, height: (1 / 2) * readerHeight },
aspectRatio: bodyWidth < 600 ? mobileAspectRatio : aspectRatio,
}
const html5QrCode = new Html5Qrcode('reader')
// @ts-ignore
html5QrCode.start({ facingMode: 'environment' }, config, (text, result) => {
html5QrCode.stop()
dispatch('scan', {
text,
result,
})
})
})
</script>
<div class={'w-full h-full flex absolute overflow-hidden ' + className}>
<div id="reader" class="w-full h-full flex justify-center items-center overflow-hidden" />
<div class="h-full w-full absolute">
<slot />
</div>
</div>
<style>
@media only screen and (min-width: 600px) {
#reader {
transform: rotateY(180deg);
}
}
</style>

View File

@ -0,0 +1,17 @@
<script>
</script>
<div class="absolute overflow-hidden w-[75%] h-1/2 z-20">
<svg class="absolute top-0 left-0" width="100" height="100" viewBox="0 0 125 125" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 120C5 120 5.00003 77.9998 5 60C4.99994 27.9998 31 4.99984 60 5C81.5 5.00012 120 5 120 5" stroke="#4263EB" stroke-width="10" stroke-linecap="round" />
</svg>
<svg class="absolute top-0 right-0" width="100" height="100" viewBox="0 0 125 125" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M120 120C120 120 120 77.9998 120 60C120 27.9998 94 4.99984 65 5C43.5 5.00012 5 5 5 5" stroke="#4263EB" stroke-width="10" stroke-linecap="round" />
</svg>
<svg class="absolute bottom-0 left-0" width="100" height="100" viewBox="0 0 125 125" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 5C5 5 5.00003 47.0002 5 65C4.99994 97.0002 31 120 60 120C81.5 120 120 120 120 120" stroke="#4263EB" stroke-width="10" stroke-linecap="round" />
</svg>
<svg class="absolute bottom-0 right-0" width="100" height="100" viewBox="0 0 125 125" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M120 5C120 5 120 47.0002 120 65C120 97.0002 94 120 65 120C43.5 120 5 120 5 120" stroke="#4263EB" stroke-width="10" stroke-linecap="round" />
</svg>
</div>

View File

@ -0,0 +1,21 @@
<script>
import { createEventDispatcher } from 'svelte'
let className = ''
export { className as class }
const dispatch = createEventDispatcher()
export let switched = null
$: dispatch('switch', switched)
</script>
{#if switched === 'scan'}
<div class={'h-[80px] w-[340px] max-w-[95%] bg-[#282828] p-[8px] flex flex-wrap flex-col gap-[8px] rounded-[30px] ' + className}>
<button class="rounded-[20px] bg-[#4263EB] text-white h-full"> Scan QR </button>
<button on:click={() => (switched = 'input')} class="rounded-[20px] bg-[#282828] text-[#8A8A8A] h-full"> Type in code </button>
</div>
{:else if switched === 'input'}
<div class={'h-[80px] w-[340px] max-w-[95%] bg-[#282828] p-[8px] flex flex-wrap flex-col gap-[8px] rounded-[30px] ' + className}>
<button on:click={() => (switched = 'scan')} class="rounded-[20px] bg-[#282828] text-[#8A8A8A] h-full"> Scan QR </button>
<button class="rounded-[20px] bg-[#4263EB] text-white h-full"> Type in code </button>
</div>
{/if}

View File

@ -0,0 +1,36 @@
<script>
import ScanFrame from './Components/ScanFrame.svelte'
import InfoBar from './Components/InfoBar.svelte'
import QRscanner from './Components/QRscanner.svelte'
import SwitchBar from './Components/SwitchBar.svelte'
import QRinput from './Components/QRinput.svelte'
import { navigate } from 'svelte-routing'
let switched = 'scan'
</script>
<div class="w-full h-full relative">
{#if switched === 'scan'}
<div class="h-auto w-full justify-center flex flex-wrap flex-row">
<InfoBar class="mt-[40px] top-0 relative z-10" on:click={() => window.history.back()}>Scan our QR code or type in code to load the experience</InfoBar>
<QRscanner on:scan={(e) => (location.href = e.detail)}>
<div class="h-full w-full relative flex justify-center gap-4 flex-wrap flex-row items-center">
<ScanFrame />
</div>
</QRscanner>
<SwitchBar {switched} on:switch={(e) => (switched = e.detail)} class="mb-[40px] bottom-0 max-w-[95%] absolute z-10" />
</div>
{:else if switched === 'input'}
<div class="h-max min-h-full w-full bg-[#3A3A3A] justify-center flex flex-wrap flex-row">
<InfoBar class="mt-[40px] top-0 relative z-10" on:click={() => window.history.back()}>Type code or type in code to load the experience</InfoBar>
<QRinput class="mb-[40px]" on:submit={(e) => navigate(e.detail)} />
<SwitchBar {switched} on:switch={(e) => (switched = e.detail)} class="mb-[40px] mt-auto bottom-0 max-w-[95%] relative z-10" />
</div>
{/if}
</div>
<style>
:global(#qr-shaded-region) {
display: none !important;
}
</style>

5
src/routes/test.svelte Normal file
View File

@ -0,0 +1,5 @@
<script>
import Carousel from '../lib/Components/common/Carousel.svelte'
</script>
<Carousel />

View File

@ -1,15 +1,8 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./src/**/*.{html,js,svelte,ts}',
'./cms/**/*.{html,js,svelte,ts}',
'./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}',
],
content: ['./index.html', './src/**/*.{html,svelte,js,ts}'],
theme: {
extend: {}
extend: {},
},
plugins: [
require('flowbite/plugin')
],
darkMode: 'class'
plugins: [],
}