Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactive pricing component #153

Open
wants to merge 7 commits into
base: interactive_pricing_component
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 156 additions & 4 deletions challenges/interactive_pricing_component/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,120 @@
/>
<link rel="manifest" href="../site.webmanifest" />
<link rel="stylesheet" href="style.css" />
<script
defer
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"
></script>
</head>
<body class="m-0">
<div
class="flex h-[100vh] w-full flex-col place-content-center text-center"
<body
class="font-manrope text-grayish-blue bg-very-pale-blue m-0 box-border bg-[url('images/bg-pattern.svg')] bg-no-repeat p-0"
>
<section
class="pattern-circles mx-auto mt-16 flex flex-col justify-center bg-[url('images/pattern-circles.svg')] bg-center bg-no-repeat py-8 text-center lg:py-10"
>
<h1 class="text-dark-desaturated-blue text-2xl font-bold">
Simple, traffic-based pricing
</h1>
<p class="mt-3 px-20">
Sign-up for our 30-day trial. No credit card required.
</p>
</section>
<section
x-data="pricing"
class="mx-auto mt-10 max-h-[500px] max-w-[320px] rounded-lg bg-white text-center shadow-xl backdrop-blur-md lg:max-w-[500px]"
>
<div class="grid w-full grid-cols-1 gap-y-3 lg:grid-cols-2">
<div
class="order-first mt-8 flex items-center justify-center gap-x-2 text-sm font-extrabold"
>
<span
x-text="getPageViews(viewsArray, inputValue) + ' PAGEVIEWS'"
></span>
</div>

<div class="col-span-2 my-4 grid items-center">
<input
x-model="inputValue"
id="price-slider"
:style="{ background: colorSlider(inputValue) }"
type="range"
min="1"
max="5"
step="1"
class="range bg-light-grayish-blue-toggle mx-auto appearance-none lg:col-span-2"
/>
</div>
<div
class="order-last flex items-center justify-center gap-2 lg:-order-1 lg:mt-8"
>
<span
x-text="'$' + getPrice(monthlyRates, viewsArray, inputValue)"
class="text-dark-desaturated-blue text-3xl font-extrabold"
></span>
<span class="text-grayish-blue text-lg font-normal">/ month</span>
</div>
</div>

<div class="my-8 flex items-center justify-center gap-2 text-xs">
<span class="text-xs font-medium">Monthly Billing</span>
<a
href="#"
id="yearly-billing-toggle"
class="flex items-center justify-center"
>
<label class="relative inline-flex cursor-pointer items-center">
<input
@click="yearlyBilling = !yearlyBilling"
type="checkbox"
class="peer sr-only"
/>
<div
class="peer bg-light-grayish-blue-toggle peer-checked:bg-strong-cyan h-5 w-9 rounded-full after:absolute after:top-[2px] after:left-[2px] after:h-4 after:w-4 after:rounded-full after:border after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none"
></div>
</label>
</a>
<span class="text-xs font-medium">Yearly Billing</span>
<div
class="text-light-red bg-light-grayish-red inline rounded-3xl py-[2px] px-[4px]"
>
<span class="lg:hidden">-</span>25%
<span class="hidden lg:inline">discount</span>
</div>
</div>

<hr />

<div
class="flex flex-col items-center justify-center gap-6 text-xs lg:flex-row lg:justify-around"
>
<ul
class="mt-8 flex flex-col items-center gap-2 lg:mb-8 lg:items-start"
>
<li class="flex items-center gap-3">
<img src="images/icon-check.svg" class="h-3" /><span
>Unlimited websites</span
>
</li>
<li class="flex items-center gap-3">
<img src="images/icon-check.svg" class="h-3" /><span
>100% data ownership</span
>
</li>
<li class="flex items-center gap-3">
<img src="images/icon-check.svg" class="h-3" /><span
>Email reports</span
>
</li>
</ul>
<button
class="bg-dark-desaturated-blue text-light-grayish-blue-toggle mb-8 rounded-3xl py-3 px-10 text-xs font-extrabold active:text-white lg:mb-0 lg:h-10"
>
Start my trial
</button>
</div>
</section>

<div class="mt-12 flex w-full flex-col place-content-center text-center">
<div>
<a
class="text-optimum-blue hover:text-optimum-darkblue"
Expand All @@ -54,10 +163,53 @@
<div class="mt-3">
<a
class="text-optimum-blue hover:text-optimum-darkblue"
href="https://github.com/optimumBA/frontend_mentor_challenges/tree/interactive_pricing_component/challenges/interactive_pricing_component"
href="https://github.com/lgmfred/frontend_mentor_challenges/tree/interactive_pricing_component/challenges/interactive_pricing_component"
>Source code</a
>
</div>
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('pricing', () => ({
inputValue: '3',
yearlyBilling: false,
viewsArray: [10000, 50000, 100000, 500000, 1000000],
monthlyRates: {
10000: 8,
50000: 12,
100000: 16,
500000: 24,
1000000: 36,
},

getPageViews(viewsArray, inputValue) {
const views = viewsArray[parseInt(inputValue, 10) - 1] || 10000
if (views >= 1e6) return views / 1e6 + 'M'
if (views >= 1e3) return views / 1e3 + 'K'
return views.toString()
},

getPrice(monthlyRates, viewsArray, inputValue) {
const monthlyView =
viewsArray[parseInt(inputValue, 10) - 1] || 10000
const monthlyPrice = this.yearlyBilling
? monthlyRates[monthlyView] * 0.75
: monthlyRates[monthlyView]
return (monthlyPrice / 1).toFixed(2)
},

colorSlider(inputValue) {
let value = ((parseInt(inputValue, 10) - 1) / (5 - 1)) * 100
return (
'linear-gradient(to right, hsl(174, 77%, 80%) 0%, hsl(174, 77%, 80%) ' +
value +
'%, hsl(224, 65%, 95%) ' +
value +
'%, hsl(224, 65%, 95%) 100%)'
)
},
}))
})
</script>
</body>
</html>
45 changes: 45 additions & 0 deletions challenges/interactive_pricing_component/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@600;800&display=swap');

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
/* hsl(174, 86%, 45%) */
.range {
-webkit-appearance: none;
width: 85%;
height: 7px;
border-radius: 5px;
outline: none;
opacity: 0.7;
transition: opacity 0.2s;
}

.range::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 30px;
height: 30px;
border: 0;
background: url('images/icon-slider.svg');
background-repeat: no-repeat;
background-position: center;
background-size: 70%;
border-radius: 50%;
background-color: hsl(174, 86%, 45%);
cursor: pointer;
box-shadow: 0px 7px 10px 8px hsl(174, 77%, 80%);
}

.range::-moz-range-thumb {
width: 30px;
height: 30px;
border: 0;
background-image: url('images/icon-slider.svg');
background-repeat: no-repeat;
background-position: center;
background-size: 70%;
border-radius: 50%;
background-color: hsl(174, 86%, 45%);
cursor: pointer;
box-shadow: 0px 7px 10px 8px hsl(174, 77%, 80%);
}
}
14 changes: 14 additions & 0 deletions challenges/interactive_pricing_component/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ module.exports = {
colors: {
'optimum-blue': '#009efc',
'optimum-darkblue': '#0389e1',
'soft-cyan': 'hsl(174, 77%, 80%)',
'strong-cyan': 'hsl(174, 86%, 45%)',
'light-grayish-red': 'hsl(14, 92%, 95%)',
'light-red': 'hsl(15, 100%, 70%)',
'Pale-blue': 'hsl(226, 100%, 87%)',
white: 'hsl(0, 0%, 100%)',
'very-pale-blue': 'hsl(230, 100%, 99%)',
'light-grayish-blue-slide-bar': 'hsl(224, 65%, 95%)',
'light-grayish-blue-toggle': 'hsl(223, 50%, 87%)',
'grayish-blue': 'hsl(225, 20%, 60%)',
'dark-desaturated-blue': 'hsl(227, 35%, 25%)',
},
fontFamily: {
manrope: ['Manrope', 'sans-serif'],
},
},
},
Expand Down
Loading