www.spaceplanner.app

Web client to the spaceplanner API
git clone git://jacobedwards.org/www.spaceplanner.app
Log | Files | Refs

commit e4ddee6b7fb504fa68c51ee47ed76fe1fa5197b6
parent 9b9921fd11d264285c3bfebeb621e4a084d5181f
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Fri, 30 Aug 2024 18:20:39 -0700

Add services page

This lists the services provided and their prices, and provides a
link to the checkout page (provided by the api, provided by Stripe's
api, and hosted by Stripe).

Diffstat:
Afiles/services/index.html | 10++++++++++
Afiles/services/main.css | 27+++++++++++++++++++++++++++
Afiles/services/main.js | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/files/services/index.html b/files/services/index.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<head> + <title>Spaceplanner - Services</title> + <link rel="stylesheet" type="text/css" href="/css/main.css"> + <link rel="stylesheet" type="text/css" href="./main.css"> + <script type="module" src="./main.js"></script> +</head> +<html> + <form id="services"><legend><h1>Services</h1></legend></form> +</html> diff --git a/files/services/main.css b/files/services/main.css @@ -0,0 +1,27 @@ +#services { + max-width: 50vw; + min-width: min(40em, 70vw); + min-height: 60%; + border: thin ridge grey; + border-radius: .25em; + padding: 2em; +} + +#services > legend { + text-align: center; +} + +.service { + border: thin ridge grey; + border-radius: .25em; + padding: 2em; + margin: 1em 0; +} + +.service > .name { + font-size: xx-large; +} + +.service > .price { + font-size: x-large; +} diff --git a/files/services/main.js b/files/services/main.js @@ -0,0 +1,78 @@ +import * as etc from "/lib/etc.js" +import * as api from "/lib/api.js" + +function main() { + api.fetch("GET", "services") + .then(function(services) { + console.warn(services) + for (let service in services) { + addService(services[service]) + } + }) +} + +function chooseService(service) { + console.log("Choose service", service.id) + + if (!api.logged_in()) { + window.location.href = "/register" + } + + api.fetch("POST", "users/" + localStorage.getItem("username") + "/services/checkout", + { prices: [ service.prices[0].id ] }).then(function(body) { + console.warn(body) + window.location.href = body.url + }) + .catch(function(err) { + console.error("Unable to checkout:", err) + etc.error("There was an unexpected error.") + }) +} + +function addService(service) { + let container = document.createElement("div") + container.classList.add("service") + + let info = container + + let button = document.createElement("input") + button.setAttribute("type", "button") + button.setAttribute("value", "Choose " + service.name) + button.addEventListener("click", function() { chooseService(service) }) + + let name = info.appendChild(document.createElement("span")) + name.classList.add("name") + name.appendChild(document.createTextNode(service.name)) + + info.appendChild(document.createTextNode(" ")) + + let price = info.appendChild(document.createElement("span")) + price.classList.add("price") + price.appendChild(document.createTextNode(costDuration(service.prices[0]))) + + if (service.description != null) { + let desc = info.appendChild(document.createElement("p")) + desc.appendChild(document.createTextNode(service.description)) + desc.classList.add("description") + } + + container.appendChild(button) + document.getElementById("services") + .appendChild(container) +} + +function costDuration(price) { + return "$" + String(price.amount / 100) + "/" + durationString(price) +} + +function durationString(price) { + if (price.interval != "month") { + throw new Error("Expecting month") + } + if (price.intervalCount === 1) { + return "mo" + } + return String(price.intervalCount) + "mo" +} + +main()