mirror of
https://github.com/KevinMidboe/planetposen-frontend.git
synced 2025-10-29 13:10:12 +00:00
All sveltekit library files
This commit is contained in:
188
src/lib/components/ApplePayButton.svelte
Normal file
188
src/lib/components/ApplePayButton.svelte
Normal file
@@ -0,0 +1,188 @@
|
||||
<script lang="ts">
|
||||
function getApplePaySession(validationURL: string) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ validationURL })
|
||||
};
|
||||
|
||||
return fetch('/api/applepay/validateSession', options).then((resp) => resp.json());
|
||||
}
|
||||
|
||||
function makeApplePayPaymentTransaction(payment: object) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ payment })
|
||||
};
|
||||
|
||||
return fetch('/api/applepay/pay', options).then((resp) => resp.json());
|
||||
}
|
||||
|
||||
function createPaymentRequest() {
|
||||
const paymentRequest = {
|
||||
countryCode: 'NO',
|
||||
currencyCode: 'NOK',
|
||||
shippingMethods: [
|
||||
{
|
||||
label: 'Free Shipping',
|
||||
amount: 0.0,
|
||||
identifier: 'free',
|
||||
detail: 'Delivers in five business days'
|
||||
},
|
||||
{
|
||||
label: 'Express Shipping',
|
||||
amount: 5.0,
|
||||
identifier: 'express',
|
||||
detail: 'Delivers in two business days'
|
||||
}
|
||||
],
|
||||
lineItems: [
|
||||
{
|
||||
label: 'Shipping',
|
||||
amount: 0.0
|
||||
}
|
||||
],
|
||||
total: {
|
||||
label: 'Apple Pay Example',
|
||||
amount: 8.99
|
||||
},
|
||||
supportedNetworks: ['amex', 'discover', 'masterCard', 'visa'],
|
||||
merchantCapabilities: ['supports3DS'],
|
||||
requiredShippingContactFields: ['postalAddress', 'email']
|
||||
};
|
||||
|
||||
const session = new ApplePaySession(6, paymentRequest);
|
||||
|
||||
session.onvalidatemerchant = (event) => {
|
||||
console.log('Validate merchante');
|
||||
console.log('event: ', event);
|
||||
|
||||
const validationURL = event.validationURL;
|
||||
this.getApplePaySession(validationURL).then((response) => {
|
||||
console.log('response from getApplePaySession:', response);
|
||||
session.completeMerchantValidation(response);
|
||||
});
|
||||
};
|
||||
|
||||
session.onpaymentauthorized = (event) => {
|
||||
this.makeApplePayPaymentTransaction(event.payment).then((response) => {
|
||||
console.log('response from pay:', response);
|
||||
|
||||
if (response.approved) session.completePayment(ApplePaySession.STATUS_SUCCESS);
|
||||
else session.completePayment(ApplePaySession.STATUS_FAILURE);
|
||||
});
|
||||
};
|
||||
|
||||
session.begin();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="apple-pay-button-with-text apple-pay-button-black-with-text"
|
||||
on:click="{createPaymentRequest}"
|
||||
>
|
||||
<span class="text">Hurtigkasse med</span>
|
||||
<svg
|
||||
x="116.59"
|
||||
y="7.92"
|
||||
height="15"
|
||||
width="35"
|
||||
class="logo"
|
||||
viewBox="0 0 105 43"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<title>Apple Logo</title>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g fill="#FFF">
|
||||
<path
|
||||
d="M19.4028,5.5674 C20.6008,4.0684 21.4138,2.0564 21.1998,0.0004 C19.4458,0.0874 17.3058,1.1574 16.0668,2.6564 C14.9538,3.9414 13.9688,6.0374 14.2258,8.0074 C16.1948,8.1784 18.1618,7.0244 19.4028,5.5674"
|
||||
></path>
|
||||
<path
|
||||
d="M21.1772,8.3926 C18.3182,8.2226 15.8872,10.0156 14.5212,10.0156 C13.1552,10.0156 11.0642,8.4786 8.8022,8.5196 C5.8592,8.5626 3.1282,10.2276 1.6342,12.8746 C-1.4378,18.1696 0.8232,26.0246 3.8112,30.3376 C5.2622,32.4716 7.0102,34.8206 9.3142,34.7366 C11.4912,34.6506 12.3442,33.3266 14.9902,33.3266 C17.6352,33.3266 18.4042,34.7366 20.7082,34.6936 C23.0972,34.6506 24.5922,32.5586 26.0422,30.4226 C27.7072,27.9906 28.3882,25.6426 28.4312,25.5126 C28.3882,25.4706 23.8232,23.7186 23.7812,18.4676 C23.7382,14.0706 27.3652,11.9786 27.5362,11.8496 C25.4882,8.8196 22.2872,8.4786 21.1772,8.3926"
|
||||
></path>
|
||||
<path
|
||||
d="M85.5508,43.0381 L85.5508,39.1991 C85.8628,39.2421 86.6158,39.2871 87.0158,39.2871 C89.2138,39.2871 90.4558,38.3551 91.2108,35.9581 L91.6548,34.5371 L83.2428,11.2321 L88.4368,11.2321 L94.2958,30.1421 L94.4068,30.1421 L100.2668,11.2321 L105.3278,11.2321 L96.6048,35.7141 C94.6078,41.3291 92.3208,43.1721 87.4828,43.1721 C87.1048,43.1721 85.8838,43.1271 85.5508,43.0381"
|
||||
></path>
|
||||
<path
|
||||
d="M42.6499,19.3555 L48.3549,19.3555 C52.6829,19.3555 55.1469,17.0255 55.1469,12.9855 C55.1469,8.9455 52.6829,6.6375 48.3769,6.6375 L42.6499,6.6375 L42.6499,19.3555 Z M49.6869,2.4425 C55.9009,2.4425 60.2289,6.7265 60.2289,12.9625 C60.2289,19.2225 55.8129,23.5285 49.5309,23.5285 L42.6499,23.5285 L42.6499,34.4705 L37.6779,34.4705 L37.6779,2.4425 L49.6869,2.4425 Z"
|
||||
></path>
|
||||
<path
|
||||
d="M76.5547,25.7705 L76.5547,23.9715 L71.0287,24.3275 C67.9207,24.5275 66.3007,25.6815 66.3007,27.7015 C66.3007,29.6545 67.9887,30.9195 70.6287,30.9195 C74.0027,30.9195 76.5547,28.7665 76.5547,25.7705 M61.4617,27.8345 C61.4617,23.7285 64.5917,21.3755 70.3627,21.0205 L76.5547,20.6425 L76.5547,18.8675 C76.5547,16.2705 74.8457,14.8495 71.8057,14.8495 C69.2967,14.8495 67.4777,16.1375 67.0997,18.1125 L62.6167,18.1125 C62.7497,13.9615 66.6567,10.9435 71.9387,10.9435 C77.6207,10.9435 81.3267,13.9175 81.3267,18.5345 L81.3267,34.4705 L76.7327,34.4705 L76.7327,30.6305 L76.6217,30.6305 C75.3127,33.1395 72.4267,34.7145 69.2967,34.7145 C64.6807,34.7145 61.4617,31.9625 61.4617,27.8345"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
@supports not (-webkit-appearance: -apple-pay-button) {
|
||||
.apple-pay-button-with-text {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.apple-pay-button-with-text {
|
||||
cursor: pointer;
|
||||
--apple-pay-scale: 1; /* (height / 32) */
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 5px;
|
||||
padding: 0.75rem 1rem;
|
||||
width: fit-content;
|
||||
box-sizing: border-box;
|
||||
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.apple-pay-button-with-text,
|
||||
svg g {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.apple-pay-button-black-with-text {
|
||||
background-color: black;
|
||||
color: white;
|
||||
white-space: nowrap;
|
||||
border: 2px solid black;
|
||||
|
||||
&:hover {
|
||||
background-color: white;
|
||||
color: black;
|
||||
|
||||
g {
|
||||
fill: black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.apple-pay-button-with-text > .text {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
|
||||
'Open Sans', 'Helvetica Neue', sans-serif, Helvetica, sans-serif;
|
||||
font-size: calc(1em * var(--apple-pay-scale));
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
align-self: center;
|
||||
margin-right: calc(2px * var(--apple-pay-scale));
|
||||
}
|
||||
|
||||
.apple-pay-button-with-text > .logo {
|
||||
width: 50px;
|
||||
/*width: calc(35px * var(--scale));*/
|
||||
height: 100%;
|
||||
background-size: 100% 60%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 50%;
|
||||
margin-top: calc(2px * var(--apple-pay-scale));
|
||||
margin-left: calc(2px * var(--apple-pay-scale));
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
60
src/lib/components/Badge.svelte
Normal file
60
src/lib/components/Badge.svelte
Normal file
@@ -0,0 +1,60 @@
|
||||
<script lang="ts">
|
||||
import BadgeType from '../interfaces/BadgeType';
|
||||
|
||||
const badgeIcons = {
|
||||
[BadgeType.INFO]: '⏳',
|
||||
[BadgeType.PENDING]: '📦',
|
||||
[BadgeType.WARNING]: '⚠️',
|
||||
[BadgeType.SUCCESS]: '✓',
|
||||
[BadgeType.ERROR]: 'X'
|
||||
};
|
||||
|
||||
export let title = 'Info';
|
||||
export let type: BadgeType = BadgeType.INFO;
|
||||
export let icon: string = badgeIcons[type];
|
||||
|
||||
$: badgeClass = `badge ${type}`;
|
||||
</script>
|
||||
|
||||
<div class="{badgeClass}">
|
||||
<span>{title}</span>
|
||||
<span class="icon">{icon}</span>
|
||||
</div>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
.badge {
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 6px;
|
||||
text-align: center;
|
||||
width: fit-content;
|
||||
font-size: 0.95rem;
|
||||
background-color: rgb(235, 238, 241);
|
||||
color: rgb(84, 89, 105);
|
||||
margin: 0.2rem;
|
||||
|
||||
.icon {
|
||||
margin-left: 0.3rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
&.success {
|
||||
background-color: rgb(215, 247, 194);
|
||||
color: rgb(0, 105, 8);
|
||||
}
|
||||
|
||||
&.error {
|
||||
background-color: rgb(255, 231, 242);
|
||||
color: rgb(179, 9, 60);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background-color: rgb(252, 237, 185);
|
||||
color: rgb(168, 44, 0);
|
||||
}
|
||||
|
||||
&.pending {
|
||||
background-color: lightblue;
|
||||
color: darkslateblue;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
42
src/lib/components/Button.svelte
Normal file
42
src/lib/components/Button.svelte
Normal file
@@ -0,0 +1,42 @@
|
||||
<script lang="ts">
|
||||
export let text = 'Bestill';
|
||||
export let type: string | null = null;
|
||||
export let active = false;
|
||||
</script>
|
||||
|
||||
<button on:click type="{type}" class="{active ? 'active' : null}">{text}</button>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
button {
|
||||
webkit-font-smoothing: antialiased;
|
||||
align-items: flex-start;
|
||||
display: block;
|
||||
appearance: auto;
|
||||
background-clip: border-box;
|
||||
background-color: var(--color-theme-1);
|
||||
border: 2px solid var(--color-theme-1);
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
height: 48px;
|
||||
letter-spacing: 1.2px;
|
||||
line-height: 14px;
|
||||
margin: 0;
|
||||
|
||||
min-width: 140px;
|
||||
padding: 10px 30px;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
padding: 12px 32px;
|
||||
transform: translateX(-2px);
|
||||
background-color: white;
|
||||
color: var(--color-theme-1);
|
||||
border-color: var(--color-theme-1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
55
src/lib/components/Cart.svelte
Normal file
55
src/lib/components/Cart.svelte
Normal file
@@ -0,0 +1,55 @@
|
||||
<script lang="ts">
|
||||
import { count, toggleCart, isOpen } from '../cartStore';
|
||||
import IconCart from '../icons/IconCart.svelte';
|
||||
</script>
|
||||
|
||||
<div id="cart" class="{$isOpen && 'open'}" on:click="{() => toggleCart()}">
|
||||
{#if $count > 0}
|
||||
<span>{$count}</span>
|
||||
{/if}
|
||||
|
||||
<IconCart />
|
||||
</div>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
#cart {
|
||||
padding: 0.3rem 0.6rem;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
// background-color: #E6E0DC;
|
||||
color: #18332f;
|
||||
// border: 1px solid rgba(0,0,0,0.1);
|
||||
z-index: 99;
|
||||
transition: all 0.25s ease;
|
||||
|
||||
&:hover,
|
||||
&.open {
|
||||
cursor: pointer;
|
||||
background-color: #18332f;
|
||||
color: #e6e0dc;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
margin-right: 0.5rem;
|
||||
border: 1px solid transparent;
|
||||
|
||||
span {
|
||||
margin-right: 0.75rem;
|
||||
font-size: 1rem;
|
||||
margin-top: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
:global(#cart svg) {
|
||||
max-width: 20px;
|
||||
width: 20px;
|
||||
fill: #18332f;
|
||||
transition: fill 0.25s ease;
|
||||
}
|
||||
:global(#cart:hover svg, #cart.open svg) {
|
||||
fill: #e6e0dc;
|
||||
}
|
||||
</style>
|
||||
64
src/lib/components/FrontText.svelte
Normal file
64
src/lib/components/FrontText.svelte
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import type IFrontText from '$lib/interfaces/IFrontText';
|
||||
export let data: IFrontText;
|
||||
</script>
|
||||
|
||||
<div class="text-container">
|
||||
<blockquote style="{`color: ${data.color || 'black'}`}">
|
||||
<p class="title">{data.title}</p>
|
||||
<p class="text">{data.text}</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
@import '../../styles/media-queries.scss';
|
||||
|
||||
.text-container {
|
||||
position: relative;
|
||||
|
||||
blockquote {
|
||||
max-width: 75%;
|
||||
margin: 12.5%;
|
||||
padding: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
@include mobile {
|
||||
margin: 10% 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 1.3rem;
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
@include desktop {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
text-align: center;
|
||||
font-size: 2rem;
|
||||
margin-top: 0;
|
||||
|
||||
@include desktop {
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '\201C';
|
||||
position: relative;
|
||||
left: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '\201D';
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
78
src/lib/components/FrontTextImage.svelte
Normal file
78
src/lib/components/FrontTextImage.svelte
Normal file
@@ -0,0 +1,78 @@
|
||||
<script lang="ts">
|
||||
import type IFrontTextImage from '$lib/interfaces/IFrontTextImage';
|
||||
export let data: IFrontTextImage;
|
||||
</script>
|
||||
|
||||
<div class="parallax-container">
|
||||
<div class="image-layout" style="{data?.imageRight && 'order: 1'}">
|
||||
<img src="{data?.image}" alt="mushroom" />
|
||||
</div>
|
||||
|
||||
<div class="text-container">
|
||||
<h2>{data?.title}</h2>
|
||||
|
||||
<span>{data?.text}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../styles/media-queries.scss';
|
||||
|
||||
.parallax-container {
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
// height: 75vh;
|
||||
min-height: 800px;
|
||||
|
||||
place-items: center;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
@include desktop {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
padding: 0 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.image-layout {
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.text-container {
|
||||
-webkit-box-flex: 0;
|
||||
box-sizing: border-box;
|
||||
color: rgb(0, 0, 0);
|
||||
display: block;
|
||||
flex-basis: 75%;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
font-size: 23px;
|
||||
font-weight: 400;
|
||||
line-height: 31.999903px;
|
||||
padding-left: 1rem;
|
||||
|
||||
h2 {
|
||||
font-size: 3rem;
|
||||
line-height: 1;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
|
||||
@include desktop {
|
||||
margin-left: 99.3125px;
|
||||
width: 595.875px;
|
||||
max-width: 75%;
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
98
src/lib/components/FrontTextImageBubble.svelte
Normal file
98
src/lib/components/FrontTextImageBubble.svelte
Normal file
@@ -0,0 +1,98 @@
|
||||
<section>
|
||||
<div class="text-part">
|
||||
<h2>Å stoppe tapet av biologisk mangfold globalt</h2>
|
||||
<p>
|
||||
En million arter av dyr, planter og sopp er nå truet med utryddelse. Biomangfold er viktig for
|
||||
alt liv på jorden fordi det bidrar til stabile økosystemer. Naturmangfoldet kan bevares
|
||||
gjennom mer kunnskap og vern.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="image-part">
|
||||
<div class="image-mask">
|
||||
<img src="https://i.imgur.com/WWbfhiZ.jpg" alt="bee inspection" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
@import '../../styles/media-queries.scss';
|
||||
|
||||
section {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin: 40% 2rem;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
@include tablet {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 10%;
|
||||
margin: 20% 2rem;
|
||||
|
||||
.text-part {
|
||||
max-width: 480px;
|
||||
justify-self: end;
|
||||
|
||||
h2 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.image-part {
|
||||
width: 100%;
|
||||
justify-self: start !important;
|
||||
max-width: calc(100vw / 3) !important;
|
||||
max-height: calc(100vw / 3) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.text-part {
|
||||
text-align: center;
|
||||
padding: 0 1rem;
|
||||
|
||||
h2 {
|
||||
font-size: 2.25rem;
|
||||
margin-bottom: 2.25rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.image-part {
|
||||
position: relative;
|
||||
height: 80vw;
|
||||
max-width: 80vw;
|
||||
width: 100%;
|
||||
justify-self: center;
|
||||
|
||||
.image-mask {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhCAAFAPUAAHmAR4OKUIOJUo2SW46VWY+TYZeeYZecZJicaZyecZ6kZ5+ka6GobKGkcaOpcKKocqSpcaeqdqitdaSmeKanfqmueauueqqsfamufK2xfq2uhK2wgK+ygq6zgq+zha+0ha+1h7CzhbGyhrKzhrC0hLG1h7G3irK3igAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAAIf8LSW1hZ2VNYWdpY2sOZ2FtbWE9MC45MDkwOTEALAAAAAAIAAUAAAYlQBPIExqJNJRTicTZXCaJTydjiTQQBUxFAlkcBoKHg6EwEAKAIAA7);
|
||||
|
||||
background-size: cover;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: cover;
|
||||
mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjgwIiBoZWlnaHQ9IjY4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNjQzLjMzIDE3Ni43NzRjNDkuMjQyIDE0MC4zMiA2NC41MzQgMzM3LjI1NC01NS4yMTYgNDE4LjI4LTExOS43NDkgODEuMDI3LTM2MC4zNTMgMTAyLjk4NC00OTguNjE4LTQuODg4cy05NS4wODgtNDAwLjkyNS0xMi44Mi00ODMuOWM4Mi4yNjgtODIuOTc1IDI0NS4wOTQtNzUuNTQ0IDMyMy4zNS04Ni45OUM0NzguMjgzIDcuODMgNTk0LjA5IDM2LjQ1NCA2NDMuMzMgMTc2Ljc3NHoiLz48L3N2Zz4=');
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
61
src/lib/components/Input.svelte
Normal file
61
src/lib/components/Input.svelte
Normal file
@@ -0,0 +1,61 @@
|
||||
<script lang="ts">
|
||||
export let id: string | null = null;
|
||||
export let label: string;
|
||||
export let value: string | number;
|
||||
export let type = 'text';
|
||||
export let name: string | null = null;
|
||||
export let required = true;
|
||||
export let autocomplete: string | null = null;
|
||||
export let autocapitalize: string | null = null;
|
||||
|
||||
function typeAction(node: HTMLInputElement) {
|
||||
node.type = type;
|
||||
}
|
||||
</script>
|
||||
|
||||
<label id="{id}" class="{required ? 'required' : null}">
|
||||
<span>{label}</span>
|
||||
<input
|
||||
bind:value="{value}"
|
||||
name="{name || id}"
|
||||
use:typeAction
|
||||
required="{required}"
|
||||
autocomplete="{autocomplete}"
|
||||
autocapitalize="{autocapitalize}"
|
||||
enterkeyhint="next"
|
||||
/>
|
||||
</label>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
span {
|
||||
margin-left: 2px;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
&.required span::after {
|
||||
content: '*';
|
||||
color: #e02b27;
|
||||
font-size: 1rem;
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
border: 2px solid grey;
|
||||
border-radius: 0px;
|
||||
padding: 0.5rem;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:valid {
|
||||
border-color: var(--text-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
15
src/lib/components/LinkArrow.svelte
Normal file
15
src/lib/components/LinkArrow.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg
|
||||
class="inline-block relative -top-1 w-10 h-10 mr-8 -stroke-green-boulogne"
|
||||
width="8"
|
||||
height="8"
|
||||
viewBox="0 0 8 8"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||
<g stroke="#8BA17F">
|
||||
<path
|
||||
d="M4.534.93a.189.189 0 000 .267l2.614 2.614H.397a.189.189 0 100 .378h6.75l-2.88 2.88a.189.189 0 10.267.268l3.203-3.204a.189.189 0 000-.266L4.801.93a.189.189 0 00-.267 0"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 482 B |
69
src/lib/components/ProductVariationSelect.svelte
Normal file
69
src/lib/components/ProductVariationSelect.svelte
Normal file
@@ -0,0 +1,69 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import type IProductVariation from '$lib/interfaces/IProductVariation';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let variations: IProductVariation[];
|
||||
let selectedVariation: IProductVariation;
|
||||
|
||||
function defaultVariationIndex(variations: IProductVariation[]) {
|
||||
return variations.findIndex((variation) => variation?.default_price || false);
|
||||
}
|
||||
|
||||
function emitSelectedVariation(_selectedVariation: IProductVariation) {
|
||||
selectedVariation = _selectedVariation;
|
||||
dispatch('selected', _selectedVariation);
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if (!variations) return;
|
||||
|
||||
const defaultVariation = variations[defaultVariationIndex(variations) || 0];
|
||||
emitSelectedVariation(defaultVariation);
|
||||
});
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
{#each variations as variation}
|
||||
<li
|
||||
class="{`variation ${variation.sku_id === selectedVariation?.sku_id && 'selected'}`}"
|
||||
on:click="{() => emitSelectedVariation(variation)}"
|
||||
>
|
||||
<span>Størrelse: {variation.size}</span>
|
||||
<span>NOK {variation.price}</span>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<style lang="scss">
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
|
||||
max-width: 400px;
|
||||
|
||||
li.variation {
|
||||
padding: 1rem 1rem;
|
||||
margin: 0.5rem 0;
|
||||
border: 2px solid rgba(0, 0, 0, 0.3);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
transition: all 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
137
src/lib/components/QuantitySelect.svelte
Normal file
137
src/lib/components/QuantitySelect.svelte
Normal file
@@ -0,0 +1,137 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function increment() {
|
||||
if (value >= Number(input?.max)) return;
|
||||
value = value + 1;
|
||||
dispatch('increment');
|
||||
}
|
||||
|
||||
function decrement() {
|
||||
if (value <= 1) return;
|
||||
|
||||
value = value - 1;
|
||||
dispatch('decrement');
|
||||
}
|
||||
|
||||
export let value: number;
|
||||
export let disabled = false;
|
||||
export let hideButtons = false;
|
||||
export let small = false;
|
||||
let max = 50;
|
||||
let input: HTMLInputElement;
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="{`quantity-picker ${hideButtons ? 'hide-buttons' : null} ${small ? 'small' : null} ${
|
||||
disabled ? 'disabled' : null
|
||||
}`}"
|
||||
>
|
||||
<span class="button" on:click="{decrement}">-</span>
|
||||
<input
|
||||
bind:this="{input}"
|
||||
type="number"
|
||||
bind:value="{value}"
|
||||
on:input
|
||||
disabled="{disabled}"
|
||||
min="1"
|
||||
max="{max}"
|
||||
/>
|
||||
<span class="button" on:click="{increment}">+</span>
|
||||
</div>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
@import '../../styles/media-queries.scss';
|
||||
|
||||
.quantity-picker {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: max-content;
|
||||
height: 2.5rem;
|
||||
border: 2px solid grey;
|
||||
font-size: 1.5rem;
|
||||
|
||||
&.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@include mobile {
|
||||
height: 2.5rem;
|
||||
font-size: 1.2rem;
|
||||
line-height: 0;
|
||||
|
||||
.button {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide-buttons {
|
||||
@include mobile {
|
||||
.button {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include mobile {
|
||||
&.small {
|
||||
height: 1.75rem;
|
||||
|
||||
.button {
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
input {
|
||||
font-size: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border: unset;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
align-items: center;
|
||||
touch-action: manipulation;
|
||||
|
||||
&:hover {
|
||||
border: 2px solid #000;
|
||||
margin-left: -2px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
max-width: 1.5rem;
|
||||
text-align: center;
|
||||
-webkit-appearance: none;
|
||||
border: none;
|
||||
padding: 0 0.5rem;
|
||||
font-size: 1.1rem;
|
||||
background-color: inherit;
|
||||
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
&[type='number'] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
114
src/lib/components/StripeCard.svelte
Normal file
114
src/lib/components/StripeCard.svelte
Normal file
@@ -0,0 +1,114 @@
|
||||
<script lang="ts">
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { loadStripe } from '@stripe/stripe-js/pure';
|
||||
import type { Stripe } from '@stripe/stripe-js';
|
||||
import { cart } from '../cartStore';
|
||||
|
||||
function mountCard() {
|
||||
const elements = stripe.elements();
|
||||
|
||||
const options = {
|
||||
hidePostalCode: true,
|
||||
style: {
|
||||
base: {
|
||||
color: '#32325d',
|
||||
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
|
||||
fontSmoothing: 'antialiased',
|
||||
fontSize: '18px',
|
||||
'::placeholder': {
|
||||
color: '#aab7c4'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
card = elements.create('card', options);
|
||||
|
||||
card.mount(cardElement);
|
||||
}
|
||||
|
||||
// function makeIntent() {
|
||||
// let url = "/api/payment/stripe";
|
||||
// if (window.location.href.includes("localhost"))
|
||||
// url = "http://localhost:30010".concat(url);
|
||||
|
||||
// fetch(url, {
|
||||
// method: "POST",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// },
|
||||
// body: JSON.stringify({
|
||||
// cart: $cart
|
||||
// })
|
||||
// })
|
||||
// .then((resp) => resp.json())
|
||||
// .then((data) => (clientSecret = data.paymentIntent.clientSecret));
|
||||
// }
|
||||
|
||||
function pay() {
|
||||
stripe
|
||||
.confirmCardPayment(clientSecret, {
|
||||
payment_method: {
|
||||
card,
|
||||
billing_details: {
|
||||
name: 'Kevin Testost'
|
||||
}
|
||||
}
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.error) {
|
||||
confirmDiag.innerText = result.error.message || 'Unexpected payment ERROR!';
|
||||
} else {
|
||||
if (result.paymentIntent.status === 'succeeded') {
|
||||
confirmDiag.innerText = 'Confirmed transaction!';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function initStripe() {
|
||||
window.addEventListener('submit-stripe-payment', pay, false);
|
||||
|
||||
loadStripe.setLoadParameters({ advancedFraudSignals: false });
|
||||
stripe = await loadStripe('pk_test_YiU5HewgBoClZCwHdhXhTxUn');
|
||||
mountCard();
|
||||
// makeIntent();
|
||||
}
|
||||
|
||||
onMount(() => initStripe());
|
||||
// onDestroy(() => window.removeEventListener('submit-stripe-payment', null))
|
||||
|
||||
let stripe: Stripe;
|
||||
let card;
|
||||
let cardElement: HTMLElement;
|
||||
let clientSecret: string;
|
||||
let confirmDiag: HTMLElement;
|
||||
</script>
|
||||
|
||||
<div class="card">
|
||||
<div bind:this="{cardElement}"></div>
|
||||
</div>
|
||||
|
||||
<div class="stripe-feedback" bind:this="{confirmDiag}"></div>
|
||||
|
||||
<style lang="scss" module="scoped">
|
||||
@import '../../styles/media-queries.scss';
|
||||
|
||||
.card {
|
||||
// padding: 1rem;
|
||||
margin: 0 0.5rem;
|
||||
border: 2px solid black;
|
||||
|
||||
@include desktop {
|
||||
max-width: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
.stripe-feedback {
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
:global(.card .StripeElement) {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
48
src/lib/components/VippsHurtigkasse.svelte
Normal file
48
src/lib/components/VippsHurtigkasse.svelte
Normal file
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div aria-role="button" on:click>
|
||||
<svg fill="none" height="44" viewBox="0 0 250 44" width="250" xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
d="m0 8c0-2.80026 0-4.20039.544967-5.26995.479363-.94081 1.244273-1.70572 2.185083-2.185083 1.06956-.544967 2.46969-.544967 5.26995-.544967h234c2.8 0 4.2 0 5.27.544967.941.479363 1.706 1.244273 2.185 2.185083.545 1.06956.545 2.46969.545 5.26995v28c0 2.8003 0 4.2004-.545 5.27-.479.9408-1.244 1.7057-2.185 2.185-1.07.545-2.47.545-5.27.545h-234c-2.80026 0-4.20039 0-5.26995-.545-.94081-.4793-1.70572-1.2442-2.185083-2.185-.544967-1.0696-.544967-2.4697-.544967-5.27z"
|
||||
fill="#ff5b24"></path><g fill="#fff"
|
||||
><path
|
||||
clip-rule="evenodd"
|
||||
d="m100.25 20.0884c-.7202-2.7477-2.4686-3.8384-4.8553-3.8384-1.9336 0-4.3605 1.0907-4.3605 3.7172 0 1.6968 1.1723 3.0304 3.0852 3.374l1.8103.323c1.2344.2221 1.5842.6869 1.5842 1.3132 0 .7071-.7612 1.111-1.8926 1.111-1.4809 0-2.4067-.5252-2.5508-2.0001l-2.6124.4042c.4112 2.8483 2.9619 4.0204 5.2658 4.0204 2.1808 0 4.5051-1.2528 4.5051-3.778 0-1.7174-1.0492-2.9696-3.0034-3.3337l-1.9951-.3633c-1.1111-.202-1.4812-.7475-1.4812-1.2727 0-.6668.7198-1.0907 1.7073-1.0907 1.255 0 2.1395.4239 2.1806 1.8179zm-58.075 4.3229 2.7149-7.8584h3.1884l-4.7314 11.6565h-2.3654l-4.7315-11.6563h3.1884zm16.6834-4.5249c0 .9292-.7406 1.5756-1.6047 1.5756-.864 0-1.6043-.6464-1.6043-1.5756 0-.9294.7403-1.5756 1.6043-1.5756.8641 0 1.6049.6462 1.6049 1.5756zm.4936 4.1213c-1.0699 1.3734-2.2013 2.3229-4.1967 2.323-2.036 0-3.6204-1.2121-4.8546-2.9897-.4939-.7275-1.255-.889-1.8105-.5051-.5142.3637-.6374 1.1314-.1645 1.7982 1.7073 2.5656 4.0729 4.0602 6.8294 4.0602 2.5305 0 4.5055-1.2119 6.0481-3.2322.5759-.7473.5553-1.515 0-1.9393-.5144-.4044-1.2755-.2624-1.8512.4849zm7.098-1.6568c0 2.384 1.3989 3.6367 2.9625 3.6367 1.4809 0 3.0034-1.1719 3.0034-3.6367 0-2.4244-1.5225-3.5959-2.9831-3.5959-1.5839 0-2.9828 1.1111-2.9828 3.5959zm0-4.1815v-1.5964h-2.9004v15.677h2.9004v-5.576c.9669 1.2932 2.2217 1.8389 3.6409 1.8389 2.6541 0 5.2459-2.0608 5.2459-6.3031 0-4.061-2.6948-5.9596-4.9989-5.9596-1.8309 0-3.0855.8281-3.8879 1.9192zm13.9275 4.1815c0 2.384 1.3987 3.6367 2.9623 3.6367 1.4809 0 3.0032-1.1719 3.0032-3.6367 0-2.4244-1.5223-3.5959-2.9828-3.5959-1.584 0-2.9829 1.1111-2.9829 3.5959zm0-4.1815v-1.5964h-.0002-2.9004v15.677h2.9004v-5.576c.967 1.2932 2.2217 1.8389 3.641 1.8389 2.6539 0 5.2459-2.0608 5.2459-6.3031 0-4.061-2.6948-5.9596-4.999-5.9596-1.8309 0-3.0854.8281-3.8877 1.9192z"
|
||||
fill-rule="evenodd"></path><path
|
||||
d="m118.384 28.25v-13.0349h-2.321v5.4199h-6.342v-5.4199h-2.33v13.0349h2.33v-5.6548h6.342v5.6548zm11.39-9.8733h-2.24v5.7542c0 1.4904-.795 2.3938-2.25 2.3938-1.337 0-1.96-.7408-1.96-2.2764v-5.8716h-2.24v6.4136c0 2.3125 1.265 3.6584 3.424 3.6584 1.508 0 2.475-.6413 2.953-1.7705h.154v1.5718h2.159zm2.546 9.8733h2.24v-5.7361c0-1.3911 1.012-2.2944 2.466-2.2944.38 0 .976.0632 1.147.1264v-2.0415c-.207-.0542-.605-.0903-.93-.0903-1.274 0-2.34.7227-2.611 1.6983h-.153v-1.5357h-2.159zm8.662-12.2942v2.4841h-1.563v1.7434h1.563v5.4471c0 1.906.903 2.6648 3.17 2.6648.434 0 .849-.0362 1.175-.0994v-1.7163c-.271.0271-.443.0452-.759.0452-.94 0-1.355-.4427-1.355-1.4273v-4.9141h2.114v-1.7434h-2.114v-2.4841zm7.523.7678c.741 0 1.346-.5871 1.346-1.3278 0-.7317-.605-1.3279-1.346-1.3279-.732 0-1.337.5962-1.337 1.3279 0 .7407.605 1.3278 1.337 1.3278zm-1.111 11.5264h2.231v-9.8733h-2.231zm9.059 3.7578c2.881 0 4.706-1.4363 4.706-3.7036v-9.9275h-2.159v1.5808h-.153c-.542-1.0749-1.717-1.7434-3.063-1.7434-2.52 0-4.083 1.9692-4.083 4.9954 0 2.9629 1.554 4.896 4.047 4.896 1.373 0 2.448-.5782 3.017-1.6441h.154v1.8789c0 1.2556-.894 1.9964-2.43 1.9964-1.229 0-2.023-.4427-2.168-1.1382h-2.249c.18 1.6982 1.843 2.8093 4.381 2.8093zm0-5.6819c-1.563 0-2.448-1.2104-2.448-3.1255 0-1.906.885-3.1164 2.448-3.1164 1.554 0 2.502 1.2104 2.502 3.1255 0 1.906-.939 3.1164-2.502 3.1164zm9.745-3.9023h-.153v-7.8679h-2.24v13.6943h2.24v-3.4688l.795-.7949 3.17 4.2637h2.71l-4.209-5.6367 3.938-4.2366h-2.601zm10.442 5.989c1.291 0 2.375-.5601 2.926-1.5176h.154v1.355h2.159v-6.7478c0-2.0867-1.427-3.3152-3.966-3.3152-2.348 0-3.983 1.1021-4.164 2.8274h2.114c.207-.6775.912-1.0478 1.942-1.0478 1.21 0 1.861.551 1.861 1.5356v.8491l-2.548.1536c-2.403.1355-3.748 1.1743-3.748 2.9448 0 1.8066 1.364 2.9629 3.27 2.9629zm.659-1.7253c-.994 0-1.707-.4969-1.707-1.346 0-.822.587-1.2827 1.842-1.364l2.232-.1536v.804c0 1.1743-1.012 2.0596-2.367 2.0596zm6.855-5.4922c0 1.4814.894 2.3486 2.791 2.7822l1.753.4065c.939.2168 1.364.5781 1.364 1.1382 0 .7497-.786 1.2646-1.915 1.2646-1.121 0-1.816-.4516-2.033-1.1833h-2.213c.172 1.7795 1.725 2.8454 4.191 2.8454s4.21-1.2556 4.21-3.1435c0-1.4544-.876-2.2583-2.764-2.6919l-1.744-.3884c-.993-.2349-1.463-.5872-1.463-1.1473 0-.7317.768-1.2285 1.788-1.2285 1.048 0 1.708.4517 1.87 1.1472h2.105c-.163-1.7795-1.635-2.8093-3.984-2.8093-2.33 0-3.956 1.2376-3.956 3.0081zm9.809 0c0 1.4814.894 2.3486 2.791 2.7822l1.752.4065c.94.2168 1.364.5781 1.364 1.1382 0 .7497-.785 1.2646-1.915 1.2646-1.12 0-1.815-.4516-2.032-1.1833h-2.213c.171 1.7795 1.725 2.8454 4.191 2.8454s4.21-1.2556 4.21-3.1435c0-1.4544-.877-2.2583-2.765-2.6919l-1.743-.3884c-.994-.2349-1.463-.5872-1.463-1.1473 0-.7317.768-1.2285 1.788-1.2285 1.048 0 1.708.4517 1.87 1.1472h2.105c-.163-1.7795-1.635-2.8093-3.984-2.8093-2.33 0-3.956 1.2376-3.956 3.0081zm16.656 4.354c-.326.7407-1.093 1.1562-2.204 1.1562-1.473 0-2.421-1.0478-2.476-2.719v-.1174h6.902v-.7136c0-3.0984-1.689-4.9683-4.508-4.9683-2.863 0-4.643 1.9963-4.643 5.167 0 3.1616 1.753 5.0947 4.661 5.0947 2.331 0 3.984-1.1201 4.39-2.8996zm-2.295-5.6187c1.346 0 2.231.9485 2.277 2.448h-4.653c.1-1.4814 1.039-2.448 2.376-2.448z"
|
||||
></path></g
|
||||
></svg
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
div {
|
||||
display: inline-block;
|
||||
width: max-content;
|
||||
height: 44px;
|
||||
border-radius: 7px;
|
||||
cursor: pointer;
|
||||
border: 2px solid #ff5b24;
|
||||
background-color: #ff5b24;
|
||||
|
||||
path {
|
||||
transition: all 0.3s ease;
|
||||
fill: #ff5b24;
|
||||
}
|
||||
|
||||
g path {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
path {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
g,
|
||||
g path {
|
||||
fill: #ff5b24;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user