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:
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()