Patch: Receipt page (#7)

* OrderSection receipts list of lineItems instead of always getting cart

* Hide express checkout behind feature flag

* Add torn receipt paper css look to order list

* Re-use OrderSection on receipt page

* Linting

* Reduced max font from 130->120%, now only applies scaling on div.main

Reducing relative font size for the largest screen width.
Scaling only applies to main container, not header and footer.

* Minor header size changes

* Set max-width to login input elements on desktop

* Prettier doesn't liek shorthand props
This commit is contained in:
2023-03-28 18:35:14 +02:00
committed by GitHub
parent 8bb65dfc2e
commit 63a1107427
12 changed files with 92 additions and 97 deletions

View File

@@ -14,7 +14,7 @@
<footer>
<section>
<h2>Personvern og vilkår</h2>
<h1>Personvern og vilkår</h1>
<ul>
<li><LinkArrow /><a href="/terms-and-conditions">Betingelser og vilkår</a></li>
<li><LinkArrow /><a href="/privacy-policy">Personvernerklæring</a></li>
@@ -31,7 +31,7 @@
</section>
<section>
<h2>Kontakt</h2>
<h1>Kontakt</h1>
<ul>
<li>Epost:&nbsp;<a class="link" href="mailto:post@planetposen.no">post@planetposen.no</a></li>
@@ -41,6 +41,7 @@
Kode:&nbsp;<a
class="link"
target="_blank"
rel="noreferrer"
href="https://github.com/search?q=user%3Akevinmidboe+sort%3Aupdated+planetposen&type=repositories"
>github.com</a
>
@@ -60,10 +61,6 @@
display: flex;
justify-content: space-around;
h2 {
font-size: 2.5rem;
}
section {
width: 30%;
padding: 2rem;
@@ -97,7 +94,7 @@
flex-direction: column;
padding: 3rem 0.5rem;
h2 {
h1 {
font-size: 1.8rem;
}

View File

@@ -7,7 +7,7 @@
import CheckoutButton from '$lib/components/Button.svelte';
import StripeCard from '$lib/components/StripeCard.svelte';
import ErrorStack from '$lib/components/ErrorStack.svelte';
import { cart } from '$lib/cartStore';
import { cart, subTotal } from '$lib/cartStore';
import stripeApi from '$lib/stripe/index';
import { OrderSubmitUnsuccessfullError } from '$lib/errors/OrderErrors';
import Loading from '$lib/components/loading/index.svelte';
@@ -28,6 +28,7 @@
let card: StripeCardElement;
let form: HTMLFormElement;
let errors: string[] = [];
let showExpressCheckout = false;
/* eslint-disable @typescript-eslint/no-explicit-any */
let resolvePaymentPromise: (value: any) => void;
@@ -147,13 +148,15 @@
<form class="checkout" bind:this="{form}" on:submit|preventDefault="{postOrder}">
<div class="main">
<section class="express-checkout" style="display: block;">
<h2>Hurtigkasse</h2>
{#if showExpressCheckout}
<section class="express-checkout" style="display: block;">
<h2>Hurtigkasse</h2>
<ExpressSection />
<ExpressSection />
<p style="margin: 0 0 -0.5rem 0.5rem; text-align: left; color: rgba(0,0,0,0.5);">eller</p>
</section>
<p style="margin: 0 0 -0.5rem 0.5rem; text-align: left; color: rgba(0,0,0,0.5);">eller</p>
</section>
{/if}
<section id="delivery">
<h2>Leveringsaddresse</h2>
@@ -178,7 +181,7 @@
<aside class="sidebar">
<section id="order">
<h2>Din ordre</h2>
<OrderSection />
<OrderSection lineItems="{$cart}" subTotal="{$subTotal}" />
</section>
</aside>
</form>

View File

@@ -1,6 +1,5 @@
<script lang="ts">
import Vipps from '$lib/icons/Vipps.svelte';
import ShopPay from '$lib/icons/ShopPay.svelte';
import ApplePay from '$lib/icons/ApplePay.svelte';
import PayPal from '$lib/icons/PayPal.svelte';
import GooglePay from '$lib/icons/GooglePay.svelte';

View File

@@ -1,16 +1,9 @@
<script lang="ts">
import OrderTotalSection from './OrderTotalSection.svelte';
import QuantitySelect from '$lib/components/QuantitySelect.svelte';
import type ICart from '$lib/interfaces/ICart';
import { cart, subTotal } from '$lib/cartStore';
import { decrementProductInCart, incrementProductInCart } from '$lib/websocketCart';
const shippingPrice = 75;
$: totalPrice = $subTotal + shippingPrice;
function lineItemClass(id: number) {
return `lineitem-${id}`;
}
export let lineItems: ICart[];
export let subTotal: number;
</script>
<div class="order-summary">
@@ -26,7 +19,7 @@
</thead>
<tbody data-order-summary-section="line-items">
{#each $cart as cartItem}
{#each lineItems as lineItem}
<tr
class="product"
data-product-id="6718367989809"
@@ -40,18 +33,18 @@
<img
alt="Black Googly Eye Puff Print Logo Tee - XS"
class="product-thumbnail__image"
src="{cartItem.image}"
src="{lineItem.image}"
data-src="//cdn.shopify.com/s/files/1/0023/3789/8540/products/20220718_A24_GooglyEye_Tee_Black_15991x1gray_small.jpg?v=1659020903"
/>
</div>
<span class="product-thumbnail__quantity" aria-hidden="true">{cartItem.quantity}</span
<span class="product-thumbnail__quantity" aria-hidden="true">{lineItem.quantity}</span
>
</div>
</td>
<th class="product__description" scope="row">
<span class="product__description__name order-summary__emphasis">{cartItem.name}</span>
<span class="product__description__name order-summary__emphasis">{lineItem.name}</span>
<span class="product__description__variant order-summary__small-text"
>{cartItem.size}</span
>{lineItem.size}</span
>
</th>
<td class="product__quantity">
@@ -59,7 +52,7 @@
</td>
<td class="product__price">
<p class="order-summary__emphasis skeleton-while-loading">
NOK {cartItem.quantity * cartItem.price}
NOK {lineItem.quantity * lineItem.price}
</p>
</td>
</tr>
@@ -68,7 +61,7 @@
</tbody>
</table>
<OrderTotalSection />
<OrderTotalSection subTotal="{subTotal}" />
</div>
<style lang="scss" module="scoped">

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { subTotal } from '$lib/cartStore';
export let subTotal: number;
</script>
<div class="total">
@@ -19,7 +19,7 @@
class="order-summary__emphasis skeleton-while-loading"
data-checkout-subtotal-price-target="4000"
>
Nok {$subTotal}
Nok {subTotal}
</span>
</td>
</tr>
@@ -58,7 +58,7 @@
<td class="price payment-due" data-presentment-currency="NOK">
<span class="payment-due__currency remove-while-loading">Nok</span>
<span class="price skeleton-while-loading--lg" data-checkout-payment-due-target="4000">
{$subTotal + 75}
{subTotal + 75}
</span>
</td>
</tr>

View File

@@ -62,13 +62,14 @@
<style lang="scss" module="scoped">
@import '../../styles/media-queries.scss';
@include desktop {
section {
margin: 20% 2rem;
width: 60%;
section {
max-width: 600px;
margin: auto;
@include desktop {
margin: 20% auto;
}
}
.signin-button {
margin-top: 2rem;
}

View File

@@ -6,7 +6,7 @@ export const load: PageServerLoad = async ({ fetch, params }) => {
const { id } = params;
const res = await fetch(`/api/v1/order/${id}`);
const orderResponse = await res.json();
const orderResponse: IOrderDTO = await res.json();
if (orderResponse?.success == false || orderResponse?.order === undefined) {
console.log('throwing error', orderResponse);

View File

@@ -1,5 +1,5 @@
import { redirect } from '@sveltejs/kit';
import type { Actions, PageServerLoad } from './$types';
import type { Actions } from './$types';
export const actions: Actions = {
default: async ({ request }) => {
@@ -10,8 +10,6 @@ export const actions: Actions = {
const receiptUrl = `/receipt/${orderId}?email=${email}`;
throw redirect(303, receiptUrl);
return { success: false };
}
};

View File

@@ -2,17 +2,11 @@
import { page } from '$app/stores';
import CircleCheckmark from '$lib/components/loading/CircleCheckmark.svelte';
import CircleError from '$lib/components/loading/CircleError.svelte';
import OrderSection from '../../checkout/OrderSection.svelte';
import type { PageServerData } from './$types';
import type { ILineItem, IOrder } from '$lib/interfaces/IOrder';
import type { IOrder } from '$lib/interfaces/IOrder';
import CircleWarning from '$lib/components/loading/CircleWarning.svelte';
function subTotal(lineItems: Array<ILineItem> = []) {
let total = 0;
lineItems.forEach((lineItem) => (total = total + lineItem.price * lineItem.quantity));
return total;
}
let id: string;
let email: string;
let order: IOrder;
@@ -23,6 +17,8 @@
email = data.email || (data?.order?.customer?.email as string);
order = data.order as IOrder;
}
$: subTotal = Math.round((order?.payment?.amount || 1) / 100);
</script>
<section class="order-confirmation">
@@ -49,21 +45,9 @@
</div>
<div class="order-receipt">
{#each order?.lineItems as lineItem}
<p>
<code>{lineItem.name} x{lineItem.quantity}</code>
<code>NOK {lineItem.price * lineItem.quantity}</code>
</p>
{/each}
<p>
<code>Shipping</code>
<code>NOK 75</code>
</p>
<p>
<code>Total</code>
<code>NOK {subTotal(order?.lineItems)}</code>
</p>
<div class="receipt-box">
<OrderSection lineItems="{order?.lineItems}" subTotal="{subTotal}" } />
</div>
</div>
</section>
@@ -75,30 +59,52 @@
}
.order-receipt {
background-color: #f7f7f7;
max-width: 500px;
--receipt_color: #f7f7f7;
--tearOffHeight: 8px;
background-color: var(--receipt_color);
max-width: 800px;
width: calc(100% - 4rem);
padding: 2rem;
font-family: monospace;
position: relative;
p {
margin: 0.8rem 0;
display: flex;
justify-content: space-between;
border-bottom: 1px solid lightgrey;
/* Paper background effect */
.receipt-box {
height: auto;
overflow: hidden;
padding: 1rem;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.05);
&:last-of-type {
padding-top: 1.5rem;
border-width: 2px;
}
}
code {
opacity: 0.4;
font-size: 1rem;
&:first-of-type {
font-weight: 600;
&::after {
content: '';
height: var(--tearOffHeight);
position: absolute;
left: 0;
right: 0;
bottom: calc(var(--tearOffHeight) * -1);
background-color: var(--receipt_color);
clip-path: polygon(
0% 0%,
5% 100%,
10% 0%,
15% 100%,
20% 0%,
25% 100%,
30% 0%,
35% 100%,
40% 0%,
45% 100%,
50% 0%,
55% 100%,
60% 0%,
65% 100%,
70% 0%,
75% 100%,
80% 0%,
85% 100%,
90% 0%,
95% 100%,
100% 0%
);
}
}
}

View File

@@ -4,7 +4,6 @@
import { onMount } from 'svelte';
import CircleLoading from '$lib/components/loading/CircleLoading.svelte';
import { buildApiUrl } from '$lib/utils/apiUrl';
import type { PageServerData } from './$types';
const { data } = $page;
const id = data?.id as string;
@@ -22,7 +21,7 @@
goto(url);
}
function checkOrder() {
async function checkOrder() {
const url = buildApiUrl(`/api/v1/order/${id}`);
return fetch(url)
.then((resp) => resp.json())

View File

@@ -1,5 +1,4 @@
<script lang="ts">
import ProductTile from '$lib/components/ProductTile.svelte';
import ProductVariationSelect from '$lib/components/ProductVariationSelect.svelte';
import QuantitySelect from '$lib/components/QuantitySelect.svelte';
import SizesSection from './SizesSection.svelte';
@@ -98,7 +97,7 @@
.details {
.name {
font-size: 2rem;
font-size: 2em;
}
.description {

View File

@@ -14,7 +14,7 @@
color: var(--color-text);
}
html {
body .app main {
font-size: 100%;
}
@@ -56,11 +56,11 @@ a.link {
}
h1 {
font-size: 2rem;
font-size: 2em;
}
h2 {
font-size: 1rem;
font-size: 1em;
}
.no-scroll {
@@ -104,12 +104,12 @@ button:focus:not(:focus-visible) {
}
@media screen and (min-width: 1500px) {
html {
body .app main {
font-size: 110%;
}
}
@media screen and (min-width: 2000px) {
html {
font-size: 130%;
body .app main {
font-size: 125%;
}
}