Skip to main content
// Online Pharmacy Website in HopeScript (HS + HSON + TDMLTK + T-Code) // - Single-file example demonstrating components, routing, state, mock backend, prescription upload, // cart, checkout flow, search & filters, admin CRUD, and a small ML-driven recommendation pipeline. // - This is a practical, runnable blueprint for a Hope AI ecosystem app. /////////////////////// // App Configuration // /////////////////////// const APP_TITLE = "HopePharm - Online Pharmacy" const API_PREFIX = "/api" // In a real deployment, point to your backend URL const STORAGE_CART_KEY = "hopepharm_cart" const STORAGE_USER_KEY = "hopepharm_user" /////////////////////// // HSON: Sample Data // /////////////////////// // Use HSON-like objects for initial dataset and schema declarations const PRODUCTS = [ { id: "p001", name: "AcetaClear 500mg", description: "Pain relief & fever reducer. 20 tablets.", price: 7.99, image: "https://hopeaihub.info/images/acetaclear.png", category: "Analgesic", requiresPrescription: false, stock: 120 }, { id: "p002", name: "CardioSafe 10mg", description: "Blood pressure control. 30 tablets.", price: 19.5, image: "https://hopeaihub.info/images/cardiosafe.png", category: "Cardiovascular", requiresPrescription: true, stock: 45 }, { id: "p003", name: "AllerGone Syrup", description: "Allergy relief, children-friendly syrup, 100ml.", price: 12.25, image: "https://hopeaihub.info/images/allergone.png", category: "Antihistamine", requiresPrescription: false, stock: 80 } ] // HSON schema (lightweight) const PRODUCT_SCHEMA = { id: "string", name: "string", description: "string", price: "number", image: "string", category: "string", requiresPrescription: "boolean", stock: "number" } ///////////////////////// // Utility & Validators // ///////////////////////// function validate(schema, obj) { for (let k in schema) { if (!(k in obj)) return false const t = typeof obj[k] if (schema[k] === "number" && t !== "number") return false if (schema[k] === "string" && t !== "string") return false if (schema[k] === "boolean" && t !== "boolean") return false } return true } function formatCurrency(n) { return "$" + n.toFixed(2) } function saveCart(cart) { localStorage.setItem(STORAGE_CART_KEY, JSON.stringify(cart)) } function loadCart() { const raw = localStorage.getItem(STORAGE_CART_KEY) return raw ? JSON.parse(raw) : [] } function saveUser(user) { localStorage.setItem(STORAGE_USER_KEY, JSON.stringify(user)) } function loadUser() { const raw = localStorage.getItem(STORAGE_USER_KEY) return raw ? JSON.parse(raw) : null } ///////////////////////// // Mock Backend Server // ///////////////////////// // T-Code activation + mock DB registration (illustrative) TCode.db("T-Code activated for HopePharm") // Mock DB using in-memory store (for demo) const DB = { products: PRODUCTS.slice(), orders: [], users: [ { id: "u_admin", email: "admin@hopepharm.example", name: "Admin", role: "admin", password: "adminpass" } ] } // Minimal API router function apiGetProducts(query = {}) { // filter by search, category, prescription flag let list = DB.products.slice() if (query.search) { const s = query.search.toLowerCase() list = list.filter(p => p.name.toLowerCase().includes(s) || p.description.toLowerCase().includes(s)) } if (query.category) { list = list.filter(p => p.category === query.category) } if (query.requiresPrescription !== undefined) { list = list.filter(p => p.requiresPrescription === query.requiresPrescription) } return Promise.resolve(list) } function apiGetProductById(id) { const p = DB.products.find(x => x.id === id) return Promise.resolve(p ? Object.assign({}, p) : null) } function apiCreateOrder(order) { // Basic validation; ensure items exist and stock available for (let item of order.items) { const prod = DB.products.find(p => p.id === item.productId) if (!prod) return Promise.reject("Product not found: " + item.productId) if (prod.stock < item.quantity) return Promise.reject("Insufficient stock for " + prod.name) } // Deduct stock for (let item of order.items) { const prod = DB.products.find(p => p.id === item.productId) prod.stock -= item.quantity } const orderId = "ord_" + Date.now() const newOrder = Object.assign({ id: orderId, createdAt: new Date().toISOString(), status: "pending" }, order) DB.orders.push(newOrder) return Promise.resolve(newOrder) } function apiCreateProduct(product) { if (!validate(PRODUCT_SCHEMA, product)) return Promise.reject("Invalid product schema") if (DB.products.find(p => p.id === product.id)) return Promise.reject("Product ID exists") DB.products.push(product) return Promise.resolve(product) } function apiUpdateProduct(product) { const idx = DB.products.findIndex(p => p.id === product.id) if (idx < 0) return Promise.reject("Product not found") DB.products[idx] = product return Promise.resolve(product) } function apiDeleteProduct(id) { const idx = DB.products.findIndex(p => p.id === id) if (idx < 0) return Promise.reject("Product not found") DB.products.splice(idx, 1) return Promise.resolve(true) } function apiAuthenticate(email, password) { const u = DB.users.find(x => x.email === email && x.password === password) if (!u) return Promise.reject("Invalid credentials") // Return sanitized user object const { password: _pw, ...san } = u return Promise.resolve(san) } ////////////////////// // TDMLTK: Recommender ////////////////////// // Simple item-based co-occurrence recommender using TDMLTK-style pipeline const Recommender = { // update model from order history buildModel: function(orders) { // co-occurrence counts const co = {} for (let order of orders) { const ids = order.items.map(i => i.productId) for (let i = 0; i < ids.length; i++) { for (let j = 0; j < ids.length; j++) { if (i === j) continue const a = ids[i], b = ids[j] co[a] = co[a] || {} co[a][b] = (co[a][b] || 0) + 1 } } } this.model = co return co }, recommend: function(productId, topK = 3) { if (!this.model || !this.model[productId]) return [] const arr = Object.entries(this.model[productId]) arr.sort((a, b) => b[1] - a[1]) return arr.slice(0, topK).map(x => x[0]) }, model: {} } Recommender.buildModel(DB.orders) ///////////////////////// // UI Components (HS) // ///////////////////////// // Very light component system: render functions returning DOM nodes // In HopeScript runtime, assume document and element creation utilities exist. function App() { document.title = APP_TITLE const root = document.getElementById("app") root.innerHTML = "" // clear root.appendChild(Header()) root.appendChild(MainRouter()) root.appendChild(Footer()) } // Header with search and cart indicator function Header() { const header = el("header", { class: "hp-header" }) header.appendChild(el("h1", { class: "hp-title" }, APP_TITLE)) // Search const searchInput = el("input", { type: "search", placeholder: "Search products..." }) searchInput.addEventListener("keydown", (e) => { if (e.key === "Enter") { navigateTo("/?search=" + encodeURIComponent(searchInput.value)) } }) header.appendChild(searchInput) // Cart summary const cartBtn = el("button", { class: "hp-cart-btn" }, `Cart (${loadCart().length})`) cartBtn.addEventListener("click", () => navigateTo("/cart")) header.appendChild(cartBtn) // User / Auth const user = loadUser() const userBtn = el("button", { class: "hp-user-btn" }, user ? user.name : "Sign In") userBtn.addEventListener("click", () => { if (user) navigateTo("/account") else navigateTo("/login") }) header.appendChild(userBtn) return header } // Footer function Footer() { const f = el("footer", { class: "hp-footer" }, "© HopePharm 2026 — Trusted online pharmacy") return f } // Router (very small) function MainRouter() { const container = el("main", { class: "hp-main" }) const path = window.location.pathname || "/" const q = new URLSearchParams(window.location.search) // Simple route switch if (path === "/" || path === "/home") { renderHome(container, q) } else if (path.startsWith("/product/")) { const id = path.split("/")[2] renderProductPage(container, id) } else if (path === "/cart") { renderCart(container) } else if (path === "/checkout") { renderCheckout(container) } else if (path === "/login") { renderLogin(container) } else if (path === "/account") { renderAccount(container) } else if (path === "/admin") { renderAdmin(container) } else { container.appendChild(el("p", {}, "Page not found")) } return container } ///////////////////////// // Page Renderers // ///////////////////////// function renderHome(root, query) { const qSearch = query.get("search") || "" const category = query.get("category") || null const section = el("section", { class: "hp-section" }) const h = el("h2", {}, "Shop Medicines & Health Products") section.appendChild(h) // Filters const filters = el("div", { class: "hp-filters" }) const allCats = Array.from(new Set(DB.products.map(p => p.category))) const catSelect = el("select") catSelect.appendChild(el("option", { value: "" }, "All Categories")) for (let c of allCats) { const opt = el("option", { value: c }, c) if (c === category) opt.selected = true catSelect.appendChild(opt) } catSelect.addEventListener("change", () => { const c = catSelect.value const url = c ? "/?category=" + encodeURIComponent(c) : "/" navigateTo(url) }) filters.appendChild(catSelect) section.appendChild(filters) // Product grid (async fetch) apiGetProducts({ search: qSearch, category: category ? category : undefined }) .then(list => { const grid = el("div", { class: "hp-grid" }) for (let p of list) { const card = el("div", { class: "hp-card" }) const img = el("img", { src: p.image, alt: p.name, class: "hp-card-img" }) card.appendChild(img) card.appendChild(el("h3", {}, p.name)) card.appendChild(el("p", { class: "hp-price" }, formatCurrency(p.price))) card.appendChild(el("p", { class: "hp-desc" }, p.description)) const btn = el("button", {}, "View") btn.addEventListener("click", () => navigateTo("/product/" + p.id)) card.appendChild(btn) grid.appendChild(card) } section.appendChild(grid) }) root.appendChild(section) } function renderProductPage(root, productId) { const section = el("section", { class: "hp-section" }) apiGetProductById(productId) .then(p => { if (!p) { section.appendChild(el("p", {}, "Product not found")) root.appendChild(section) return } const container = el("div", { class: "hp-product" }) container.appendChild(el("img", { src: p.image, alt: p.name, class: "hp-product-img" })) const info = el("div", { class: "hp-product-info" }) info.appendChild(el("h2", {}, p.name)) info.appendChild(el("p", { class: "hp-price" }, formatCurrency(p.price))) info.appendChild(el("p", {}, p.description)) info.appendChild(el("p", {}, "Category: " + p.category)) if (p.requiresPrescription) info.appendChild(el("p", { class: "hp-warning" }, "Prescription required")) info.appendChild(el("p", {}, "In stock: " + p.stock)) // Quantity + Add to cart const qty = el("input", { type: "number", min: 1, value: 1 }) const addBtn = el("button", {}, "Add to Cart") addBtn.addEventListener("click", () => { const q = Math.max(1, parseInt(qty.value) || 1) const cart = loadCart() cart.push({ productId: p.id, quantity: q }) saveCart(cart) showToast("Added to cart") navigateTo("/") // refresh header cart count via full re-render }) info.appendChild(el("div", {}, qty, addBtn)) // Prescription upload if required if (p.requiresPrescription) { const prescForm = el("div", { class: "hp-presc" }) prescForm.appendChild(el("label", {}, "Upload prescription (PDF/JPG): ")) const fileInput = el("input", { type: "file", accept: ".pdf,image/*" }) prescForm.appendChild(fileInput) prescForm.appendChild(el("p", { class: "hp-note" }, "Our pharmacist will review your prescription during checkout.")) info.appendChild(prescForm) } container.appendChild(info) section.appendChild(container) // Recommendations (TDMLTK) const recIds = Recommender.recommend(p.id, 3) if (recIds.length > 0) { const recSection = el("div", { class: "hp-recs" }) recSection.appendChild(el("h3", {}, "Customers also bought")) const recGrid = el("div", { class: "hp-grid" }) for (let rid of recIds) { const prod = DB.products.find(x => x.id === rid) if (!prod) continue const card = el("div", { class: "hp-card" }) card.appendChild(el("img", { src: prod.image, alt: prod.name, class: "hp-card-img" })) card.appendChild(el("h4", {}, prod.name)) const vbtn = el("button", {}, "View") vbtn.addEventListener("click", () => navigateTo("/product/" + prod.id)) card.appendChild(vbtn) recGrid.appendChild(card) } recSection.appendChild(recGrid) section.appendChild(recSection) } root.appendChild(section) }) } function renderCart(root) { const section = el("section", { class: "hp-section" }) section.appendChild(el("h2", {}, "Your Cart")) const cart = loadCart() if (!cart.length) { section.appendChild(el("p", {}, "Your cart is empty.")) section.appendChild(el("button", {}, "Continue shopping").addEventListener("click", () => navigateTo("/"))) root.appendChild(section) return } const table = el("table", { class: "hp-cart-table" }) for (let item of cart) { const prod = DB.products.find(p => p.id === item.productId) if (!prod) continue const row = el("tr") row.appendChild(el("td", {}, prod.name)) row.appendChild(el("td", {}, formatCurrency(prod.price))) row.appendChild(el("td", {}, "x" + item.quantity)) row.appendChild(el("td", {}, formatCurrency(prod.price * item.quantity))) table.appendChild(row) } section.appendChild(table) const checkoutBtn = el("button", {}, "Proceed to Checkout") checkoutBtn.addEventListener("click", () => navigateTo("/checkout")) section.appendChild(checkoutBtn) root.appendChild(section) } function renderCheckout(root) { const section = el("section", { class: "hp-section" }) section.appendChild(el("h2", {}, "Checkout")) const cart = loadCart() if (!cart.length) { section.appendChild(el("p", {}, "Your cart is empty.")) root.appendChild(section) return } // Order summary const summary = el("div", { class: "hp-order-summary" }) let total = 0 for (let item of cart) { const prod = DB.products.find(p => p.id === item.productId) if (!prod) continue summary.appendChild(el("p", {}, `${prod.name} x${item.quantity} — ${formatCurrency(prod.price * item.quantity)}`)) total += prod.price * item.quantity } summary.appendChild(el("h3", {}, "Total: " + formatCurrency(total))) section.appendChild(summary) // Shipping / Payment stub const form = el("form") form.appendChild(el("label", {}, "Full Name")) const nameInput = el("input", { type: "text", required: true }) form.appendChild(nameInput) form.appendChild(el("label", {}, "Shipping Address")) const addrInput = el("textarea", { required: true }) form.appendChild(addrInput) form.appendChild(el("label", {}, "Prescription file (if any medicines require it)")) const prescInput = el("input", { type: "file", accept: ".pdf,image/*" }) form.appendChild(prescInput) const payBtn = el("button", { type: "submit" }, "Place Order (Pay)") form.addEventListener("submit", (evt) => { evt.preventDefault() const order = { user: loadUser(), items: cart.map(i => ({ productId: i.productId, quantity: i.quantity })), shipping: { name: nameInput.value, address: addrInput.value }, total: total // payment flow would be integrated here } apiCreateOrder(order) .then(created => { // clear cart saveCart([]) // update recommender model Recommender.buildModel(DB.orders) showToast("Order placed: " + created.id) navigateTo("/home") }) .catch(err => showToast("Checkout error: " + err)) }) section.appendChild(form) root.appendChild(section) } function renderLogin(root) { const section = el("section", { class: "hp-section" }) section.appendChild(el("h2", {}, "Sign In")) const form = el("form") form.appendChild(el("label", {}, "Email")) const email = el("input", { type: "email", required: true }) form.appendChild(email) form.appendChild(el("label", {}, "Password")) const password = el("input", { type: "password", required: true }) form.appendChild(password) const submit = el("button", { type: "submit" }, "Sign In") form.addEventListener("submit", (evt) => { evt.preventDefault() apiAuthenticate(email.value, password.value) .then(user => { saveUser(user) showToast("Signed in as " + user.name) navigateTo("/account") }) .catch(err => showToast("Auth error: " + err)) }) form.appendChild(submit) section.appendChild(form) root.appendChild(section) } function renderAccount(root) { const user = loadUser() const section = el("section", { class: "hp-section" }) if (!user) { section.appendChild(el("p", {}, "Not signed in.")) section.appendChild(el("button", {}, "Sign In").addEventListener("click", () => navigateTo("/login"))) root.appendChild(section) return } section.appendChild(el("h2", {}, "Account")) section.appendChild(el("p", {}, "Name: " + user.name)) section.appendChild(el("p", {}, "Email: " + user.email)) const signout = el("button", {}, "Sign Out") signout.addEventListener("click", () => { localStorage.removeItem(STORAGE_USER_KEY) showToast("Signed out") navigateTo("/") }) section.appendChild(signout) root.appendChild(section) } function renderAdmin(root) { const user = loadUser() if (!user || user.role !== "admin") { root.appendChild(el("p", {}, "Admin access required.")) return } const section = el("section", { class: "hp-section" }) section.appendChild(el("h2", {}, "Admin Dashboard")) section.appendChild(el("h3", {}, "Products")) const prodList = el("div", { class: "hp-admin-list" }) for (let p of DB.products) { const row = el("div", { class: "hp-admin-row" }) row.appendChild(el("span", {}, p.name)) const edit = el("button", {}, "Edit") edit.addEventListener("click", () => { const newName = prompt("New name", p.name) if (newName) { p.name = newName apiUpdateProduct(p).then(() => { showToast("Product updated") navigateTo("/admin") }) } }) const del = el("button", {}, "Delete") del.addEventListener("click", () => { if (confirm("Delete " + p.name + "?")) { apiDeleteProduct(p.id).then(() => { showToast("Deleted") navigateTo("/admin") }) } }) row.appendChild(edit); row.appendChild(del) prodList.appendChild(row) } section.appendChild(prodList) const createBtn = el("button", {}, "Create New Product") createBtn.addEventListener("click", () => { const id = "p" + Math.floor(Math.random() * 10000) const name = prompt("Product name") if (!name) return const price = parseFloat(prompt("Price", "0")) const category = prompt("Category", "General") const p = { id, name, description: "", price: price || 0, image: "", category, requiresPrescription: false, stock: 0 } apiCreateProduct(p).then(() => { showToast("Created") navigateTo("/admin") }) }) section.appendChild(createBtn) root.appendChild(section) } ////////////////////// // Small UI Helpers // ////////////////////// // create element helper (simple) function el(tag, attrs = {}, ...children) { const node = document.createElement(tag) for (let k in attrs) { if (k === "class") node.className = attrs[k] else if (k === "html") node.innerHTML = attrs[k] else node.setAttribute(k, attrs[k]) } for (let ch of children) { if (!ch) continue if (typeof ch === "string") node.appendChild(document.createTextNode(ch)) else node.appendChild(ch) } return node } function navigateTo(path) { history.pushState({}, "", path) // re-render entire app for simplicity App() } window.addEventListener("popstate", () => App()) function showToast(msg) { const t = el("div", { class: "hp-toast" }, msg) document.body.appendChild(t) setTimeout(() => t.classList.add("show"), 20) setTimeout(() => t.classList.remove("show"), 4000) setTimeout(() => t.remove(), 4500) } ////////////////////// // Initial Boot // ////////////////////// // Minimal CSS injection for presentation const css = ` .hp-header{display:flex;gap:12px;align-items:center;padding:12px;background:#0b5; color:#003} .hp-title{margin:0} .hp-main{padding:16px} .hp-section{margin-bottom:24px} .hp-grid{display:flex;gap:12px;flex-wrap:wrap} .hp-card{border:1px solid #ddd;padding:12px;width:200px} .hp-card-img{width:100%;height:120px;object-fit:contain} .hp-product{display:flex;gap:16px} .hp-product-img{width:200px;height:200px;object-fit:contain} .hp-recs{margin-top:16px} .hp-footer{padding:12px;text-align:center;background:#f3f3f3} .hp-cart-btn, .hp-user-btn{padding:8px} .hp-toast{position:fixed;bottom:20px;right:20px;background:#222;color:#fff;padding:12px;border-radius:6px;opacity:0;transition:all .3s} .hp-toast.show{opacity:1;transform:translateY(-6px)} .hp-warning{color:#b00;font-weight:bold} .hp-admin-row{display:flex;gap:8px;align-items:center} ` const style = document.createElement("style") style.appendChild(document.createTextNode(css)) document.head.appendChild(style) // Ensure root exists if (!document.getElementById("app")) { const rootDiv = document.createElement("div") rootDiv.id = "app" document.body.appendChild(rootDiv) } // Boot the app App() // Expose API for testing in console (dev convenience) window.HopePharmAPI = { db: DB, apiGetProducts, apiGetProductById, apiCreateOrder, apiCreateProduct, apiUpdateProduct, apiDeleteProduct, Recommender }