Files
housesof/src/routes/location/[country]/[location].svelte
Félix Péault 1db9217cd0 Use a component for the pagination
Make the component and the page communicate with events to add more photos
2020-03-02 22:27:39 +01:00

195 lines
6.3 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,
site,
locations,
currentLocation,
currentPhotos
} from '../../../store'
import { stores } from '@sapper/app'
// Preload data
export async function preload (page, session) {
// Load photos
const req = await this.fetch(`${apiEndpoints.rest}/items/photos?fields=id,name,slug,image.*,location.*,location.country.*,created_on,modified_on&filter[location.slug][rlike]=%${page.params.location}%&limit=-1&sort=-created_on,name`)
console.log(req.headers.host)
const photos = await req.json()
if (req.ok) {
return { photos: photos.data }
}
this.error(404, 'Not found')
}
</script>
<script>
import { onMount } from 'svelte'
import * as fn from '../../../functions'
const { page } = stores()
// Dependencies
import AOS from 'aos'
import 'lazysizes'
import dayjs from 'dayjs'
import advancedFormat from 'dayjs/plugin/advancedFormat'
import relativeTime from 'dayjs/plugin/relativeTime'
dayjs.extend(advancedFormat)
dayjs.extend(relativeTime)
// 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'
// Props and variables
export let photos
let layoutSetting
// Update current location
const location = $locations.find(loc => loc.slug === $page.params.location)
currentLocation.set(location)
currentPhotos.set(photos)
// Define dates
$: latestPhoto = photos[0]
$: dateUpdatedFull = latestPhoto ? dayjs(latestPhoto.modified_on).format('MMM Do, YYYY') : ''
$: dateUpdatedDatetime = latestPhoto ?dayjs(latestPhoto.modified_on).format('YYYY-MM-DDThh:mm:ss') : ''
$: dateUpdatedRelative = latestPhoto ?dayjs().to(dayjs(latestPhoto.modified_on)) : ''
$: lastUpdated = latestPhoto ? (dayjs(latestPhoto.modified_on).isBefore(dayjs().subtract(1, 'M'))) ? dateUpdatedFull : dateUpdatedRelatives : ''
/*
** Pagination
*/
let photosPerPage = 2 // 12
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.paginatedPhotos
/*
** Run code on browser only
*/
onMount(() => {
// Get layout setting from storage
layoutSetting = localStorage.getItem('photosLayout')
if (process.browser) {
// Scroll apparitions
AOS.init()
}
})
</script>
<svelte:head>
<title>Houses Of Beautiful houses of {location.name}, {location.country.name}</title>
<meta name="description" content="Houses Of {location.name} {location.description}">
<SocialMetas
url="https://housesof.world/location/{location.country.slug}/{location.slug}"
title="Houses Of Beautiful houses of {location.name}, {location.country.name}"
description="Houses Of {location.name} {location.description}"
image={latestPhoto ? fn.getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null}
/>
</svelte:head>
<section class="place">
<div class="place__title">
<h1 class="title-location title-location--big">
<span class="top">Houses <em>of</em></span>
<span class="bottom">{location.name}</span>
</h1>
<a href="/choose" class="button-control button-control--big button-control--dashed">
<span class="center">
<IconGlobe width="44" color="#fff" />
<span>Change</span>
</span>
<svg>
<circle cx="50%" cy="50%" r="43%" />
</svg>
</a>
</div>
<div class="place__wrap wrap">
<div class="place__description">
<div class="wrapper">
<p>{$site.description}</p>
{#if location.description}
<p>
Houses Of
<LinkChange href="/choose" text={location.name}>
<IconGlobeSmall width="14" color="#999" />
</LinkChange>
{location.description}
</p>
{/if}
{#if photos.length}
<p class="updated style-caps">
<strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{lastUpdated}</time>
</p>
<ToggleLayout />
{/if}
</div>
</div>
</div>
<div class="place__illustration">
<div class="place__illustration--left side"></div>
<div class="place__illustration--center"></div>
<div class="place__illustration--right side"></div>
</div>
</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}>{lastUpdated}</time>
</p>
{/if}
</aside>
</div>
{#if photos.length}
<div class="photos__view wrap">
{#each paginatedPhotos as photo, index}
<Photo
photo={photo}
index={photos.length - photos.indexOf(photo)}
layout={layoutSetting}
/>
{/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 />