Merge pull request #35 from zschaffer/dev

dev
This commit is contained in:
Xinrui Chen 2022-07-20 10:48:09 -07:00 committed by GitHub
commit 2bb2d07653
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 104 additions and 10 deletions

View File

@ -1,3 +1,7 @@
/**
* @param {rating[]} ratings An array of ratings
* @returns {number} Average rating
*/
export const getAvgRating = (ratings) => {
if (!ratings) return 0;
if (ratings.length === 1) return ratings[0].rating;

View File

@ -1,2 +1,6 @@
/**
* @param {string} str Any string
* @returns {string} Lowercased string without any extra spaces
*/
export const normalize = (str) => str.toLowerCase().trim()

View File

@ -1,9 +1,17 @@
import {normalize }from './normalize';
/**
* @param {string} slug Slug of a product name
* @returns Normalized slug with all dashes replaced with spaces
*/
export function parseSlug(slug) {
return normalize(slug).replaceAll("-", " ")
}
/**
* @param {string} name Product name
* @returns Normalized name with all spaces replaced with '-'
*/
export function parseName(name) {
return normalize(name).replaceAll(" ","-")
}

View File

@ -1,8 +1,35 @@
import {normalize, parseName} from './index';
import { parseName, parseSlug, normalize } from './';
export const toProduct = (product, currentProduct) => {
const url = new URL(window.location);
url.searchParams.set('product', normalize(parseName(product.name)));
window.history.pushState({}, '', url);
currentProduct.set(product)
}
/**
* Updates a url with search parameters to match product name of product passed in.
* @param {URL} url a URL object
* @param {object} product
* @returns {URL} a URL object with search parameters appended.
*/
const setUrlParam = (url, product) => {
url.searchParams.set('product', parseName(product.name));
return url;
};
/**
* Updates Window URL and checks that it is equal to product name
* @param {URL} url a URL object
* @param {product} product product to check URL against
* @returns {Boolean} True if URL parameter is equal to product name
*/
const didWinUrlUpdate = (url, product) => {
window.history.pushState(window.history.state, '', url);
const params = new URLSearchParams(window.location.search).get('product');
return parseSlug(params) === normalize(product.name);
};
/**
* Takes a `product` and `currentProduct` store
* Sets URL params to parsed product name and updates Browser URL
* Sets `currentProduct` store to `product`.
* @param {object} product The product to switch feature to.
* @param {store} currentProduct currentProduct store
*/
export const toProduct = (product, currentProduct) =>
didWinUrlUpdate(setUrlParam(new URL(window.location), product), product) &&
currentProduct.set(product)

View File

@ -2,6 +2,7 @@
import { urlFor } from '$lib/sanityClient';
import { currentProduct } from '$lib/stores';
import Rating from './Rating/Rating.svelte';
import PrevNext from './PrevNext/PrevNext.svelte';
import Tag from './Tag/Tag.svelte';
const { container, imageView, name, description, productInfo, date, tags, img, ratings } = {
@ -44,6 +45,7 @@
{/each}
</div>
{/if}
<PrevNext />
</div>
<style>

View File

@ -0,0 +1,50 @@
<script>
import { currentProduct, productsView } from '$lib/stores';
import { toProduct } from '$helpers';
$: foundIndex = $productsView.findIndex((prod) => prod._id === $currentProduct._id)
$: PREV = $productsView[foundIndex-1];
$: NEXT = $productsView[foundIndex+1];
const navigate = (e) => {
if (e.target.name === 'prev' && PREV) {
toProduct(PREV, currentProduct)
}
if (e.target.name === 'next' && NEXT){
toProduct(NEXT, currentProduct)
}
}
const { container, btn } = {
container: 'flex justify-between h-12 ml-16 mr-16',
btn: 'flex items-center gap-4'
};
</script>
<div class={container}>
{#if PREV }
<button on:click={navigate} class={btn} name={'prev'}
><svg focusable="false" width={50} height={50} viewBox="0 0 24 24">
<path d="m14 7-5 5 5 5V7z" />
</svg>{PREV.name}</button
>
{:else}
<div></div>
{/if}
{#if NEXT}
<button on:click={navigate} class={btn} name={'next'}
>{NEXT.name}<svg focusable="false" width={50} height={50} viewBox="0 0 24 24"
><path d="m10 17 5-5-5-5v10z" /></svg
></button
>
{:else}
<div></div>
{/if}
</div>
<style>
svg,path {
pointer-events: none;
}
</style>

View File

@ -12,8 +12,7 @@
productsView.set(data.products);
const goToProduct = () => {
const params = new URLSearchParams(window.location.search);
const paramProd = params.get('product');
const paramProd = (new URLSearchParams(window.location.search)).get('product');
if (paramProd) {
const foundProduct = $products.find(

View File

@ -3,7 +3,7 @@ import { resolve } from 'path';
/** @type {import('vite').UserConfig} */
const config = {
plugins: [sveltekit()],
plugins: [sveltekit()],
resolve: {
alias: {
$lib: resolve('./src/lib'),