adding stripe section, parts of dashboard
7
db/comalyr.svg
Normal file
|
After Width: | Height: | Size: 554 KiB |
@@ -3,6 +3,7 @@ import chalk from 'chalk';
|
||||
import path from 'path';
|
||||
|
||||
import Titles from "./model/Titles.js"
|
||||
import Networks from "./model/Networks.js"
|
||||
import Members from './model/Members.js'
|
||||
import Tokens from './model/Tokens.js'
|
||||
import Payments from "./model/Payments.js"
|
||||
@@ -12,6 +13,7 @@ import Messages from "./model/Messages/Messages.js"
|
||||
|
||||
export default class Database {
|
||||
titles = new Titles()
|
||||
networks = new Networks()
|
||||
members = new Members()
|
||||
tokens = new Tokens()
|
||||
payments = new Payments()
|
||||
@@ -20,8 +22,9 @@ export default class Database {
|
||||
messages = new Messages()
|
||||
|
||||
fromID = {
|
||||
"HY": this.titles,
|
||||
"MEMBER": this.members,
|
||||
"NETWORK": this.networks,
|
||||
"TITLE": this.titles,
|
||||
"TOKEN": this.tokens,
|
||||
"PAYMENT": this.payments,
|
||||
"POST": this.posts,
|
||||
|
||||
@@ -22,6 +22,7 @@ export default class Members extends OrderedObject {
|
||||
),
|
||||
joined: z.string(),
|
||||
address: this.addressSchema,
|
||||
networks: z.array(z.number())
|
||||
})
|
||||
|
||||
isHashed = (s) => {return s.startsWith("$argon2")}
|
||||
|
||||
39
server/db/model/Networks.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import OrderedObject from "./OrderedObject.js"
|
||||
import { z } from 'zod';
|
||||
|
||||
export default class Networks extends OrderedObject {
|
||||
prefix = `NETWORK`
|
||||
|
||||
schema = z.object({
|
||||
id: z.number(),
|
||||
name: z.string(),
|
||||
})
|
||||
|
||||
save(n) {
|
||||
let id = `${this.prefix}-${n.id}`
|
||||
let result = this.schema.safeParse(n)
|
||||
if(result.success) {
|
||||
try {
|
||||
super.add(id, n)
|
||||
} catch(e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
console.error(result.error)
|
||||
throw new global.ServerError(400, "Invalid Member Data!");
|
||||
}
|
||||
}
|
||||
|
||||
add(n) {
|
||||
let toSave = {
|
||||
id: this.entries.length+1,
|
||||
...n
|
||||
}
|
||||
this.save(toSave)
|
||||
}
|
||||
|
||||
get(id) {
|
||||
return this.entries[this.ids[`${this.prefix}-${id}`]]
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ class Server {
|
||||
|
||||
registerRoutes(router) {
|
||||
/* Stripe */
|
||||
router.post("/create-checkout-session", PaymentsHandler.danceTicket)
|
||||
router.post("/create-checkout-session", PaymentsHandler.newSubscription)
|
||||
router.post("/webhook", express.raw({ type: "application/json" }), PaymentsHandler.webhook)
|
||||
|
||||
/* Auth */
|
||||
@@ -33,7 +33,6 @@ class Server {
|
||||
router.get('/signout', this.auth.logout)
|
||||
|
||||
/* Site */
|
||||
router.get('/signup', this.verifyToken, this.get)
|
||||
router.post('/signup', this.verifyToken, this.newUserSubmission)
|
||||
router.get('/db/images/*', this.getUserImage)
|
||||
router.get('/*', this.get)
|
||||
|
||||
@@ -6,22 +6,22 @@ const stripe = new Stripe(process.env.STRIPE_SECRET);
|
||||
|
||||
export default class PaymentsHandler {
|
||||
|
||||
static async danceTicket(req, res) {
|
||||
static async newSubscription(req, res) {
|
||||
try {
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
mode: "payment",
|
||||
payment_method_types: ["card"],
|
||||
metadata: {
|
||||
productId: "austin_winter_ball_2025_ticket"
|
||||
productId: "50_month_sub"
|
||||
},
|
||||
line_items: [
|
||||
{
|
||||
price_data: {
|
||||
currency: "usd",
|
||||
product_data: {
|
||||
name: "Hyperia Winter Ball"
|
||||
name: "Monthly Subscription"
|
||||
},
|
||||
unit_amount: 3500
|
||||
unit_amount: 5000
|
||||
},
|
||||
quantity: 1
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
--gold: #FEBA7D;
|
||||
--divider: #bb7c36;
|
||||
--green: #0857265c;
|
||||
--red: #E84343;
|
||||
--red: #CE0000;
|
||||
--redorange: #ff2e00;
|
||||
--brown: #812A18;
|
||||
--darkbrown: #3f0808;
|
||||
|
||||
@@ -14,12 +15,18 @@
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--main: var(--brown);
|
||||
--accent: var(--gold);
|
||||
--main: #000000;
|
||||
--accent: #453C33;
|
||||
--accent2: var(--gold);
|
||||
}
|
||||
}
|
||||
|
||||
:root.red {
|
||||
--main: var(--red);
|
||||
--accent: #6a0000;
|
||||
--accent2: var(--green);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Canterbury';
|
||||
src: url('/_/fonts/Canterbury/Canterbury.ttf') format('truetype');
|
||||
@@ -84,6 +91,7 @@ a:active {
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: inherit;
|
||||
background-color: transparent;
|
||||
color: var(--accent);
|
||||
padding: 0.5em;
|
||||
@@ -102,6 +110,7 @@ input {
|
||||
}
|
||||
|
||||
input::placeholder {
|
||||
font-family: "Nanum";
|
||||
color: var(--accent)
|
||||
}
|
||||
|
||||
|
||||
9
ui/_/icons/forum.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="31" height="31" viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M24.875 8H6.125V30.5H24.875V8Z" stroke="black" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M30.5 0.5H0.5V4.25038H30.5V0.5Z" stroke="black" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M27.6871 4.25H3.3125V8H27.6871V4.25Z" stroke="black" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11 10.5V18.9379V27.3757" stroke="black" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M14 10.5V27.3757" stroke="black" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M17 10.5V27.3757" stroke="black" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M20 10.5V27.3757" stroke="black" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 958 B |
4
ui/_/icons/house.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="27" viewBox="0 0 24 27" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.5 8.95052V25.6172H23.5V8.95052L12 0.617188L0.5 8.95052Z" stroke="#4C0B00"/>
|
||||
<path d="M15.8385 25.6169V15.2002H8.17188V25.6169" stroke="#4C0B00"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 261 B |
11
ui/_/icons/nodes.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="30" height="28" viewBox="0 0 30 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="14.5" cy="14.5" r="6" stroke="black"/>
|
||||
<circle cx="26.5" cy="3.5" r="3" stroke="black"/>
|
||||
<circle cx="8.5" cy="3.5" r="3" stroke="black"/>
|
||||
<circle cx="3.5" cy="19.5" r="3" stroke="black"/>
|
||||
<circle cx="26.5" cy="24.5" r="3" stroke="black"/>
|
||||
<rect x="19.3531" y="10.04" width="6.20598" height="0.5" transform="rotate(-42 19.3531 10.04)" fill="black" stroke="black" stroke-width="0.5"/>
|
||||
<rect x="11.5018" y="8.76443" width="2.48193" height="0.5" transform="rotate(-118 11.5018 8.76443)" fill="black" stroke="black" stroke-width="0.5"/>
|
||||
<rect x="8.74289" y="17.7719" width="2.12617" height="0.5" transform="rotate(149 8.74289 17.7719)" fill="black" stroke="black" stroke-width="0.5"/>
|
||||
<rect x="19.692" y="18.3533" width="5.65271" height="0.5" transform="rotate(43 19.692 18.3533)" fill="black" stroke="black" stroke-width="0.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 940 B |
3
ui/_/icons/people.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="26" height="23" viewBox="0 0 26 23" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16.5208 15.1601C17.867 15.1601 18.9583 16.251 18.9583 17.5966V19.223L18.9498 19.3405C18.6131 21.6429 16.5442 22.75 13.0724 22.75C9.61308 22.75 7.51108 21.6555 7.05733 19.3796L7.04167 19.2209V17.5966C7.04167 16.251 8.13297 15.1601 9.47917 15.1601H16.5208ZM16.5208 16.7844H9.47917C9.03044 16.7844 8.66667 17.1481 8.66667 17.5966V19.1347C8.96977 20.4346 10.3465 21.1257 13.0724 21.1257C15.7981 21.1257 17.113 20.442 17.3333 19.1593V17.5966C17.3333 17.1481 16.9696 16.7844 16.5208 16.7844ZM17.5972 8.66176L23.5625 8.66294C24.9087 8.66294 26 9.75378 26 11.0994V12.7258L25.9915 12.8433C25.6548 15.1457 23.5858 16.2528 20.114 16.2528L19.7729 16.2492C19.4533 15.4764 18.8664 14.8437 18.1278 14.4644C18.6855 14.5737 19.3463 14.6285 20.114 14.6285C22.8398 14.6285 24.1547 13.9448 24.375 12.6621V11.0994C24.375 10.6509 24.0112 10.2872 23.5625 10.2872H17.875C17.875 9.71726 17.7771 9.17014 17.5972 8.66176ZM2.4375 8.66294L8.40282 8.66176C8.25289 9.08541 8.15991 9.53596 8.13309 10.0042L8.125 10.2872H2.4375C1.98877 10.2872 1.625 10.6509 1.625 11.0994V12.6375C1.92811 13.9374 3.30485 14.6285 6.03069 14.6285C6.7046 14.6285 7.29227 14.5867 7.79848 14.5044C7.09349 14.8871 6.53462 15.5039 6.22521 16.2501L6.03069 16.2528C2.57141 16.2528 0.46941 15.1583 0.0156679 12.8824L0 12.7237V11.0994C0 9.75378 1.09131 8.66294 2.4375 8.66294ZM13 6.4972C15.0941 6.4972 16.7917 8.19406 16.7917 10.2872C16.7917 12.3804 15.0941 14.0773 13 14.0773C10.9059 14.0773 9.20833 12.3804 9.20833 10.2872C9.20833 8.19406 10.9059 6.4972 13 6.4972ZM13 8.1215C11.8034 8.1215 10.8333 9.09114 10.8333 10.2872C10.8333 11.4833 11.8034 12.453 13 12.453C14.1966 12.453 15.1667 11.4833 15.1667 10.2872C15.1667 9.09114 14.1966 8.1215 13 8.1215ZM20.0417 0C22.1357 0 23.8333 1.69686 23.8333 3.79004C23.8333 5.88321 22.1357 7.58007 20.0417 7.58007C17.9476 7.58007 16.25 5.88321 16.25 3.79004C16.25 1.69686 17.9476 0 20.0417 0ZM5.95833 0C8.05241 0 9.75 1.69686 9.75 3.79004C9.75 5.88321 8.05241 7.58007 5.95833 7.58007C3.86425 7.58007 2.16667 5.88321 2.16667 3.79004C2.16667 1.69686 3.86425 0 5.95833 0ZM20.0417 1.6243C18.845 1.6243 17.875 2.59393 17.875 3.79004C17.875 4.98614 18.845 5.95577 20.0417 5.95577C21.2383 5.95577 22.2083 4.98614 22.2083 3.79004C22.2083 2.59393 21.2383 1.6243 20.0417 1.6243ZM5.95833 1.6243C4.76172 1.6243 3.79167 2.59393 3.79167 3.79004C3.79167 4.98614 4.76172 5.95577 5.95833 5.95577C7.15495 5.95577 8.125 4.98614 8.125 3.79004C8.125 2.59393 7.15495 1.6243 5.95833 1.6243Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -2,4 +2,4 @@
|
||||
<path d="M12.601 19.3119C30.0726 23.7394 45.0003 32.9288 58.0437 47.2932C65.867 55.904 73.1099 66.9446 78.1982 77.9986C80.1834 82.327 80.7396 83.681 80.4431 83.4078C80.2882 83.2845 79.1607 81.7739 77.9251 80.0797C72.6654 72.9045 63.9124 61.9202 58.2259 55.3998C49.4162 45.2961 40.8775 37.3512 34.7055 33.4708C33.1306 32.4896 31.6913 31.8371 31.5848 32.0504C31.5582 32.1037 32.6828 32.9529 34.0966 33.9233C45.1644 41.5053 59.6654 57.6861 75.6237 80.3202C79.3447 85.5744 80.5135 87.3357 80.4203 87.5223C80.3804 87.6023 79.3067 87.685 78.0045 87.6918C71.9837 87.7778 66.6482 86.4576 60.4258 83.3453C55.1855 80.7338 50.7349 77.5414 46.0439 73.0628C40.6182 67.8877 36.9592 63.0096 32.5423 55.1467C26.3802 44.1093 19.5147 33.4466 10.9795 21.5924C9.78439 19.9505 8.85209 18.5494 8.87871 18.4961C8.89854 18.423 10.5783 18.794 12.601 19.3119Z" fill="#E94242"/>
|
||||
<path d="M54.6744 45.5251C63.9684 54.6538 77.6243 75.2121 91.793 101.393C92.552 102.799 93.2167 104.082 93.2541 104.221C93.3039 104.407 93.0894 104.348 92.4432 103.99C91.9728 103.718 91.086 103.375 90.4836 103.237C89.8913 103.081 89.4012 102.963 89.3971 102.948C89.3929 102.932 89.389 102.518 89.3786 102.023C89.3529 100.387 88.9501 99.2829 87.0386 95.6288C76.6739 75.7157 66.9904 60.2843 58.3454 49.8696C57.1128 48.4072 54.8905 45.932 54.0627 45.1247C53.8988 44.9694 53.8003 44.8298 53.8573 44.8145C53.9001 44.8031 54.2748 45.1176 54.6744 45.5251Z" fill="#E94242"/>
|
||||
<path d="M16.9505 80.1346C17.0099 80.3564 16.9656 80.4331 16.8619 80.288C16.7636 80.1631 16.7351 79.9762 16.7794 79.8995C16.8183 79.8026 16.9112 79.9074 16.9505 80.1346Z" fill="#E94242"/>
|
||||
</svg>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
5
ui/_/icons/quillblack.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="35" height="44" viewBox="0 0 35 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M30.0889 7.80232C23.8314 9.04361 18.3849 12.0151 13.5085 16.8507C10.5838 19.7494 7.81924 23.5176 5.816 27.3304C5.03413 28.8235 4.81246 29.2918 4.92233 29.2007C4.97937 29.16 5.40585 28.647 5.87397 28.0711C7.86595 25.6324 11.1632 21.912 13.294 19.7127C16.595 16.3047 19.7602 13.6546 22.0136 12.3974C22.5885 12.0798 23.1093 11.8758 23.143 11.9532C23.1514 11.9725 22.7382 12.2518 22.2205 12.5687C18.168 15.0435 12.7428 20.4941 6.68296 28.1987C5.27041 29.9869 4.82467 30.5878 4.85415 30.6555C4.86679 30.6845 5.24475 30.7336 5.7049 30.7601C7.83142 30.9021 9.74172 30.5343 11.9987 29.5495C13.8993 28.7235 15.5316 27.6775 17.2726 26.1814C19.2862 24.4528 20.6699 22.7964 22.3767 20.099C24.7592 16.3119 27.3834 12.6702 30.6198 8.63841C31.0726 8.08023 31.4281 7.60225 31.4197 7.58291C31.414 7.55671 30.8134 7.65674 30.0889 7.80232Z" fill="black"/>
|
||||
<path d="M14.7332 16.2884C11.279 19.3429 6.07149 26.3564 0.578482 35.3476C0.28413 35.8308 0.0254414 36.2718 0.00965904 36.3204C-0.0113841 36.3851 0.0655024 36.3683 0.300541 36.2538C0.47185 36.1662 0.791671 36.0613 1.00713 36.0239C1.21937 35.9795 1.39478 35.947 1.39653 35.9416C1.39829 35.9362 1.40734 35.79 1.42018 35.6151C1.4596 35.0372 1.6224 34.6546 2.36573 33.3984C6.39806 26.552 10.1066 21.277 13.3552 17.756C13.8179 17.262 14.6493 16.4282 14.9568 16.1582C15.0176 16.1064 15.055 16.0589 15.0351 16.0524C15.0202 16.0476 14.882 16.1518 14.7332 16.2884Z" fill="black"/>
|
||||
<path d="M27.4238 29.219C27.3987 29.2963 27.413 29.3242 27.4523 29.2749C27.4894 29.2325 27.5029 29.167 27.4887 29.1391C27.4767 29.1041 27.4419 29.1394 27.4238 29.219Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -87,8 +87,8 @@ class Forum extends Shadow {
|
||||
.gap(0.5, em)
|
||||
.width(100, pct)
|
||||
.height(100, vh)
|
||||
.alignHorizontal("center")
|
||||
.alignVertical("end")
|
||||
.horizontalAlign("center")
|
||||
.verticalAlign("end")
|
||||
})
|
||||
.width(100, "%")
|
||||
.height(87, vh)
|
||||
|
||||
@@ -72,8 +72,8 @@ class Messages extends Shadow {
|
||||
})
|
||||
.gap(1, em)
|
||||
.width(100, pct)
|
||||
.alignHorizontal("center")
|
||||
.alignVertical("end")
|
||||
.horizontalAlign("center")
|
||||
.verticalAlign("end")
|
||||
})
|
||||
.onAppear(async () => {
|
||||
let res = await Socket.send({app: "MESSAGES", operation: "GET"})
|
||||
@@ -121,8 +121,8 @@ class Messages extends Shadow {
|
||||
|
||||
})
|
||||
.gap(1, em)
|
||||
.alignVertical("center")
|
||||
.alignHorizontal("center")
|
||||
.verticalAlign("center")
|
||||
.horizontalAlign("center")
|
||||
.backgroundColor("black")
|
||||
.border("1px solid var(--accent)")
|
||||
.position("fixed")
|
||||
|
||||
@@ -25,9 +25,8 @@ css(`
|
||||
border-radius: 5px;
|
||||
text-underline-offset: 5px;
|
||||
}
|
||||
app-menu p:hover {
|
||||
text-decoration: underline;
|
||||
transform: translateY(-5%)
|
||||
app-menu img:hover {
|
||||
border: "1px solid black";
|
||||
}
|
||||
app-menu p.touched {
|
||||
text-decoration: underline;
|
||||
@@ -56,19 +55,14 @@ class AppMenu extends Shadow {
|
||||
render() {
|
||||
VStack(() => {
|
||||
HStack(() => {
|
||||
p("Forum")
|
||||
p("Messages")
|
||||
p("Market")
|
||||
p("Jobs")
|
||||
img("/_/icons/house.svg", "1.5em")
|
||||
img("/_/icons/nodes.svg", "1.5em")
|
||||
img("/_/icons/forum.svg", "1.5em")
|
||||
img("/_/icons/people.svg", "1.5em")
|
||||
})
|
||||
.justifyContent("center")
|
||||
.gap(1.5, em)
|
||||
.gap(3, em)
|
||||
.paddingRight(2, em)
|
||||
|
||||
img("/_/images/divider.svg", "40vw")
|
||||
.attr({
|
||||
"id": "divider",
|
||||
})
|
||||
})
|
||||
.gap(0.5, em)
|
||||
.onNavigate(() => {
|
||||
@@ -81,14 +75,14 @@ class AppMenu extends Shadow {
|
||||
}
|
||||
})
|
||||
.onAppear(() => {
|
||||
Array.from(this.querySelectorAll("p")).forEach((el) => {
|
||||
Array.from(this.querySelectorAll("img")).forEach((el) => {
|
||||
el.addEventListener("mousedown", (e) => {
|
||||
el.classList.add("touched")
|
||||
})
|
||||
})
|
||||
window.addEventListener("mouseup", (e) => {
|
||||
let target = e.target
|
||||
if(!target.matches("app-menu p")) {
|
||||
if(!target.matches("app-menu img")) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -8,23 +8,17 @@ class Home extends Shadow {
|
||||
|
||||
render() {
|
||||
ZStack(() => {
|
||||
img("/_/icons/logo.svg", "2.5em")
|
||||
.position("fixed")
|
||||
.left(3, em)
|
||||
.top(3, vh)
|
||||
.zIndex(3)
|
||||
.onClick(() => {
|
||||
window.navigateTo("/")
|
||||
})
|
||||
|
||||
div()
|
||||
.width(100, vw)
|
||||
.height(100, vh)
|
||||
.margin(0)
|
||||
.backgroundImage("/_/images/the_return.webp")
|
||||
.backgroundSize("cover")
|
||||
.backgroundPosition("48% 65%")
|
||||
.backgroundRepeat("no-repeat")
|
||||
|
||||
VStack(() => {
|
||||
img(document.documentElement.classList.contains("red") ? "/_/icons/quillblack.svg" : "/_/icons/quill.svg", "2.5em")
|
||||
.position("fixed")
|
||||
.left(3, em)
|
||||
.top(3, vh)
|
||||
.zIndex(3)
|
||||
.onClick(() => {
|
||||
window.navigateTo("/")
|
||||
})
|
||||
})
|
||||
|
||||
switch(window.location.pathname) {
|
||||
case "/":
|
||||
@@ -82,7 +76,7 @@ class Home extends Shadow {
|
||||
.gap(1, em)
|
||||
.xRight(2, em).y(2.3, em)
|
||||
.position("fixed")
|
||||
.alignVertical("center")
|
||||
.verticalAlign("center")
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<title>Parchment</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" href="/_/icons/logo.svg">
|
||||
<link rel="icon" href="/_/icons/quill.svg">
|
||||
<link rel="stylesheet" href="/_/code/shared.css">
|
||||
<script src="/_/code/quill.js"></script>
|
||||
<script src="/_/code/zod.js"></script>
|
||||
|
||||
@@ -52,8 +52,8 @@ class Forum extends Shadow {
|
||||
.gap(0.5, em)
|
||||
.width(100, pct)
|
||||
.height(100, vh)
|
||||
.alignHorizontal("center")
|
||||
.alignVertical("end")
|
||||
.horizontalAlign("center")
|
||||
.verticalAlign("end")
|
||||
})
|
||||
.onAppear(() => document.body.style.backgroundColor = "var(--darkbrown)")
|
||||
.width(100, pct)
|
||||
|
||||
@@ -72,8 +72,8 @@ class Messages extends Shadow {
|
||||
})
|
||||
.gap(1, em)
|
||||
.width(100, pct)
|
||||
.alignHorizontal("center")
|
||||
.alignVertical("end")
|
||||
.horizontalAlign("center")
|
||||
.verticalAlign("end")
|
||||
})
|
||||
.onAppear(async () => {
|
||||
let res = await Socket.send({app: "MESSAGES", operation: "GET"})
|
||||
@@ -121,8 +121,8 @@ class Messages extends Shadow {
|
||||
|
||||
})
|
||||
.gap(1, em)
|
||||
.alignVertical("center")
|
||||
.alignHorizontal("center")
|
||||
.verticalAlign("center")
|
||||
.horizontalAlign("center")
|
||||
.backgroundColor("black")
|
||||
.border("1px solid var(--accent)")
|
||||
.position("fixed")
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
class Events extends Shadow {
|
||||
|
||||
events = [
|
||||
{
|
||||
date: `January 23, 2025`,
|
||||
title: `Hyperia Winter Ball`,
|
||||
description: `Join us in Austin, Texas for a dance. Live music and drinks will be included. <br>Admission for men is $50, women are free. Open to the public.`,
|
||||
location: `Austin, TX`
|
||||
}
|
||||
]
|
||||
|
||||
render() {
|
||||
ZStack(() => {
|
||||
VStack(() => {
|
||||
|
||||
h1("HYPERIA")
|
||||
.marginBottom(0, em)
|
||||
|
||||
p("Public Events")
|
||||
.fontSize(1.2, em)
|
||||
.marginBottom(2, em)
|
||||
|
||||
const Stack = window.isMobile() ? VStack : HStack
|
||||
Stack(() => {
|
||||
|
||||
VStack(() => {
|
||||
p(`January 23, 2025`)
|
||||
|
||||
p(`Hyperia Winter Ball`)
|
||||
.fontSize(1.2, em)
|
||||
|
||||
p(`Austin, TX`)
|
||||
|
||||
})
|
||||
|
||||
p(`Join us in Austin, Texas for a great dance, with free drinks and live music. <br><br>Admission: $35 for men, women are free.`)
|
||||
.marginRight(4, em)
|
||||
|
||||
HStack(() => {
|
||||
img("/_/icons/creditcards/visa.svg")
|
||||
img("/_/icons/creditcards/mastercard.svg")
|
||||
img("/_/icons/creditcards/discover.svg")
|
||||
img("/_/icons/creditcards/amex.svg")
|
||||
})
|
||||
.alignSelf("flex-start")
|
||||
.height(2, em)
|
||||
.maxWidth(40, vw)
|
||||
|
||||
button("Buy Ticket")
|
||||
.color("var(--darkbrown")
|
||||
.border("1px solid #ab2f007d")
|
||||
.background('var(--green)')
|
||||
.marginLeft("auto")
|
||||
.onClick(async function() {
|
||||
this.innerText = "Loading..."
|
||||
const res = await fetch("/create-checkout-session", { method: "POST" });
|
||||
const data = await res.json();
|
||||
window.location = data.url;
|
||||
})
|
||||
})
|
||||
.gap(3, em)
|
||||
.color("var(--darkbrown)")
|
||||
.background(`var(--accent)`)
|
||||
.padding(1, em)
|
||||
.borderRadius(12, px)
|
||||
.border("2px solid #ab2f007d")
|
||||
})
|
||||
.marginLeft(window.isMobile() ? 0 : 15, vmax)
|
||||
.marginRight(window.isMobile() ? 0 : 15, vmax)
|
||||
.marginTop(10, vmax)
|
||||
|
||||
HStack(() => {
|
||||
p("Privacy Policy")
|
||||
.onHover(function (hovering) {
|
||||
if(hovering) {
|
||||
this.style.color = "var(--darkbrown)"
|
||||
} else {
|
||||
this.style.color = ""
|
||||
}
|
||||
})
|
||||
.onClick(() => {
|
||||
this.$("#policyWindow").style.display = "flex"
|
||||
})
|
||||
p("Refund and Return Policy")
|
||||
.onHover(function (hovering) {
|
||||
if(hovering) {
|
||||
this.style.color = "var(--darkbrown)"
|
||||
} else {
|
||||
this.style.color = ""
|
||||
}
|
||||
})
|
||||
.onClick(() => {
|
||||
this.$("#refundWindow").style.display = "flex"
|
||||
})
|
||||
p("Contact Us")
|
||||
.onHover(function (hovering) {
|
||||
if(hovering) {
|
||||
this.style.color = "var(--darkbrown)"
|
||||
} else {
|
||||
this.style.color = ""
|
||||
}
|
||||
})
|
||||
.onClick(() => {
|
||||
this.$("#contactWindow").style.display = "flex"
|
||||
})
|
||||
})
|
||||
.x(50, vw).yBottom(0, vh)
|
||||
.center()
|
||||
.gap(2, em)
|
||||
.opacity(0.5)
|
||||
.cursor("default")
|
||||
})
|
||||
|
||||
VStack(() => {
|
||||
|
||||
p("Privacy Policy")
|
||||
.fontSize(2, em)
|
||||
.fontWeight(600)
|
||||
.marginBottom(1, em)
|
||||
|
||||
p("We value your privacy. This Privacy Policy explains how we collect, use, store, and protect your information when you use our website or services.")
|
||||
|
||||
p("1. Information We Collect")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("• Personal information you provide, such as your name, email address, or other contact details.")
|
||||
p("• Automatically collected data, including IP address, browser type, device information, and usage statistics.")
|
||||
p("• Cookies or similar tracking technologies that help us improve the user experience.")
|
||||
|
||||
p("2. How We Use Your Information")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("• To operate and improve our website and services.")
|
||||
p("• To communicate with you about updates, support requests, or account-related matters.")
|
||||
p("• To maintain security, prevent fraud, and ensure proper functionality.")
|
||||
|
||||
p("3. How We Share Information")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("We do not sell your personal information. We may share data only with trusted service providers who help us operate the platform, or when required by law.")
|
||||
|
||||
p("4. Data Storage & Security")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("We use reasonable technical and administrative safeguards to protect your information. However, no system is completely secure, and we cannot guarantee absolute protection.")
|
||||
|
||||
p("5. Cookies")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("Our site may use cookies to remember preferences, analyze traffic, and enhance usability. You can disable cookies in your browser settings, but some features may stop working.")
|
||||
|
||||
p("6. Your Rights")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("Depending on your location, you may have rights to access, update, delete, or request a copy of your personal data. Contact us if you wish to exercise these rights.")
|
||||
|
||||
p("7. Third-Party Links")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("Our website may contain links to third-party sites. We are not responsible for their content or privacy practices.")
|
||||
|
||||
p("8. Changes to This Policy")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("We may update this Privacy Policy from time to time. Updated versions will be posted on this page with the effective date.")
|
||||
|
||||
p("9. Contact Us")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("If you have any questions about this Privacy Policy, feel free to contact us at info@hyperia.so.")
|
||||
|
||||
p("x")
|
||||
.onClick(function (done) {
|
||||
if(done) {
|
||||
this.parentElement.style.display = "none"
|
||||
}
|
||||
})
|
||||
.color("var(--red)")
|
||||
.xRight(1, em).y(1, em)
|
||||
.fontSize(2, em)
|
||||
.cursor("pointer")
|
||||
|
||||
})
|
||||
.x(50, vw).y(50, vh)
|
||||
.width(70, vw).height(70, vh)
|
||||
.center()
|
||||
.backgroundColor("var(--accent)")
|
||||
.display("none")
|
||||
.overflow("scroll")
|
||||
.padding(1, em)
|
||||
.border("3px solid black")
|
||||
.color("var(--darkbrown)")
|
||||
.attr({ id: "policyWindow" })
|
||||
|
||||
VStack(() => {
|
||||
|
||||
p("Refund & Return Policy")
|
||||
.fontSize(2, em)
|
||||
.fontWeight(600)
|
||||
.marginBottom(1, em)
|
||||
|
||||
p("1. Eligibility for Refunds")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("• Refund requests may be considered when submitted within 14 days of purchase.")
|
||||
p("• To qualify, you must provide proof of purchase and a valid reason for the request.")
|
||||
p("• Certain digital products or services may be non-refundable once accessed or downloaded.")
|
||||
|
||||
p("2. Non-Refundable Items")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("• Products or services that have already been delivered, downloaded, or accessed in full.")
|
||||
p("• Custom work, personalized items, or one-time service fees.")
|
||||
p("• Any promotional or discounted items, unless required by law.")
|
||||
|
||||
p("3. Returns (If Applicable)")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("• Physical items must be returned in their original condition.")
|
||||
p("• You are responsible for return shipping costs unless the item was defective or incorrect.")
|
||||
p("• Items damaged through misuse or neglect cannot be returned.")
|
||||
|
||||
p("4. Processing Refunds")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("• Approved refunds are issued to the original payment method.")
|
||||
p("• Processing times may vary depending on your bank or payment provider.")
|
||||
p("• We will notify you once your refund has been initiated.")
|
||||
|
||||
p("5. Cancellations")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("• Orders or subscriptions may be cancelled before fulfillment or renewal.")
|
||||
p("• If Hyperia declare a cancellation of any product or event, a refund will be issued to all parties.")
|
||||
|
||||
p("6. Contact for Refund Requests")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("If you need to request a refund, return an item, or cancel an order, please contact us at info@hyperia.so. Include your order number and relevant details so we can assist you promptly.")
|
||||
|
||||
p("7. Policy Updates")
|
||||
.fontWeight(600)
|
||||
.marginTop(1, em)
|
||||
|
||||
p("We may update this Refund & Return Policy from time to time. Any changes will be posted on this page with the effective date.")
|
||||
|
||||
p("x")
|
||||
.onClick(function (done) {
|
||||
if(done) {
|
||||
this.parentElement.style.display = "none"
|
||||
}
|
||||
})
|
||||
.color("var(--red)")
|
||||
.xRight(1, em).y(1, em)
|
||||
.fontSize(2, em)
|
||||
.cursor("pointer")
|
||||
|
||||
})
|
||||
.x(50, vw).y(50, vh)
|
||||
.width(70, vw).height(70, vh)
|
||||
.center()
|
||||
.backgroundColor("var(--accent)")
|
||||
.display("none")
|
||||
.overflow("scroll")
|
||||
.padding(1, em)
|
||||
.border("3px solid black")
|
||||
.color("var(--darkbrown)")
|
||||
.attr({ id: "refundWindow" })
|
||||
|
||||
|
||||
VStack(() => {
|
||||
|
||||
p("Contact Us")
|
||||
.fontSize(2, em)
|
||||
.fontWeight(600)
|
||||
.marginBottom(1, em)
|
||||
|
||||
p("Email: info@hyperia.so")
|
||||
p("Phone: 813-373-9100")
|
||||
p("Address: 2014 E 9th St, Unit A, Austin TX")
|
||||
|
||||
p("x")
|
||||
.onClick(function (done) {
|
||||
if(done) {
|
||||
this.parentElement.style.display = "none"
|
||||
}
|
||||
})
|
||||
.color("var(--red)")
|
||||
.xRight(1, em).y(1, em)
|
||||
.fontSize(2, em)
|
||||
.cursor("pointer")
|
||||
|
||||
})
|
||||
.gap(2, em)
|
||||
.x(50, vw).y(50, vh)
|
||||
.width(50, vw).height(50, vh)
|
||||
.center()
|
||||
.backgroundColor("var(--accent)")
|
||||
.display("none")
|
||||
.overflow("scroll")
|
||||
.padding(1, em)
|
||||
.border("3px solid black")
|
||||
.color("var(--darkbrown)")
|
||||
.attr({ id: "contactWindow" })
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
register(Events)
|
||||
@@ -1,9 +1,6 @@
|
||||
import "../components/NavBar.js"
|
||||
import "./SignupForm.js"
|
||||
import "./Why.js"
|
||||
import "./Events.js"
|
||||
import "./Join.js"
|
||||
import "./SignUp.js"
|
||||
import "./SignIn.js"
|
||||
import "./SignupForm.js"
|
||||
import "./Success.js"
|
||||
|
||||
class Home extends Shadow {
|
||||
@@ -55,7 +52,6 @@ class Home extends Shadow {
|
||||
.fontSize(1.2, em)
|
||||
.cursor("default")
|
||||
.onHover(function (hovering) {
|
||||
console.log("hover")
|
||||
if(hovering) {
|
||||
this.style.background = "var(--red)"
|
||||
this.style.color = "black"
|
||||
@@ -75,7 +71,6 @@ class Home extends Shadow {
|
||||
.fontSize(1.2, em)
|
||||
.cursor("default")
|
||||
.onHover(function (hovering) {
|
||||
console.log("hover")
|
||||
if(hovering) {
|
||||
this.style.background = "var(--red)"
|
||||
this.style.color = "black"
|
||||
@@ -110,7 +105,6 @@ class Home extends Shadow {
|
||||
.marginHorizontal(27, vw)
|
||||
.width(46, vw)
|
||||
.marginTop(10, vh)
|
||||
.fontFamily("Nanum")
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -121,28 +115,22 @@ class Home extends Shadow {
|
||||
case "/":
|
||||
this.MainContent()
|
||||
break;
|
||||
case "/why":
|
||||
Why()
|
||||
break;
|
||||
case "/events":
|
||||
Events()
|
||||
break;
|
||||
case "/join":
|
||||
Join()
|
||||
case "/signup":
|
||||
SignUp()
|
||||
break;
|
||||
case "/success":
|
||||
Success()
|
||||
break;
|
||||
|
||||
default:
|
||||
if(window.location.pathname.startsWith("/signup")) {
|
||||
if(window.location.pathname.startsWith("/free")) {
|
||||
SignupForm()
|
||||
} else if(window.location.pathname.startsWith("/login")) {
|
||||
SignIn()
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
.fontFamily("Nanum")
|
||||
.onNavigate(() => {
|
||||
this.rerender()
|
||||
})
|
||||
|
||||
31
ui/public/pages/SignUp.js
Normal file
@@ -0,0 +1,31 @@
|
||||
class SignUp extends Shadow {
|
||||
render() {
|
||||
VStack(() => {
|
||||
|
||||
h2("$50 / Month Subscription")
|
||||
.color("var(--red)")
|
||||
|
||||
p(" - Access to Parchment Online and Parchment Desktop")
|
||||
p(" - Ability to Create Networks")
|
||||
p(" - Up to 5GB Storage Space")
|
||||
|
||||
button("Buy")
|
||||
.color("var(--red")
|
||||
.border("1px solid var(--red)")
|
||||
.marginLeft("auto")
|
||||
.fontSize(1.1, em)
|
||||
.onClick(async function() {
|
||||
this.innerText = "Loading..."
|
||||
const res = await fetch("/create-checkout-session", { method: "POST" });
|
||||
const data = await res.json();
|
||||
window.location = data.url;
|
||||
})
|
||||
.marginTop(2, em)
|
||||
})
|
||||
.x(50, vw).y(50, vh).center()
|
||||
.border("1px solid var(--red)")
|
||||
.padding(1, em)
|
||||
}
|
||||
}
|
||||
|
||||
register(SignUp)
|
||||
@@ -12,7 +12,7 @@ class SignupForm extends Shadow {
|
||||
render() {
|
||||
ZStack(() => {
|
||||
form(() => {
|
||||
|
||||
|
||||
VStack(() => {
|
||||
|
||||
p()
|
||||
@@ -23,20 +23,20 @@ class SignupForm extends Shadow {
|
||||
.background("var(--accent)")
|
||||
|
||||
HStack(() => {
|
||||
|
||||
|
||||
VStack(() => {
|
||||
input("First Name*")
|
||||
.attr({name: "firstName", type: "name", required: "true"})
|
||||
.styles(this.inputStyles)
|
||||
|
||||
input("Last Name*")
|
||||
.attr({name: "lastName", type: "name", required: "true"})
|
||||
.styles(this.inputStyles)
|
||||
|
||||
input("Email*")
|
||||
.attr({name: "email", type: "email", required: "true"})
|
||||
.styles(this.inputStyles)
|
||||
|
||||
|
||||
input("First Name*")
|
||||
.attr({name: "firstName", type: "name", required: "true"})
|
||||
.styles(this.inputStyles)
|
||||
|
||||
input("Last Name*")
|
||||
.attr({name: "lastName", type: "name", required: "true"})
|
||||
.styles(this.inputStyles)
|
||||
|
||||
input("Password*")
|
||||
.attr({name: "password", type: "password", required: "true"})
|
||||
.styles(this.inputStyles)
|
||||
|
||||