diff --git a/.gitignore b/.gitignore index 7d9a7d2..46ba834 100644 --- a/.gitignore +++ b/.gitignore @@ -129,7 +129,7 @@ dist .yarn/install-state.gz .pnp.* -sarlink.jpg +sarlink* uploads/ diff --git a/README.md b/README.md index 9b78de7..78947c6 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # SAR Link Customer Registration form. - ## Todo -- [ ] Implement per device addons. -- [ ] Add all devices and their corresponding addons. + +- [x] Implement per device addons. +- [x] Add all devices and their corresponding addons. - [ ] Generate a connection request receipt including all information entered by the user. -- [ ] Incorporate a step to ask for the customer's phone number. +- [x] Incorporate a step to ask for the customer's phone number. - [ ] Create a link with instructions on how to connect, including how to disable MAC randomization and providing the network password. - [ ] Dhivehi support, Dhivehi to be the default language diff --git a/server.js b/server.js index 5d02e17..05cb7e8 100644 --- a/server.js +++ b/server.js @@ -21,6 +21,7 @@ function loadEnv() { currency: process.env.PRICE_CURRENCY || "MVR", } } + console.log(`Registration is now ${registrationOpen ? "open" : "closed"}`) } loadEnv() @@ -31,7 +32,6 @@ fs.watchFile(path.join(__dirname, ".env"), (curr, prev) => { delete require.cache[require.resolve("dotenv")] require("dotenv").config({ override: true }) loadEnv() - console.log(`Registration is now ${registrationOpen ? "open" : "closed"}`) }) // initialize express @@ -46,7 +46,7 @@ app.use(express.urlencoded({ extended: true })) // add multer const multer = require("multer") if (!fs.existsSync("uploads")) fs.mkdirSync("uploads", { recursive: true }) -if (!fs.existsSync("registrations.csv")) fs.writeFileSync("registrations.csv", "Customer Name,MAC Address,Device Name,Roaming,Gaming,Wired,Receipt\n", { encoding: "utf-8" }); +if (!fs.existsSync("registrations.csv")) fs.writeFileSync("registrations.csv", "Customer Name,Phone Number,MAC Address,Device Name,Roaming,Gaming,Wired,Receipt\n", { encoding: "utf-8" }); const upload = multer({ storage: multer.diskStorage({ destination: (req, file, cb) => { @@ -70,21 +70,19 @@ app.post("/register", upload.single("transfer_receipt"), (req, res) => { return; } - let { customer_name, mac_address, device_name, is_roaming, is_gaming } = req.body + let { customer_name, phone_number, mac_address, device_name, is_roaming, is_gaming } = req.body const receipt = req.file; if (!is_roaming || is_roaming === "false") is_roaming = false if (!is_gaming || is_gaming === "false") is_gaming = false - if (!customer_name || !mac_address || !device_name || !receipt) { + if (!customer_name || !phone_number || !mac_address || !device_name || !receipt) { res.render("index", { branding, message: "Please fill all fields" }) return; } - console.log(is_roaming, is_gaming) - // save info to csv file - const csv = `${customer_name},${mac_address},${device_name},${is_roaming ? "true" : "false"},${is_gaming ? "true" : "false"},false,${receipt.path}\n` + const csv = `${customer_name},${phone_number},${mac_address.replace(/,/g, " ")},${device_name.replace(/,/g, " ")},${is_roaming.replace(/,/g, " ")},${is_gaming.replace(/,/g, " ")},false,${receipt.path}\n` fs.appendFile("registrations.csv", csv, (err) => { if (err) { console.error(err) @@ -93,7 +91,7 @@ app.post("/register", upload.single("transfer_receipt"), (req, res) => { }); // send receipt to telegram - sendInfo(receipt.path, { customer_name, mac_address, device_name, is_roaming, is_gaming }) + sendInfo(receipt.path, { customer_name, phone_number, mac_address, device_name, is_roaming, is_gaming }) .then(() => { res.render("success", { branding }) }) diff --git a/src/public/styles.css b/src/public/styles.css index 08950ad..69e5bbf 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -1441,38 +1441,19 @@ html { align-items: center; } -.select { - display: inline-flex; +.radio { + flex-shrink: 0; + --chkbg: var(--bc); + height: 1.5rem; + width: 1.5rem; cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -webkit-appearance: none; -moz-appearance: none; appearance: none; - height: 3rem; - min-height: 3rem; - padding-left: 1rem; - padding-right: 2.5rem; - font-size: 0.875rem; - line-height: 1.25rem; - line-height: 2; - border-radius: var(--rounded-btn, 0.5rem); + border-radius: 9999px; border-width: 1px; - border-color: transparent; - --tw-bg-opacity: 1; - background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); - background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), - linear-gradient(135deg, currentColor 50%, transparent 50%); - background-position: calc(100% - 20px) calc(1px + 50%), - calc(100% - 16.1px) calc(1px + 50%); - background-size: 4px 4px, - 4px 4px; - background-repeat: no-repeat; -} - -.select[multiple] { - height: auto; + border-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity))); + --tw-border-opacity: 0.2; } .steps { @@ -1503,15 +1484,6 @@ html { --alert-bg-mix: var(--fallback-b1,oklch(var(--b1)/1)); } -.badge-secondary { - --tw-border-opacity: 1; - border-color: var(--fallback-s,oklch(var(--s)/var(--tw-border-opacity))); - --tw-bg-opacity: 1; - background-color: var(--fallback-s,oklch(var(--s)/var(--tw-bg-opacity))); - --tw-text-opacity: 1; - color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity))); -} - .badge-error { border-color: transparent; --tw-bg-opacity: 1; @@ -1520,11 +1492,6 @@ html { color: var(--fallback-erc,oklch(var(--erc)/var(--tw-text-opacity))); } -.badge-outline.badge-secondary { - --tw-text-opacity: 1; - color: var(--fallback-s,oklch(var(--s)/var(--tw-text-opacity))); -} - .badge-outline.badge-error { --tw-text-opacity: 1; color: var(--fallback-er,oklch(var(--er)/var(--tw-text-opacity))); @@ -1587,6 +1554,14 @@ html { border-color: var(--btn-color, var(--fallback-b2)); } + .btn-primary { + --btn-color: var(--fallback-p); + } + + .btn-accent { + --btn-color: var(--fallback-a); + } + .btn-info { --btn-color: var(--fallback-in); } @@ -1643,7 +1618,21 @@ html { outline-offset: 2px; } +.btn-primary { + --tw-text-opacity: 1; + color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity))); + outline-color: var(--fallback-p,oklch(var(--p)/1)); +} + @supports (color: oklch(0 0 0)) { + .btn-primary { + --btn-color: var(--p); + } + + .btn-accent { + --btn-color: var(--a); + } + .btn-info { --btn-color: var(--in); } @@ -1657,6 +1646,12 @@ html { } } +.btn-accent { + --tw-text-opacity: 1; + color: var(--fallback-ac,oklch(var(--ac)/var(--tw-text-opacity))); + outline-color: var(--fallback-a,oklch(var(--a)/1)); +} + .btn-info { --tw-text-opacity: 1; color: var(--fallback-inc,oklch(var(--inc)/var(--tw-text-opacity))); @@ -2268,6 +2263,32 @@ details.collapse summary::-webkit-details-marker { } } +.radio:focus { + box-shadow: none; +} + +.radio:focus-visible { + outline-style: solid; + outline-width: 2px; + outline-offset: 2px; + outline-color: var(--fallback-bc,oklch(var(--bc)/1)); +} + +.radio:checked, + .radio[aria-checked="true"] { + --tw-bg-opacity: 1; + background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity))); + background-image: none; + animation: radiomark var(--animation-input, 0.2s) ease-out; + box-shadow: 0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset, + 0 0 0 4px var(--fallback-b1,oklch(var(--b1)/1)) inset; +} + +.radio:disabled { + cursor: not-allowed; + opacity: 0.2; +} + @keyframes radiomark { 0% { box-shadow: 0 0 0 12px var(--fallback-b1,oklch(var(--b1)/1)) inset, @@ -2299,55 +2320,6 @@ details.collapse summary::-webkit-details-marker { } } -.select-bordered { - border-color: var(--fallback-bc,oklch(var(--bc)/0.2)); -} - -.select:focus { - box-shadow: none; - border-color: var(--fallback-bc,oklch(var(--bc)/0.2)); - outline-style: solid; - outline-width: 2px; - outline-offset: 2px; - outline-color: var(--fallback-bc,oklch(var(--bc)/0.2)); -} - -.select-disabled, - .select:disabled, - .select[disabled] { - cursor: not-allowed; - --tw-border-opacity: 1; - border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity))); - --tw-bg-opacity: 1; - background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity))); - color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity))); - --tw-text-opacity: 0.2; -} - -.select-disabled::-moz-placeholder, .select:disabled::-moz-placeholder, .select[disabled]::-moz-placeholder { - color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity))); - --tw-placeholder-opacity: 0.2; -} - -.select-disabled::placeholder, - .select:disabled::placeholder, - .select[disabled]::placeholder { - color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity))); - --tw-placeholder-opacity: 0.2; -} - -.select-multiple, - .select[multiple], - .select[size].select:not([size="1"]) { - background-image: none; - padding-right: 1rem; -} - -[dir="rtl"] .select { - background-position: calc(0% + 12px) calc(1px + 50%), - calc(0% + 16px) calc(1px + 50%); -} - @keyframes skeleton { from { background-position: 150%; @@ -2653,6 +2625,10 @@ details.collapse summary::-webkit-details-marker { margin-right: auto; } +.mt-4 { + margin-top: 1rem; +} + .mt-8 { margin-top: 2rem; } @@ -2661,8 +2637,12 @@ details.collapse summary::-webkit-details-marker { margin-top: 0.25rem; } -.mt-4 { - margin-top: 1rem; +.mt-2 { + margin-top: 0.5rem; +} + +.mb-1 { + margin-bottom: 0.25rem; } .flex { @@ -2681,8 +2661,8 @@ details.collapse summary::-webkit-details-marker { height: 100vh; } -.w-10 { - width: 2.5rem; +.w-12 { + width: 3rem; } .w-6 { @@ -2741,6 +2721,15 @@ details.collapse summary::-webkit-details-marker { border-radius: 0.25rem; } +.border { + border-width: 1px; +} + +.border-base-300 { + --tw-border-opacity: 1; + border-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-border-opacity))); +} + .bg-base-100 { --tw-bg-opacity: 1; background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); @@ -2765,6 +2754,14 @@ details.collapse summary::-webkit-details-marker { stroke: currentColor; } +.text-center { + text-align: center; +} + +.align-middle { + vertical-align: middle; +} + .text-3xl { font-size: 1.875rem; line-height: 2.25rem; @@ -2816,4 +2813,36 @@ details.collapse summary::-webkit-details-marker { .filter { filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +@media (min-width: 1024px) { + .lg\:join-horizontal.join { + flex-direction: row; + } + + .lg\:join-horizontal.join .join-item:first-child:not(:last-child),.lg\:join-horizontal + .join *:first-child:not(:last-child) .join-item { + border-end-end-radius: 0; + border-start-end-radius: 0; + border-end-start-radius: inherit; + border-start-start-radius: inherit; + } + + .lg\:join-horizontal.join .join-item:last-child:not(:first-child),.lg\:join-horizontal + .join *:last-child:not(:first-child) .join-item { + border-end-start-radius: 0; + border-start-start-radius: 0; + border-end-end-radius: inherit; + border-start-end-radius: inherit; + } + + .lg\:join-horizontal.join > :where(*:not(:first-child)) { + margin-top: 0px; + margin-bottom: 0px; + margin-inline-start: -1px; + } + + .lg\:mb-0 { + margin-bottom: 0px; + } } \ No newline at end of file diff --git a/src/telegram.js b/src/telegram.js index 344ff63..a54f832 100644 --- a/src/telegram.js +++ b/src/telegram.js @@ -9,7 +9,7 @@ function kebabToTitleCase(str) { async function sendInfo(filepath, details) { // const caption = `Customer Name: \`${customer_name}\`\nMAC Address: \`${mac_address}\`\nDevice Name: \`${device_name}\`\nRoaming: **${roaming ? "Yes" : "No"}**\nGaming: **${gaming ? "Yes" : "No"}**` let caption = ""; - let manualHandles = ["mac_address", "device_name"]; + let manualHandles = ["mac_address", "device_name", "is_roaming", "is_gaming"]; for (const key in details) { if (manualHandles.includes(key)) continue; @@ -24,7 +24,9 @@ async function sendInfo(filepath, details) { let macAddresses = details["mac_address"].split(","); let deviceNames = details["device_name"].split(","); - caption += "\n" + macAddresses.map((macAddress, index) => `- \`${macAddress}\` : \`${deviceNames[index]}\``).join("\n"); + let isRoaming = details["is_roaming"].split(","); + let isGaming = details["is_gaming"].split(","); + caption += macAddresses.map((macAddress, index) => `\n\`${deviceNames[index]}\`\nMAC Address: \`${macAddress}\`\nIs Roaming: **${isRoaming[index] === "true" ? "Yes" : "No"}**\nIs Gaming: **${isGaming[index] === "true" ? "Yes" : "No"}**`).join("\n"); caption = caption.replace(/-/g, '\\-') diff --git a/src/views/index.ejs b/src/views/index.ejs index 52dbd85..5e2afe2 100644 --- a/src/views/index.ejs +++ b/src/views/index.ejs @@ -1,597 +1,551 @@ -
- - -