Files
housesof/src/routes/location/[country]/[place].svelte

209 lines
7.8 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script context="module">
import { apiEndpoints } from 'utils/store'
// Preload data
export async function preload (page, session) {
// Load photos
const fields = [
'id', 'name', 'slug', 'date', 'image.private_hash',
'location.id', 'location.name', 'location.slug', 'location.region',
'location.country.name', 'location.country.slug',
'created_on', 'modified_on'
].join(',')
const sort = ['-created_on', 'name'].join(',')
const limit = -1
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=${fields}&status=published&filter[location.slug][rlike]=%${page.params.place}%&limit=${limit}&sort=${sort}`, {
'Authorization': 'bearer ' + process.env.CONFIG.API_TOKEN
})
const photos = await req.json()
if (req.ok) {
return { photos: photos.data }
}
this.error(404, 'Not found')
}
</script>
<script>
import { onMount } from 'svelte'
import { stores } from '@sapper/app'
import {
site,
locations,
currentLocation,
currentPhotos,
pageReady,
pageAnimation
} from 'utils/store'
import { formatDate, relativeTime, getThumbnail } from 'utils/functions'
// Components
import IconGlobe from 'atoms/IconGlobe'
import IconGlobeSmall from 'atoms/IconGlobeSmall'
import LinkChange from 'atoms/LinkChange'
import ToggleLayout from 'atoms/ToggleLayout'
import Photo from 'molecules/Photo'
import Switcher from 'molecules/Switcher'
import Pagination from 'organisms/Pagination'
import Footer from 'organisms/Footer'
import SocialMetas from 'utils/SocialMetas'
// Animations
import { animateIn } from 'animations/place'
// Props and variables
export let photos
const { page } = stores()
pageAnimation.set(animateIn)
let layoutSetting
let windowWidth
$: latestPhoto = photos[0]
// Update current location
const location = $locations.find(loc => loc.slug === $page.params.place)
const { description, country, illu_desktop, illu_desktop_2x, illu_mobile } = location
currentLocation.set(location)
currentPhotos.set(photos)
// Define dates
$: latestPhotoModified = latestPhoto ? latestPhoto.modified_on.replace(' ', 'T') : ''
$: dateUpdatedFull = latestPhoto ? formatDate(latestPhotoModified, 'FULL') : ''
$: dateUpdatedDatetime = latestPhoto ? formatDate(latestPhotoModified, 'DATETIME') : ''
$: dateUpdatedRelative = latestPhoto ? relativeTime(latestPhotoModified, 2592000000) : ''
/*
** Pagination
*/
let photosPerPage = $site.photos_per_page
let currentIndex = photosPerPage
// Hide photos by default
photos.forEach((photo, index) => photo.hidden = (index + 1 > photosPerPage) ? true : false)
let paginatedPhotos = photos.filter(photo => photo.hidden === false)
// Update pagination event from Pagination component
const updatePagination = event => paginatedPhotos = event.detail
/*
** Run code when mounted
*/
onMount(() => {
// Page is loaded
pageReady.set(true)
// Get layout setting from storage
layoutSetting = localStorage.getItem('photosLayout')
})
</script>
<svelte:head>
<title>{$site.seo_name} {$site.seo_title_default} of {location.name}, {country.name}</title>
<meta name="description" content="{$site.seo_name} {location.name} {description}">
<SocialMetas
url="{process.env.CONFIG.PROD_URL}/location/{country.slug}/{location.slug}"
title="{$site.seo_name} {$site.seo_title_default} of {location.name}, {country.name}"
description="{$site.seo_name} {location.name} {description}"
image={latestPhoto ? getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null}
/>
</svelte:head>
<svelte:window bind:innerWidth={windowWidth} />
<main class="housesof" class:is-transitioning={!$pageReady}>
<section class="place">
<div class="place__title">
<h1 class="title-location title-location--big" aria-label="Houses of {location.name}" data-rellax-speed="-2.75" data-rellax-max-y="200">
<span class="place__title_top anim-mask">
<span class="place__title_houses">Houses</span>
<em class="place__title_of">of</em>
</span>
<span class="place__title_bottom anim-mask">
<span class="place__title_name">{location.name}</span>
</span>
</h1>
<div data-rellax-speed={windowWidth <= 768 ? -2.5 : -1.75} data-rellax-max-y="200">
<a href="/choose" class="button-control button-control--big button-control--dashed" aria-label="Change location">
<span class="center">
<IconGlobe width={windowWidth <= 768 ? 32 : 44} color="#fff" />
<span>Change</span>
</span>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="50%" cy="50%" r="43%" />
</svg>
</a>
</div>
</div>
<div class="place__wrap wrap">
<div class="place__description">
<div class="wrapper">
<p>{$site.description}</p>
{#if description}
<p>
Houses Of
<LinkChange href="/choose" text={location.name}>
<IconGlobeSmall width="14" color="#999" />
</LinkChange>
{description}
</p>
{/if}
{#if photos.length}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
</p>
<ToggleLayout />
{/if}
</div>
</div>
</div>
{#if illu_desktop || illu_desktop_2x || illu_mobile}
<div class="place__illustration">
<div class="parallax" data-rellax-speed="-5" data-rellax-max-y="400">
<div class="place__illustration_img" style="{`--url-desktop: ${illu_desktop ? `url(${illu_desktop.full_url});` : undefined}`}
{`--url-desktop-2x: ${illu_desktop_2x ? `url(${illu_desktop_2x.full_url});` : undefined}`}
{`--url-mobile: ${illu_mobile ? `url(${illu_mobile.full_url});` : undefined}`}"
/>
</div>
</div>
{/if}
</section>
<section class="photos photos--{layoutSetting || 'list'}">
<div class="photos__sidewrap wrap">
<aside class="photos__side">
<Switcher type="switcher--side" />
{#if photos.length}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
</p>
{/if}
</aside>
</div>
{#if photos}
<div class="photos__view wrap">
{#each paginatedPhotos as photo, index}
<Photo {photo} index={photos.length - photos.indexOf(photo)} />
{/each}
</div>
<Pagination {photos} {paginatedPhotos} {photosPerPage}
on:updatePagination={updatePagination}
/>
{:else}
<div class="wrap" style="padding-top: 20vw; padding-bottom: 20vw;">
<p style="text-align: center; color: #333;">No photo for {location.name}</p>
</div>
{/if}
</section>
<Footer />
</main>