diff --git a/.commandcode/settings.json b/.commandcode/settings.json index d373f99..34a0542 100644 --- a/.commandcode/settings.json +++ b/.commandcode/settings.json @@ -32,7 +32,19 @@ "Shell(python3 -c import sys,json; d=json.load(sys.stdin); print('products:', len(d.get('products',[]))); print('tags:', [t['tagName'] for t in d.get('tags',[])][:12]) 2 >& 1)", "Shell(curl -s http://localhost:4174/src/styles.css 2 > /dev/null)", "Shell(printf:*)", - "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/apps/backend && python3 - <<'EOF' import re with open('dumps/local_8_aug.sql') as f: content = f.read() # Find all CREATE TABLE positions and all REFERENCES target tables create_positions = {} # table name -> line for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(', content): create_positions[m.group(1)] = content.count('\\n', 0, m.start()) + 1 # Verify each REFERENCES target is defined before the referencing CREATE errors = [] for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(([^;]*?)\\)', content, re.S): table = m.group(1) table_line = content.count('\\n', 0, m.start()) + 1 body = m.group(2) for ref in re.findall(r'REFERENCES `?([A-Za-z_]+)`?\\(', body): if ref in create_positions and create_positions[ref] > table_line: errors.append(f\"{table} (line {table_line}) references {ref} (defined line {create_positions[ref]})\") if errors: print(\"FAIL - out of order:\") for e in errors: print(\" \", e) else: print(\"PASS - all REFERENCES resolve to tables defined earlier\") EOF)" + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/apps/backend && python3 - <<'EOF' import re with open('dumps/local_8_aug.sql') as f: content = f.read() # Find all CREATE TABLE positions and all REFERENCES target tables create_positions = {} # table name -> line for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(', content): create_positions[m.group(1)] = content.count('\\n', 0, m.start()) + 1 # Verify each REFERENCES target is defined before the referencing CREATE errors = [] for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(([^;]*?)\\)', content, re.S): table = m.group(1) table_line = content.count('\\n', 0, m.start()) + 1 body = m.group(2) for ref in re.findall(r'REFERENCES `?([A-Za-z_]+)`?\\(', body): if ref in create_positions and create_positions[ref] > table_line: errors.append(f\"{table} (line {table_line}) references {ref} (defined line {create_positions[ref]})\") if errors: print(\"FAIL - out of order:\") for e in errors: print(\" \", e) else: print(\"PASS - all REFERENCES resolve to tables defined earlier\") EOF)", + "Shell(find packages/db_helper_sqlite/src packages/db_helper_postgres/src -name \"*.ts\" | xargs wc -l | tail -5 && echo \"=== apps imports of db_helper ===\" && grep -rn \"db_helper\" apps packages --include=\"*.ts\" --include=\"*.tsx\" --include=\"*.json\" -l | grep -v node_modules | grep -v \"db_helper_sqlite/\\|db_helper_postgres/\\|\\.turbo\\|dist\" | sort -u)", + "Shell(cat apps/backend/wrangler.toml 2>/dev/null | head -30; echo \"=== package.json ===\"; cat apps/backend/package.json; echo \"=== how build/dev resolves ===\"; ls apps/backend/.wrangler/tmp/dev-*/worker.js 2>/dev/null | head -1 | xargs grep -o \"sqliteService\\|getAllSlotsWithProductsForCache\" 2>/dev/null | head -3; echo \"=== tsx alias config? ===\"; grep -rn \"tsx\\|alias\" apps/backend/package.json apps/backend/wrangler.toml 2>/dev/null | head; echo \"=== node_modules links ===\"; ls -la apps/backend/node_modules/ 2>/dev/null | grep -i \"db_helper\\|sqlite\\|postgres\" | head)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && for pkg in packages/db_helper_sqlite packages/db_helper_postgres; do echo \"########## $pkg ##########\"; for f in $(find $pkg/src -name \"*.ts\" | sort); do # relative imports only grep -oE \"from '(\\.\\.?/[^']+)'\" $f | sed \"s/from '//;s/'//\" | while read imp; do resolved=$(cd $(dirname $f) && node -e \"const p=require('path');try{const r=p.resolve('$imp');console.log(r.startsWith(process.cwd())?p.relative(process.cwd(),r):'')}catch(e){}\" 2>/dev/null) if [ -n \"$resolved\" ] && [ -f \"$resolved.ts\" ] || [ -n \"$resolved\" ] && [ -f \"$resolved\" ]; then echo \"$(echo $f | sed 's|^packages/||') -> $resolved\"; fi done; done; done 2>/dev/null | sort -u | grep -v \"db_index\\|schema.ts ->\" | head -80)", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); for (const pkg of [\"packages/db_helper_sqlite\", \"packages/db_helper_postgres\"]) { console.log(\"########## \" + pkg + \" ##########\"); const files = []; (function walk(d){ for (const e of fs.readdirSync(d)) { const p = path.join(d,e); if (fs.statSync(p).isDirectory()) walk(p); else if (e.endsWith(\".ts\")) files.push(p); } })(pkg); const edges = {}; for (const f of files) { const src = fs.readFileSync(f, \"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(src))) { const base = path.dirname(f); let target = path.resolve(base, m[1]); if (!fs.existsSync(target) && fs.existsSync(target + \".ts\")) target += \".ts\"; if (target.startsWith(process.cwd()) && fs.existsSync(target)) { const rel = path.relative(pkg, target); if (!rel.startsWith(\"..\")) { (edges[f] = edges[f] || []).push(rel); } } } } const allRel = files.map(f => path.relative(pkg, f)); const imported = new Set(Object.values(edges).flat()); const deadFiles = allRel.filter(r => r !== \"index.ts\" && !imported.has(r) && !r.includes(\"/db/seed\") && !r.includes(\"drizzle.config\")); // internal cross-file usage counts: who imports this rel path (excluding itself) for (const f of files) { const rel = path.relative(pkg, f); const importers = Object.entries(edges).filter(([src, tgts]) => tgts.includes(rel) && src !== f).map(([src]) => path.relative(pkg, src)); if (rel.endsWith(\".ts\") && importers.length) console.log(rel + \" <== imported by: \" + importers.join(\", \")); } console.log(\"--- files with NO internal importers (candidates for dead file): ---\"); console.log(deadFiles.join(\"\\n\")); } )", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); for (const pkg of [\"packages/db_helper_sqlite\", \"packages/db_helper_postgres\"]) { console.log(\"########## \" + pkg + \" ##########\"); const files = []; (function walk(d){ if (d.includes(\"node_modules\")) return; for (const e of fs.readdirSync(d)) { const p = path.join(d,e); if (fs.statSync(p).isDirectory()) walk(p); else if (e.endsWith(\".ts\")) files.push(p); } })(pkg); const imported = new Set(); const importers = {}; // target -> [sources] for (const f of files) { const src = fs.readFileSync(f, \"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(src))) { let target = path.resolve(path.dirname(f), m[1]); if (!fs.existsSync(target) && fs.existsSync(target + \".ts\")) target += \".ts\"; if (target.startsWith(pkg) && fs.existsSync(target)) { const rel = path.relative(pkg, target); imported.add(rel); (importers[rel] = importers[rel] || []).push(path.relative(pkg, f)); } } } const excluded = new Set([\"index.ts\",\"drizzle.config.ts\",\"src/db/seed.ts\",\"src/db/db_index.ts\",\"src/db/schema.ts\"]); const noImporter = files.map(f=>path.relative(pkg,f)).filter(r => !imported.has(r) && !excluded.has(r) && !r.includes(\"drizzle.config\")); console.log(\"Files never imported internally (incl. index.ts not importing them? checked separately):\"); for (const r of noImporter) console.log(\" \" + r); // now check which of those are imported by index.ts explicitly const idx = fs.readFileSync(path.join(pkg,\"index.ts\"),\"utf8\"); for (const r of noImporter) { const basename = path.basename(r, \".ts\"); if (!idx.includes(basename)) console.log(\" [also NOT in index.ts] \" + r); } } )", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); const pkg = \"packages/db_helper_sqlite\"; const idx = fs.readFileSync(path.join(pkg,\"index.ts\"),\"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(idx))) { const raw = m[1]; let target = path.resolve(pkg, raw); if (!fs.existsSync(target) && fs.existsSync(target+\".ts\")) target += \".ts\"; console.log(JSON.stringify(raw), \"exists:\", fs.existsSync(target), \"rel:\", path.relative(pkg, target), \"startsWithPkg:\", target.startsWith(pkg), \"target:\", target); } )", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); const cwd = process.cwd(); for (const pkg of [\"packages/db_helper_sqlite\", \"packages/db_helper_postgres\"]) { console.log(\"########## \" + pkg + \" ##########\"); const pkgAbs = path.resolve(pkg); const files = []; (function walk(d){ if (d.includes(\"node_modules\")) return; for (const e of fs.readdirSync(d)) { const p = path.join(d,e); if (fs.statSync(p).isDirectory()) walk(p); else if (e.endsWith(\".ts\")) files.push(p); } })(pkgAbs); const imported = new Set(); for (const f of files) { const src = fs.readFileSync(f, \"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(src))) { let target = path.resolve(path.dirname(f), m[1]); if (!fs.existsSync(target) && fs.existsSync(target + \".ts\")) target += \".ts\"; if (target.startsWith(pkgAbs) && fs.existsSync(target) && target !== f) { imported.add(path.relative(pkgAbs, target)); } } } const allRel = files.map(f => path.relative(pkgAbs, f)).sort(); console.log(\"Total ts files:\", allRel.length); for (const r of allRel) { if (r === \"index.ts\" || r.includes(\"drizzle.config\")) continue; if (!imported.has(r)) console.log(\" NEVER-IMPORTED FILE: \" + r); } } )", + "Shell(for:*)", + "Shell(do:*)", + "Shell(done:*)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && echo \"=== product.ts trpc import line & usage count ===\" && sed -n '1,40p' apps/backend/src/trpc/apis/admin-apis/apis/product.ts && echo \"=== count occurrences of each beyond import ===\" && for fn in checkUnitExists getProductImagesById replaceProductTags; do echo \"$fn: total=$(grep -c \"$fn\" apps/backend/src/trpc/apis/admin-apis/apis/product.ts)\"; done)", + "Shell(node -e const fs = require(\"fs\"); const parse = (p) => { const src = fs.readFileSync(p,\"utf8\"); const names = new Set(); // export { a, b as c, ... } from / re-export lists const re = /\\bexport\\s*\\{([^}]*)\\}/g; let m; while ((m = re.exec(src))) { const body = m[1]; for (let line of body.split(\",\")) { line = line.trim().replace(/\\/\\/.*$/,\"\").trim(); if (!line) continue; const asMatch = line.match(/^(.+?)\\s+as\\s+(.+)$/); if (asMatch) names.add(asMatch[2].trim()); else if (line.match(/^[A-Za-z_$][\\w$]*$/)) names.add(line); } } return names; }; const sqlite = parse(\"packages/db_helper_sqlite/index.ts\"); const pg = parse(\"packages/db_helper_postgres/index.ts\"); const onlySqlite = [...sqlite].filter(x=>!pg.has(x)).sort(); const onlyPg = [...pg].filter(x=>!sqlite.has(x)).sort(); console.log(\"ONLY IN SQLITE INDEX:\", onlySqlite.join(\", \")); console.log(\"ONLY IN POSTGRES INDEX:\", onlyPg.join(\", \")); )" ], "deny": [], "defaultMode": "default" diff --git a/.commandcode/taste/taste/taste.md b/.commandcode/taste/taste/taste.md index 60c4b9d..53fa3f5 100644 --- a/.commandcode/taste/taste/taste.md +++ b/.commandcode/taste/taste/taste.md @@ -26,7 +26,7 @@ - Wants feature parity maintained between the web-ui and user-ui apps (port logic/data patterns, rebuild UI per platform) — e.g., when he asks for a link in the cart page "at the coupons section" of @apps/user-ui/components/cart-page.tsx, he means mirror user-ui's coupons section (card, header, icon) in web-ui and add the requested link there; and conversely asks for features added in one app to be added to the sibling app "too" (e.g., "add the coupon redirection on the user-ui cart-page too"), expecting the agent to locate the equivalent component/route and replicate it. Confidence: 0.98 - Wants the web-ui home page section/component order to match the reference user-ui home page exactly (e.g., "on the home page have the order same as that of @apps/user-ui/.../home/index.tsx"), including when deciding placement of sections like Explore, Stores, Slots, and All Products. Confidence: 0.7 - Wants brand/logo spots to use the single real brand logo asset (shared across apps, e.g., the Freshyo splash logo) displayed as an image, not a generic/decorative icon (e.g., a "meat piece" Meat/Beef icon) — web-ui should be on par with user-ui and show the same logo; applies to favicon, PWA icons, and every in-UI branding spot (sidebar, topbar, login, home banner). Confidence: 0.85 -- Prefers dead-code audits to be documented in a markdown file. Confidence: 0.8 +- Prefers dead-code audits to be documented in a markdown file. Confidence: 0.9 - Prefers detailed technical documentation of system architecture, data models, flows, and integrations in markdown format. Confidence: 0.8 - Wants edge cases explicitly enumerated when documenting or analyzing existing code/systems. Confidence: 0.8 - Values end-to-end analysis of features (architecture, data model, flows, integrations, and edge cases) when asked to explain how something works. Confidence: 0.7 @@ -90,6 +90,9 @@ er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the - For bulk/sequential generation from a code pattern (e.g., ABC12 → ABC13...), expects numbering to continue from the HIGHEST existing value so regeneration never re-emits already-entered codes — after entering ABC12, the next batch must start at ABC13, not restart at 12 (the first matching code). Confidence: 0.6 - Dislikes UI that renders transient loading states as definitive business states — e.g., the home page showed every item as "out of stock" until slot data loaded, because the out-of-stock check treated "no slot yet" (data not loaded) as genuinely out of stock. Expects a "data loaded" guard so the UI never flashes a wrong definitive status (out of stock) before data arrives, while still applying real out-of-stock detection once loaded. Confidence: 0.7 - When deleting a record, prefers the existing soft-delete/invalidate path over hard-deleting rows: the supported delete already sets `isInvalidated: true` (keeping history/audit and avoiding broken FK joins), and a raw hard delete should only be considered when confirmed nothing references the row (no usage records), with related rows (couponApplicableUsers/Products) removed transactionally to avoid orphans. Confidence: 0.75 +- When commissioning a dead-code audit of an app/package, expects a "close analysis" that is exhaustive across every category — dead, unreachable, and unused code: orphaned files, unreachable/unlinked routes, dormant or disabled-by-flag features, dead branches and commented-out blocks, and unused imports/exports — finding "every such code which serves no purpose" rather than only obviously-unreferenced files; findings should distinguish verified-dead items from merely dormant/judgment-call items. Confidence: 0.65 +- When an analysis/audit has been produced for one app in the monorepo, expects the same analysis run for the sibling apps too — after the user-ui dead-code audit he immediately asked "now do the same for the @apps/admin-ui" — applying the identical exhaustive methodology and document style to each named app. Confidence: 0.85 +- For per-app analysis documents, expects a consistent naming pattern following the established convention (`user_ui_dpsk.md` → `admin_ui_dpsk.md`, i.e., `{app}_dpsk.md` at the repo root) rather than an ad-hoc filename — "make another md file with same naming pattern". Confidence: 0.9 e changes. Confidence: 0.95 er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the agent to mirror that pattern exactly, including details like item counts and container styling. Confidence: 0.9 als) rather than introducing new brand palettes; approval of a redesign's layout/composition does not imply approval of color or theme changes. Confidence: 0.95 diff --git a/apps/admin-ui/.detoxrc.js b/apps/admin-ui/.detoxrc.js deleted file mode 100644 index 35b91ea..0000000 --- a/apps/admin-ui/.detoxrc.js +++ /dev/null @@ -1,83 +0,0 @@ -/** @type {Detox.DetoxConfig} */ -module.exports = { - testRunner: { - args: { - '$0': 'jest', - config: 'e2e/jest.config.js' - }, - jest: { - setupTimeout: 120000 - } - }, - apps: { - 'ios.debug': { - type: 'ios.app', - binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/YOUR_APP.app', - build: 'xcodebuild -workspace ios/YOUR_APP.xcworkspace -scheme YOUR_APP -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build' - }, - 'ios.release': { - type: 'ios.app', - binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/YOUR_APP.app', - build: 'xcodebuild -workspace ios/YOUR_APP.xcworkspace -scheme YOUR_APP -configuration Release -sdk iphonesimulator -derivedDataPath ios/build' - }, - 'android.debug': { - type: 'android.apk', - binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk', - build: 'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug', - reversePorts: [ - 8081 - ] - }, - 'android.release': { - type: 'android.apk', - binaryPath: 'android/app/build/outputs/apk/release/app-release.apk', - build: 'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release' - } - }, - devices: { - simulator: { - type: 'ios.simulator', - device: { - type: 'iPhone 15' - } - }, - attached: { - type: 'android.attached', - device: { - adbName: '.*' - } - }, - emulator: { - type: 'android.emulator', - device: { - avdName: 'Pixel_3a_API_30_x86' - } - } - }, - configurations: { - 'ios.sim.debug': { - device: 'simulator', - app: 'ios.debug' - }, - 'ios.sim.release': { - device: 'simulator', - app: 'ios.release' - }, - 'android.att.debug': { - device: 'attached', - app: 'android.debug' - }, - 'android.att.release': { - device: 'attached', - app: 'android.release' - }, - 'android.emu.debug': { - device: 'emulator', - app: 'android.debug' - }, - 'android.emu.release': { - device: 'emulator', - app: 'android.release' - } - } -}; diff --git a/apps/admin-ui/.expo/types/router.d.ts b/apps/admin-ui/.expo/types/router.d.ts index e2dc4a9..fe7d472 100644 --- a/apps/admin-ui/.expo/types/router.d.ts +++ b/apps/admin-ui/.expo/types/router.d.ts @@ -6,9 +6,9 @@ export * from 'expo-router'; declare module 'expo-router' { export namespace ExpoRouter { export interface __routes { - hrefInputParams: { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/`; params?: Router.UnknownInputParams; } | { pathname: `/login`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard` | `/dashboard`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/complaints` | `/dashboard/complaints`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/create` | `/dashboard/coupons/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons` | `/dashboard/coupons`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/reserved-coupons` | `/dashboard/coupons/reserved-coupons`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/all-items-order` | `/dashboard/customize-app/all-items-order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app` | `/dashboard/customize-app`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/popular-items` | `/dashboard/customize-app/popular-items`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/create` | `/dashboard/dashboard-banners/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners` | `/dashboard/dashboard-banners`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders` | `/dashboard/manage-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences` | `/dashboard/manage-orders/delivery-sequences`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/orders` | `/dashboard/manage-orders/orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/prices-overview` | `/dashboard/prices-overview`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/create` | `/dashboard/product-groupings/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings` | `/dashboard/product-groupings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/add` | `/dashboard/product-tags/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags` | `/dashboard/product-tags`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/order` | `/dashboard/product-tags/order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/edit` | `/dashboard/product-tags/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/add` | `/dashboard/products/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/edit` | `/dashboard/products/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products` | `/dashboard/products`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/rebalance-orders` | `/dashboard/rebalance-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/send-notifications` | `/dashboard/send-notifications`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/add` | `/dashboard/slots/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots` | `/dashboard/slots`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/slot-details` | `/dashboard/slots/slot-details`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/add` | `/dashboard/stores/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/edit` | `/dashboard/stores/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores` | `/dashboard/stores`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/user-management` | `/dashboard/user-management`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/vendor-snippets` | `/dashboard/vendor-snippets`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/edit/[id]` | `/dashboard/coupons/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/edit/[id]` | `/dashboard/dashboard-banners/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/order-details/[id]` | `/dashboard/manage-orders/order-details/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/edit/[id]` | `/dashboard/product-groupings/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/products/detail/[id]` | `/dashboard/products/detail/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/slots/edit/[id]` | `/dashboard/slots/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/user-management/[id]` | `/dashboard/user-management/[id]`, params: Router.UnknownInputParams & { id: string | number; } }; - hrefOutputParams: { pathname: Router.RelativePathString, params?: Router.UnknownOutputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownOutputParams } | { pathname: `/`; params?: Router.UnknownOutputParams; } | { pathname: `/login`; params?: Router.UnknownOutputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard` | `/dashboard`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/complaints` | `/dashboard/complaints`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/create` | `/dashboard/coupons/create`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons` | `/dashboard/coupons`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/reserved-coupons` | `/dashboard/coupons/reserved-coupons`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/all-items-order` | `/dashboard/customize-app/all-items-order`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app` | `/dashboard/customize-app`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/popular-items` | `/dashboard/customize-app/popular-items`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/create` | `/dashboard/dashboard-banners/create`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners` | `/dashboard/dashboard-banners`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders` | `/dashboard/manage-orders`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences` | `/dashboard/manage-orders/delivery-sequences`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/orders` | `/dashboard/manage-orders/orders`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/prices-overview` | `/dashboard/prices-overview`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/create` | `/dashboard/product-groupings/create`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings` | `/dashboard/product-groupings`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/add` | `/dashboard/product-tags/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags` | `/dashboard/product-tags`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/order` | `/dashboard/product-tags/order`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/edit` | `/dashboard/product-tags/edit`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/add` | `/dashboard/products/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/edit` | `/dashboard/products/edit`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/products` | `/dashboard/products`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/rebalance-orders` | `/dashboard/rebalance-orders`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/send-notifications` | `/dashboard/send-notifications`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/add` | `/dashboard/slots/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots` | `/dashboard/slots`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/slot-details` | `/dashboard/slots/slot-details`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/add` | `/dashboard/stores/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/edit` | `/dashboard/stores/edit`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores` | `/dashboard/stores`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/user-management` | `/dashboard/user-management`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/vendor-snippets` | `/dashboard/vendor-snippets`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/edit/[id]` | `/dashboard/coupons/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/edit/[id]` | `/dashboard/dashboard-banners/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/order-details/[id]` | `/dashboard/manage-orders/order-details/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/edit/[id]` | `/dashboard/product-groupings/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/products/detail/[id]` | `/dashboard/products/detail/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/slots/edit/[id]` | `/dashboard/slots/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/user-management/[id]` | `/dashboard/user-management/[id]`, params: Router.UnknownOutputParams & { id: string; } }; - href: Router.RelativePathString | Router.ExternalPathString | `/${`?${string}` | `#${string}` | ''}` | `/login${`?${string}` | `#${string}` | ''}` | `/_sitemap${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard${`?${string}` | `#${string}` | ''}` | `/dashboard${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/complaints${`?${string}` | `#${string}` | ''}` | `/dashboard/complaints${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/coupons/create${`?${string}` | `#${string}` | ''}` | `/dashboard/coupons/create${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/coupons${`?${string}` | `#${string}` | ''}` | `/dashboard/coupons${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/coupons/reserved-coupons${`?${string}` | `#${string}` | ''}` | `/dashboard/coupons/reserved-coupons${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/customize-app/all-items-order${`?${string}` | `#${string}` | ''}` | `/dashboard/customize-app/all-items-order${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/customize-app${`?${string}` | `#${string}` | ''}` | `/dashboard/customize-app${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/customize-app/popular-items${`?${string}` | `#${string}` | ''}` | `/dashboard/customize-app/popular-items${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/dashboard-banners/create${`?${string}` | `#${string}` | ''}` | `/dashboard/dashboard-banners/create${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/dashboard-banners${`?${string}` | `#${string}` | ''}` | `/dashboard/dashboard-banners${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders/delivery-sequences${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders/orders${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders/orders${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/prices-overview${`?${string}` | `#${string}` | ''}` | `/dashboard/prices-overview${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-groupings/create${`?${string}` | `#${string}` | ''}` | `/dashboard/product-groupings/create${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-groupings${`?${string}` | `#${string}` | ''}` | `/dashboard/product-groupings${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags/add${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags/order${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags/order${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags/edit${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags/edit${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products/add${`?${string}` | `#${string}` | ''}` | `/dashboard/products/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products/edit${`?${string}` | `#${string}` | ''}` | `/dashboard/products/edit${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products${`?${string}` | `#${string}` | ''}` | `/dashboard/products${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/rebalance-orders${`?${string}` | `#${string}` | ''}` | `/dashboard/rebalance-orders${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/send-notifications${`?${string}` | `#${string}` | ''}` | `/dashboard/send-notifications${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots/add${`?${string}` | `#${string}` | ''}` | `/dashboard/slots/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots${`?${string}` | `#${string}` | ''}` | `/dashboard/slots${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots/slot-details${`?${string}` | `#${string}` | ''}` | `/dashboard/slots/slot-details${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/stores/add${`?${string}` | `#${string}` | ''}` | `/dashboard/stores/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/stores/edit${`?${string}` | `#${string}` | ''}` | `/dashboard/stores/edit${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/stores${`?${string}` | `#${string}` | ''}` | `/dashboard/stores${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/user-management${`?${string}` | `#${string}` | ''}` | `/dashboard/user-management${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/vendor-snippets${`?${string}` | `#${string}` | ''}` | `/dashboard/vendor-snippets${`?${string}` | `#${string}` | ''}` | { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/`; params?: Router.UnknownInputParams; } | { pathname: `/login`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard` | `/dashboard`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/complaints` | `/dashboard/complaints`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/create` | `/dashboard/coupons/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons` | `/dashboard/coupons`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/reserved-coupons` | `/dashboard/coupons/reserved-coupons`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/all-items-order` | `/dashboard/customize-app/all-items-order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app` | `/dashboard/customize-app`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/popular-items` | `/dashboard/customize-app/popular-items`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/create` | `/dashboard/dashboard-banners/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners` | `/dashboard/dashboard-banners`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders` | `/dashboard/manage-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences` | `/dashboard/manage-orders/delivery-sequences`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/orders` | `/dashboard/manage-orders/orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/prices-overview` | `/dashboard/prices-overview`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/create` | `/dashboard/product-groupings/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings` | `/dashboard/product-groupings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/add` | `/dashboard/product-tags/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags` | `/dashboard/product-tags`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/order` | `/dashboard/product-tags/order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/edit` | `/dashboard/product-tags/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/add` | `/dashboard/products/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/edit` | `/dashboard/products/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products` | `/dashboard/products`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/rebalance-orders` | `/dashboard/rebalance-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/send-notifications` | `/dashboard/send-notifications`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/add` | `/dashboard/slots/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots` | `/dashboard/slots`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/slot-details` | `/dashboard/slots/slot-details`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/add` | `/dashboard/stores/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/edit` | `/dashboard/stores/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores` | `/dashboard/stores`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/user-management` | `/dashboard/user-management`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/vendor-snippets` | `/dashboard/vendor-snippets`; params?: Router.UnknownInputParams; } | `${'/(drawer)'}/dashboard/coupons/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/coupons/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/dashboard-banners/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/dashboard-banners/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders/order-details/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders/order-details/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-groupings/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/product-groupings/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products/detail/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/products/detail/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/slots/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/user-management/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/user-management/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | { pathname: `${'/(drawer)'}/dashboard/coupons/edit/[id]` | `/dashboard/coupons/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/edit/[id]` | `/dashboard/dashboard-banners/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/order-details/[id]` | `/dashboard/manage-orders/order-details/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/edit/[id]` | `/dashboard/product-groupings/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/products/detail/[id]` | `/dashboard/products/detail/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/slots/edit/[id]` | `/dashboard/slots/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/user-management/[id]` | `/dashboard/user-management/[id]`, params: Router.UnknownInputParams & { id: string | number; } }; + hrefInputParams: { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/`; params?: Router.UnknownInputParams; } | { pathname: `/login`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard` | `/dashboard`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/complaints` | `/dashboard/complaints`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/create` | `/dashboard/coupons/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons` | `/dashboard/coupons`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/all-items-order` | `/dashboard/customize-app/all-items-order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app` | `/dashboard/customize-app`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/popular-items` | `/dashboard/customize-app/popular-items`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/create` | `/dashboard/dashboard-banners/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners` | `/dashboard/dashboard-banners`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders` | `/dashboard/manage-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences` | `/dashboard/manage-orders/delivery-sequences`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/orders` | `/dashboard/manage-orders/orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/prices-overview` | `/dashboard/prices-overview`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/create` | `/dashboard/product-groupings/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings` | `/dashboard/product-groupings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/add` | `/dashboard/product-tags/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags` | `/dashboard/product-tags`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/order` | `/dashboard/product-tags/order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/edit` | `/dashboard/product-tags/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/add` | `/dashboard/products/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/edit` | `/dashboard/products/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products` | `/dashboard/products`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/rebalance-orders` | `/dashboard/rebalance-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/send-notifications` | `/dashboard/send-notifications`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/add` | `/dashboard/slots/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots` | `/dashboard/slots`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/slot-details` | `/dashboard/slots/slot-details`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/add` | `/dashboard/stores/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/edit` | `/dashboard/stores/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores` | `/dashboard/stores`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/user-management` | `/dashboard/user-management`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/vendor-snippets` | `/dashboard/vendor-snippets`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/edit/[id]` | `/dashboard/coupons/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/edit/[id]` | `/dashboard/dashboard-banners/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/order-details/[id]` | `/dashboard/manage-orders/order-details/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/edit/[id]` | `/dashboard/product-groupings/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/products/detail/[id]` | `/dashboard/products/detail/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/slots/edit/[id]` | `/dashboard/slots/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/user-management/[id]` | `/dashboard/user-management/[id]`, params: Router.UnknownInputParams & { id: string | number; } }; + hrefOutputParams: { pathname: Router.RelativePathString, params?: Router.UnknownOutputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownOutputParams } | { pathname: `/`; params?: Router.UnknownOutputParams; } | { pathname: `/login`; params?: Router.UnknownOutputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard` | `/dashboard`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/complaints` | `/dashboard/complaints`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/create` | `/dashboard/coupons/create`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons` | `/dashboard/coupons`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/all-items-order` | `/dashboard/customize-app/all-items-order`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app` | `/dashboard/customize-app`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/popular-items` | `/dashboard/customize-app/popular-items`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/create` | `/dashboard/dashboard-banners/create`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners` | `/dashboard/dashboard-banners`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders` | `/dashboard/manage-orders`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences` | `/dashboard/manage-orders/delivery-sequences`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/orders` | `/dashboard/manage-orders/orders`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/prices-overview` | `/dashboard/prices-overview`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/create` | `/dashboard/product-groupings/create`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings` | `/dashboard/product-groupings`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/add` | `/dashboard/product-tags/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags` | `/dashboard/product-tags`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/order` | `/dashboard/product-tags/order`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/edit` | `/dashboard/product-tags/edit`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/add` | `/dashboard/products/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/edit` | `/dashboard/products/edit`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/products` | `/dashboard/products`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/rebalance-orders` | `/dashboard/rebalance-orders`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/send-notifications` | `/dashboard/send-notifications`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/add` | `/dashboard/slots/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots` | `/dashboard/slots`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/slot-details` | `/dashboard/slots/slot-details`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/add` | `/dashboard/stores/add`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/edit` | `/dashboard/stores/edit`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores` | `/dashboard/stores`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/user-management` | `/dashboard/user-management`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/vendor-snippets` | `/dashboard/vendor-snippets`; params?: Router.UnknownOutputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/edit/[id]` | `/dashboard/coupons/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/edit/[id]` | `/dashboard/dashboard-banners/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/order-details/[id]` | `/dashboard/manage-orders/order-details/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/edit/[id]` | `/dashboard/product-groupings/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/products/detail/[id]` | `/dashboard/products/detail/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/slots/edit/[id]` | `/dashboard/slots/edit/[id]`, params: Router.UnknownOutputParams & { id: string; } } | { pathname: `${'/(drawer)'}/dashboard/user-management/[id]` | `/dashboard/user-management/[id]`, params: Router.UnknownOutputParams & { id: string; } }; + href: Router.RelativePathString | Router.ExternalPathString | `/${`?${string}` | `#${string}` | ''}` | `/login${`?${string}` | `#${string}` | ''}` | `/_sitemap${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard${`?${string}` | `#${string}` | ''}` | `/dashboard${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/complaints${`?${string}` | `#${string}` | ''}` | `/dashboard/complaints${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/coupons/create${`?${string}` | `#${string}` | ''}` | `/dashboard/coupons/create${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/coupons${`?${string}` | `#${string}` | ''}` | `/dashboard/coupons${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/customize-app/all-items-order${`?${string}` | `#${string}` | ''}` | `/dashboard/customize-app/all-items-order${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/customize-app${`?${string}` | `#${string}` | ''}` | `/dashboard/customize-app${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/customize-app/popular-items${`?${string}` | `#${string}` | ''}` | `/dashboard/customize-app/popular-items${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/dashboard-banners/create${`?${string}` | `#${string}` | ''}` | `/dashboard/dashboard-banners/create${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/dashboard-banners${`?${string}` | `#${string}` | ''}` | `/dashboard/dashboard-banners${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders/delivery-sequences${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders/orders${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders/orders${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/prices-overview${`?${string}` | `#${string}` | ''}` | `/dashboard/prices-overview${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-groupings/create${`?${string}` | `#${string}` | ''}` | `/dashboard/product-groupings/create${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-groupings${`?${string}` | `#${string}` | ''}` | `/dashboard/product-groupings${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags/add${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags/order${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags/order${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-tags/edit${`?${string}` | `#${string}` | ''}` | `/dashboard/product-tags/edit${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products/add${`?${string}` | `#${string}` | ''}` | `/dashboard/products/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products/edit${`?${string}` | `#${string}` | ''}` | `/dashboard/products/edit${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products${`?${string}` | `#${string}` | ''}` | `/dashboard/products${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/rebalance-orders${`?${string}` | `#${string}` | ''}` | `/dashboard/rebalance-orders${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/send-notifications${`?${string}` | `#${string}` | ''}` | `/dashboard/send-notifications${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots/add${`?${string}` | `#${string}` | ''}` | `/dashboard/slots/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots${`?${string}` | `#${string}` | ''}` | `/dashboard/slots${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots/slot-details${`?${string}` | `#${string}` | ''}` | `/dashboard/slots/slot-details${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/stores/add${`?${string}` | `#${string}` | ''}` | `/dashboard/stores/add${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/stores/edit${`?${string}` | `#${string}` | ''}` | `/dashboard/stores/edit${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/stores${`?${string}` | `#${string}` | ''}` | `/dashboard/stores${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/user-management${`?${string}` | `#${string}` | ''}` | `/dashboard/user-management${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/vendor-snippets${`?${string}` | `#${string}` | ''}` | `/dashboard/vendor-snippets${`?${string}` | `#${string}` | ''}` | { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/`; params?: Router.UnknownInputParams; } | { pathname: `/login`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard` | `/dashboard`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/complaints` | `/dashboard/complaints`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons/create` | `/dashboard/coupons/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/coupons` | `/dashboard/coupons`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/all-items-order` | `/dashboard/customize-app/all-items-order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app` | `/dashboard/customize-app`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/customize-app/popular-items` | `/dashboard/customize-app/popular-items`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/create` | `/dashboard/dashboard-banners/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners` | `/dashboard/dashboard-banners`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders` | `/dashboard/manage-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/delivery-sequences` | `/dashboard/manage-orders/delivery-sequences`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/orders` | `/dashboard/manage-orders/orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/prices-overview` | `/dashboard/prices-overview`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/create` | `/dashboard/product-groupings/create`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-groupings` | `/dashboard/product-groupings`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/add` | `/dashboard/product-tags/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags` | `/dashboard/product-tags`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/order` | `/dashboard/product-tags/order`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/product-tags/edit` | `/dashboard/product-tags/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/add` | `/dashboard/products/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products/edit` | `/dashboard/products/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/products` | `/dashboard/products`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/rebalance-orders` | `/dashboard/rebalance-orders`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/send-notifications` | `/dashboard/send-notifications`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/add` | `/dashboard/slots/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots` | `/dashboard/slots`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/slots/slot-details` | `/dashboard/slots/slot-details`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/add` | `/dashboard/stores/add`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores/edit` | `/dashboard/stores/edit`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/stores` | `/dashboard/stores`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/user-management` | `/dashboard/user-management`; params?: Router.UnknownInputParams; } | { pathname: `${'/(drawer)'}/dashboard/vendor-snippets` | `/dashboard/vendor-snippets`; params?: Router.UnknownInputParams; } | `${'/(drawer)'}/dashboard/coupons/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/coupons/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/dashboard-banners/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/dashboard-banners/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/manage-orders/order-details/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/manage-orders/order-details/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/product-groupings/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/product-groupings/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/products/detail/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/products/detail/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/slots/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/slots/edit/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `${'/(drawer)'}/dashboard/user-management/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | `/dashboard/user-management/${Router.SingleRoutePart}${`?${string}` | `#${string}` | ''}` | { pathname: `${'/(drawer)'}/dashboard/coupons/edit/[id]` | `/dashboard/coupons/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/dashboard-banners/edit/[id]` | `/dashboard/dashboard-banners/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/manage-orders/order-details/[id]` | `/dashboard/manage-orders/order-details/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/product-groupings/edit/[id]` | `/dashboard/product-groupings/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/products/detail/[id]` | `/dashboard/products/detail/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/slots/edit/[id]` | `/dashboard/slots/edit/[id]`, params: Router.UnknownInputParams & { id: string | number; } } | { pathname: `${'/(drawer)'}/dashboard/user-management/[id]` | `/dashboard/user-management/[id]`, params: Router.UnknownInputParams & { id: string | number; } }; } } } diff --git a/apps/admin-ui/app/(drawer)/dashboard/coupons/reserved-coupons/index.tsx b/apps/admin-ui/app/(drawer)/dashboard/coupons/reserved-coupons/index.tsx deleted file mode 100644 index 6c32c32..0000000 --- a/apps/admin-ui/app/(drawer)/dashboard/coupons/reserved-coupons/index.tsx +++ /dev/null @@ -1,248 +0,0 @@ -import React, { useState, useCallback, useMemo } from 'react'; -import { View, TouchableOpacity, Alert, RefreshControl } from 'react-native'; -import { MaterialCommunityIcons } from '@expo/vector-icons'; -import { LinearGradient } from 'expo-linear-gradient'; -import { tw, MyButton, MyText, SearchBar, MyFlatList, useMarkDataFetchers, MyTouchableOpacity, BottomDropdown } from 'common-ui'; -import useManualRefresh from 'common-ui/hooks/useManualRefresh'; -import { trpc } from '@/src/trpc-client'; -import { useRouter } from 'expo-router'; -import { useInfiniteQuery } from '@tanstack/react-query'; - -const ReservedCouponItem = ({ item }: { item: any }) => { - const getStatus = () => { - if (item.isRedeemed) return 'redeemed'; - if (item.validTill && new Date(item.validTill) <= new Date()) return 'expired'; - return 'active'; - }; - - const status = getStatus(); - - const getBorderColor = () => { - if (status === 'active') return 'border-green-500'; - if (status === 'expired') return 'border-yellow-500'; - return 'border-blue-500'; - }; - - const getBgColor = () => { - if (status === 'active') return 'bg-green-100'; - if (status === 'expired') return 'bg-yellow-100'; - return 'bg-blue-100'; - }; - - const getTextColor = () => { - if (status === 'active') return 'text-green-600'; - if (status === 'expired') return 'text-yellow-600'; - return 'text-blue-600'; - }; - - const getIconColor = () => { - if (status === 'active') return '#10b981'; - if (status === 'expired') return '#f59e0b'; - return '#3b82f6'; - }; - - return ( - - - - - - - {item.secretCode} - Coupon: {item.couponCode} - - - - {status === 'active' ? 'Active' : status === 'expired' ? 'Expired' : 'Redeemed'} - - - - - - - Discount: {item.discountPercent ? `${item.discountPercent}% off` : item.flatDiscount ? `₹${item.flatDiscount} off` : 'N/A'} - - - Min Order: {item.minOrder ? `₹${item.minOrder}` : 'None'} - Max: {item.maxValue ? `₹${item.maxValue}` : 'None'} - - - Valid Till: {item.validTill ? new Date(item.validTill).toLocaleDateString() : 'No expiry'} - - - - {item.isRedeemed && item.redeemedUser && ( - - - Redeemed by: {item.redeemedUser.name || 'Unknown'} ({item.redeemedUser.mobile}) - - - Redeemed on: {item.redeemedAt ? new Date(item.redeemedAt).toLocaleDateString() : 'N/A'} - - - )} - - - - Created by: {item.creator?.name || 'Unknown'} - - - - ); -}; - -export default function ReservedCoupons() { - const router = useRouter(); - const [refreshing, setRefreshing] = useState(false); - const [searchQuery, setSearchQuery] = useState(''); - const [statusFilters, setStatusFilters] = useState([]); - - const { - data, - fetchNextPage, - hasNextPage, - isLoading, - isFetchingNextPage, - refetch, - } = trpc.admin.coupon.getReservedCoupons.useInfiniteQuery( - { limit: 50 }, - { - getNextPageParam: (lastPage) => lastPage.nextCursor, - } - ); - - const coupons = data?.pages.flatMap(page => page.coupons) || []; - - const getStatus = (coupon: any) => { - if (coupon.isRedeemed) return 'redeemed'; - if (coupon.validTill && new Date(coupon.validTill) <= new Date()) return 'expired'; - return 'active'; - }; - - const filteredCoupons = useMemo(() => { - let filtered = coupons.filter(coupon => - coupon.secretCode.toLowerCase().includes(searchQuery.toLowerCase()) || - coupon.couponCode.toLowerCase().includes(searchQuery.toLowerCase()) - ); - if (statusFilters.length > 0) { - filtered = filtered.filter(coupon => statusFilters.includes(getStatus(coupon))); - } - return filtered; - }, [coupons, searchQuery, statusFilters]); - - const handleRefresh = useCallback(async () => { - setRefreshing(true); - await refetch(); - setRefreshing(false); - }, [refetch]); - - useManualRefresh(() => refetch()); - - useMarkDataFetchers(() => { - refetch(); - }); - - if (isLoading) { - return ( - - - - - Loading Reserved Coupons... - - ); - } - - return ( - - - - - - setStatusFilters(value as string[])} - multiple={true} - triggerComponent={({ onPress }) => ( - - - - )} - /> - - item.id.toString()} - renderItem={({ item }) => } - refreshControl={ - - } - contentContainerStyle={tw`px-4 pb-4`} - onEndReached={() => { - if (hasNextPage && !isFetchingNextPage) { - fetchNextPage(); - } - }} - onEndReachedThreshold={0.5} - ListEmptyComponent={ - searchQuery ? ( - - - - - No Results - No reserved coupons match “{searchQuery}” - setSearchQuery('')} style={tw`bg-gray-500`}> - Clear Search - - - ) : ( - - - - - No Reserved Coupons Yet - Create your first reserved coupon to start offering secret discounts - router.push('/(drawer)/dashboard/coupons/create')} style={tw`bg-blue-500`}> - - - Create Reserved Coupon - - - - ) - } - /> - - {/* FAB for Add New Reserved Coupon */} - router.push('/(drawer)/dashboard/coupons/create')} - activeOpacity={0.95} - style={{ position: 'absolute', bottom: 32, right: 24, zIndex: 100 }} - > - - - - - - ); -} \ No newline at end of file diff --git a/apps/admin-ui/app/(drawer)/dashboard/index.tsx b/apps/admin-ui/app/(drawer)/dashboard/index.tsx index 003723e..fbc31b9 100644 --- a/apps/admin-ui/app/(drawer)/dashboard/index.tsx +++ b/apps/admin-ui/app/(drawer)/dashboard/index.tsx @@ -3,7 +3,6 @@ import { View, ScrollView, Pressable } from 'react-native'; import { useRouter } from 'expo-router'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import { MyText, tw } from 'common-ui'; -import { LinearGradient } from 'expo-linear-gradient'; import { theme } from 'common-ui/src/theme'; import { trpc } from '@/src/trpc-client'; import { useNavigationTarget } from 'common-ui/hooks/useNavigationTarget'; diff --git a/apps/admin-ui/app/(drawer)/dashboard/manage-orders/delivery-sequences/index.tsx b/apps/admin-ui/app/(drawer)/dashboard/manage-orders/delivery-sequences/index.tsx index 0519753..5013288 100644 --- a/apps/admin-ui/app/(drawer)/dashboard/manage-orders/delivery-sequences/index.tsx +++ b/apps/admin-ui/app/(drawer)/dashboard/manage-orders/delivery-sequences/index.tsx @@ -537,11 +537,6 @@ export default function DeliverySequences() { ) : ( - {/* - - Long press an item to drag and reorder - - */} ( diff --git a/apps/admin-ui/app/(drawer)/dashboard/send-notifications/index.tsx b/apps/admin-ui/app/(drawer)/dashboard/send-notifications/index.tsx index a52ddbb..f892d1b 100644 --- a/apps/admin-ui/app/(drawer)/dashboard/send-notifications/index.tsx +++ b/apps/admin-ui/app/(drawer)/dashboard/send-notifications/index.tsx @@ -14,11 +14,8 @@ import { tw, MyTextInput, BottomDropdown, - ImageUploader, } from 'common-ui'; import { trpc } from '@/src/trpc-client'; -import usePickImage from 'common-ui/src/components/use-pick-image'; -import { useUploadToObjectStorage } from '@/hooks/useUploadToObjectStore'; interface User { id: number; @@ -32,8 +29,6 @@ export default function SendNotifications() { const [selectedUserIds, setSelectedUserIds] = useState([]); const [title, setTitle] = useState(''); const [message, setMessage] = useState(''); - const [selectedImage, setSelectedImage] = useState<{ blob: Blob; mimeType: string } | null>(null); - const [displayImage, setDisplayImage] = useState<{ uri?: string } | null>(null); const [searchQuery, setSearchQuery] = useState(''); // Query users eligible for notifications @@ -41,8 +36,6 @@ export default function SendNotifications() { search: searchQuery, }); - const { uploadSingle } = useUploadToObjectStorage(); - // Send notification mutation const sendNotification = trpc.admin.user.sendNotification.useMutation({ onSuccess: () => { @@ -51,8 +44,6 @@ export default function SendNotifications() { setSelectedUserIds([]); setTitle(''); setMessage(''); - setSelectedImage(null); - setDisplayImage(null); }, onError: (error: any) => { Alert.alert('Error', error.message || 'Failed to send notification'); @@ -66,29 +57,6 @@ export default function SendNotifications() { value: user.id, })); - const handleImagePick = usePickImage({ - setFile: async (assets: any) => { - if (!assets || (Array.isArray(assets) && assets.length === 0)) { - setSelectedImage(null); - setDisplayImage(null); - return; - } - - const file = Array.isArray(assets) ? assets[0] : assets; - const response = await fetch(file.uri); - const blob = await response.blob(); - - setSelectedImage({ blob, mimeType: file.mimeType || 'image/jpeg' }); - setDisplayImage({ uri: file.uri }); - }, - multiple: false, - }); - - const handleRemoveImage = () => { - setSelectedImage(null); - setDisplayImage(null); - }; - const handleSend = async () => { if (title.trim().length === 0) { Alert.alert('Error', 'Please enter a title'); @@ -117,20 +85,11 @@ export default function SendNotifications() { } try { - let imageUrl: string | undefined; - - // Upload image if selected - if (selectedImage) { - const { key } = await uploadSingle(selectedImage.blob, selectedImage.mimeType, 'notification'); - imageUrl = key; - } - // Send notification await sendNotification.mutateAsync({ userIds: selectedUserIds, title: title.trim(), text: message.trim(), - imageUrl, }); } catch (error: any) { Alert.alert('Error', error.message || 'Failed to send notification'); @@ -196,17 +155,6 @@ export default function SendNotifications() { /> - {/* Image Upload - Hidden for now */} - {/* - Image (Optional) - - */} - {/* User Selection */} Select Users (Optional) diff --git a/apps/admin-ui/components/AddressPlaceForm.tsx b/apps/admin-ui/components/AddressPlaceForm.tsx deleted file mode 100644 index 89ea40f..0000000 --- a/apps/admin-ui/components/AddressPlaceForm.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react' -import { Formik } from 'formik' -import * as Yup from 'yup' -import { View, Text, TouchableOpacity } from 'react-native' -import { MyTextInput, BottomDropdown, tw } from 'common-ui' -import { trpc } from '@/src/trpc-client' - -interface AddressPlaceFormProps { - onSubmit: (values: { placeName: string; zoneId: number | null }) => void - onClose: () => void -} - -const AddressPlaceForm: React.FC = ({ onSubmit, onClose }) => { - const { data: zones } = trpc.admin.address.getZones.useQuery() - - const validationSchema = Yup.object({ - placeName: Yup.string().required('Place name is required'), - zoneId: Yup.number().optional(), - }) - - const zoneOptions = zones?.map(z => ({ label: z.zoneName, value: z.id })) || [] - - return ( - - Add Place - { - onSubmit(values) - onClose() - }} - > - {({ handleChange, setFieldValue, handleSubmit, values, errors, touched }) => ( - - - setFieldValue('zoneId', value as number | undefined)} - placeholder="Select Zone" - /> - - - Cancel - - handleSubmit()}> - Create - - - - )} - - - ) -} - -export default AddressPlaceForm \ No newline at end of file diff --git a/apps/admin-ui/components/AddressZoneForm.tsx b/apps/admin-ui/components/AddressZoneForm.tsx deleted file mode 100644 index db00ecd..0000000 --- a/apps/admin-ui/components/AddressZoneForm.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react' -import { Formik } from 'formik' -import * as Yup from 'yup' -import { View, Text, TouchableOpacity } from 'react-native' -import { MyTextInput, tw } from 'common-ui' - -interface AddressZoneFormProps { - onSubmit: (values: { zoneName: string }) => void - onClose: () => void -} - -const AddressZoneForm: React.FC = ({ onSubmit, onClose }) => { - const validationSchema = Yup.object({ - zoneName: Yup.string().required('Zone name is required'), - }) - - return ( - - Add Zone - { - onSubmit(values) - onClose() - }} - > - {({ handleChange, handleSubmit, values, errors, touched }) => ( - - - - - Cancel - - handleSubmit()}> - Create - - - - )} - - - ) -} - -export default AddressZoneForm \ No newline at end of file diff --git a/apps/admin-ui/components/HorizontalImageScroller.tsx b/apps/admin-ui/components/HorizontalImageScroller.tsx deleted file mode 100755 index b7afad8..0000000 --- a/apps/admin-ui/components/HorizontalImageScroller.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from "react"; -import { ScrollView, View, StyleSheet } from "react-native"; -import { ImageViewerURI } from "common-ui"; - -interface HorizontalImageScrollerProps { - urls: string[]; - imageHeight?: number; - imageWidth?: number; -} - -const HorizontalImageScroller: React.FC = ({ - urls, - imageHeight = 128, - imageWidth = 128, -}) => { - if (!urls || urls.length === 0) return null; - - - return ( - - - {urls.map((url, idx) => ( - - - - ))} - - - ); -}; - -const styles = StyleSheet.create({ - container: { - marginVertical: 8, - }, -}); - -export default HorizontalImageScroller; diff --git a/apps/admin-ui/components/StoreForm.tsx b/apps/admin-ui/components/StoreForm.tsx index fd5399e..da48a60 100644 --- a/apps/admin-ui/components/StoreForm.tsx +++ b/apps/admin-ui/components/StoreForm.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useState, useEffect, useMemo } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { View, TouchableOpacity, Alert } from 'react-native'; import { Formik } from 'formik'; import * as Yup from 'yup'; @@ -16,10 +16,6 @@ export interface StoreFormData { products: number[]; } -export interface StoreFormRef { - // Add methods if needed -} - interface StoreFormProps { mode: 'create' | 'edit'; initialValues: StoreFormData; @@ -36,8 +32,7 @@ const validationSchema = Yup.object().shape({ products: Yup.array().of(Yup.number()), }); -const StoreForm = forwardRef((props, ref) => { - const { mode, initialValues, onSubmit, isLoading, storeId } = props; +function StoreForm({ mode, initialValues, onSubmit, isLoading, storeId }: StoreFormProps) { const { data: staffData } = trpc.admin.staffUser.getStaff.useQuery(); const { data: productsData } = trpc.admin.product.getProducts.useQuery(); @@ -199,8 +194,6 @@ const StoreForm = forwardRef((props, ref) => { }} ); -}); - -StoreForm.displayName = 'StoreForm'; +} export default StoreForm; diff --git a/apps/admin-ui/components/TabNavigation.tsx b/apps/admin-ui/components/TabNavigation.tsx deleted file mode 100755 index 02ec64c..0000000 --- a/apps/admin-ui/components/TabNavigation.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { View, TouchableOpacity } from 'react-native'; -import { MyText , tw } from "common-ui"; - -interface TabNavigationProps { - tabs: { key: string; title: string }[]; - activeTab: string; - onTabChange: (tabKey: string) => void; -} - -const TabNavigation: React.FC = ({ tabs, activeTab, onTabChange }) => { - return ( - - {tabs.map((tab) => ( - onTabChange(tab.key)} - > - - {tab.title} - - - ))} - - ); -}; - -export default TabNavigation; \ No newline at end of file diff --git a/apps/admin-ui/components/UserIncidentDialog.tsx b/apps/admin-ui/components/UserIncidentDialog.tsx deleted file mode 100644 index 4842ab2..0000000 --- a/apps/admin-ui/components/UserIncidentDialog.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React, { useState } from 'react'; -import { View, TouchableOpacity } from 'react-native'; -import { MyText, tw, BottomDialog, MyTextInput } from 'common-ui'; -import { trpc } from '@/src/trpc-client'; -import MaterialIcons from '@expo/vector-icons/MaterialIcons'; -import { Alert } from 'react-native'; - -interface UserIncidentDialogProps { - orderId: number; - userId: number; - open: boolean; - onClose: () => void; - onSuccess?: () => void; -} - -export default function UserIncidentDialog({ orderId, userId, open, onClose, onSuccess }: UserIncidentDialogProps) { - const [adminComment, setAdminComment] = useState(''); - const [negativityScore, setNegativityScore] = useState(''); - - const addIncidentMutation = trpc.admin.user.addUserIncident.useMutation({ - onSuccess: () => { - Alert.alert('Success', 'Incident added successfully'); - setAdminComment(''); - setNegativityScore(''); - onClose(); - onSuccess?.(); - }, - onError: (error: any) => { - Alert.alert('Error', error.message || 'Failed to add incident'); - }, - }); - - const handleAddIncident = () => { - const score = negativityScore ? parseInt(negativityScore) : undefined; - - if (!adminComment.trim() && !negativityScore) { - Alert.alert('Error', 'Please enter a comment or negativity score'); - return; - } - - addIncidentMutation.mutate({ - userId, - orderId, - adminComment: adminComment || undefined, - negativityScore: score, - }); - }; - - return ( - - - - - - - - Add User Incident - - - Record an incident for this user. This will be visible in their profile. - - - - - - - - - - - Higher negativity scores indicate more serious incidents (e.g., repeated cancellations, abusive behavior). - - - - - - Cancel - - - - {addIncidentMutation.isPending ? 'Adding...' : 'Add Incident'} - - - - - - ); -} \ No newline at end of file diff --git a/apps/admin-ui/components/app-container.tsx b/apps/admin-ui/components/app-container.tsx deleted file mode 100755 index 50e2b54..0000000 --- a/apps/admin-ui/components/app-container.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import { AppContainer } from "common-ui"; - -export default AppContainer; \ No newline at end of file diff --git a/apps/admin-ui/components/context/auth-context.tsx b/apps/admin-ui/components/context/auth-context.tsx deleted file mode 100755 index ed365b9..0000000 --- a/apps/admin-ui/components/context/auth-context.tsx +++ /dev/null @@ -1,270 +0,0 @@ -// import React, { -// createContext, -// useContext, -// useEffect, -// useState, -// ReactNode, -// } from "react"; -// import { -// getJWT, -// deleteJWT, -// getRoles, -// saveJWT, -// saveRoles, -// saveUserId, -// getUserId, -// } from "../../hooks/useJWT"; -// import { useFocusEffect, usePathname, useRouter } from "expo-router"; -// import queryClient from "@/utils/queryClient"; -// import { DeviceEventEmitter } from "react-native"; -// import { FORCE_LOGOUT_EVENT, SESSION_EXPIRED_MSG } from "common-ui/src/lib/const-strs"; -// import { useLogin, useLogout } from "@/api-hooks/auth.api"; -// import { -// useUserResponsibilities, -// UserResponsibilities, -// } from "@/api-hooks/user.api"; -// import { InfoToast, SuccessToast } from "@/services/toaster"; -// import { useNotification } from "@/services/notif-service/notif-context"; - -// interface LoginFormInputs { -// login: string; -// password: string; -// useUsername?: boolean; -// expoPushToken?: string | null; -// } - -// interface AuthContextType { -// isLoggedIn: boolean; -// setIsLoggedIn: (value: boolean) => void; -// logout: ({ -// isSessionExpired, -// }: { -// isSessionExpired?: boolean; -// }) => Promise; -// responsibilities: UserResponsibilities | null; -// responsibilitiesLoading: boolean; -// responsibilitiesError: Error | null; -// roles: string[] | null; -// setRoles: (roles: string[] | null) => void; -// refreshRoles: () => Promise; -// loginFunc: (payload: LoginFormInputs) => Promise; -// userId: number | null; -// isLoggingIn: boolean; -// loginError?: string; -// } - -// const defaultResponsibilities: UserResponsibilities = { -// hospitalAdminFor: null, -// secretaryFor: [], -// }; - -// export const AuthContext = createContext( -// undefined -// ); - -// export const AuthProvider = ({ children }: { children: ReactNode }) => { -// const { mutate: loginApi, isPending: isLoggingIn, error: loginError } = useLogin(); -// const [isLoggedIn, setIsLoggedIn] = useState(false); -// const [roles, setRoles] = useState(null); -// const [userId, setUserId] = useState(null); - -// const refreshRoles = async () => { -// const r = await getRoles(); -// setRoles(r); -// }; - - - -// useEffect(() => { -// refreshRoles(); -// }, []); -// const { mutate: logoutApi } = useLogout(); -// const router = useRouter(); -// const [responsibilitiesError, setResponsibilitiesError] = -// useState(null); - -// const { -// data: responsibilities, -// isLoading: responsibilitiesLoading, -// isFetching: responsibilitiesFetching, -// refetch: refetchResponsibilities, -// error: queryError, -// } = useUserResponsibilities(userId); - - -// React.useEffect(() => { -// (async () => { -// const token = await getJWT(); - -// setIsLoggedIn(!!token); -// if (!token) { -// if (!pathname.includes("login")) { -// router.replace("/login" as any); -// } -// } else { -// refetchResponsibilities(); -// router.replace("/(drawer)/dashboard"); -// const userId = await getUserId(); -// setUserId(userId ? parseInt(userId) : null); -// } -// })(); -// }, []); - -// const pathname = usePathname(); - - -// const logout = async ({ -// isSessionExpired, -// }: { -// isSessionExpired?: boolean; -// }) => { - -// const pageConditon = -// pathname.includes("/login") || -// pathname.includes("/signup") || -// pathname === "/"; - -// if (!isSessionExpired) { -// logoutApi({} as any, { -// onSuccess: () => {}, -// onSettled: () => { - -// if (!pageConditon) { -// router.replace({ -// pathname: "/login" as any, -// params: isSessionExpired ? { message: SESSION_EXPIRED_MSG } : {}, -// }); -// } -// deleteJWT(); -// }, -// }); -// setIsLoggedIn(false); -// } else { -// deleteJWT(); -// setIsLoggedIn(false); -// InfoToast("Session expired. Please log in again."); -// if (!pageConditon) { -// router.replace({ -// pathname: "/login" as any, -// params: { message: SESSION_EXPIRED_MSG }, -// }); -// } -// } -// queryClient.clear(); -// }; - -// const loginFunc = async (data: LoginFormInputs) => { -// loginApi(data, { -// onSuccess: async (result) => { - -// // refetchUserId(); -// // await refetchUserData(); - -// await saveUserId(result.user.id.toString()); -// setUserId(result.user.id); - -// await saveJWT(result.token); - -// // Update login state in auth context -// setIsLoggedIn(true); - -// // Handle roles if available -// if (result.user.roles) { -// await saveRoles(result.user.roles); -// await refreshRoles(); -// } -// await refetchResponsibilities(); - -// // Clear the 'message' search param from the URL after login -// router.replace({ -// pathname: "/(drawer)/dashboard", -// params: {}, -// }); -// }, -// onError: (e: any) => { -// // setError("login", { -// // type: "manual", -// // message: e.message || "Login failed", -// // }); -// }, -// }); -// }; - -// React.useEffect(() => { -// const subscription = DeviceEventEmitter.addListener( -// FORCE_LOGOUT_EVENT, -// () => { -// logout({ isSessionExpired: true }); -// } -// ); - -// return () => { -// subscription.remove(); -// }; -// }, []); - - -// return ( -// -// {children} -// -// ); -// }; - -// export const useAuth = () => { -// const context = useContext(AuthContext); -// if (!context) { -// throw new Error("useAuth must be used within an AuthProvider"); -// } -// return context; -// }; - -// /** -// * Hook to check if the current user is a hospital admin -// * @param hospitalId Hospital ID to check against -// * @returns Boolean indicating if user is admin for that hospital -// */ -// export const useIsHospitalAdmin = (hospitalId?: number | string): boolean => { -// const { responsibilities } = useAuth(); - -// // If no hospitalId provided, return false -// if (hospitalId === undefined) { -// return false; -// } - -// // Check if user is admin for the specified hospital -// return responsibilities?.hospitalAdminFor === hospitalId; -// }; - -// /** -// * Hook to check if the current user is a secretary for a specific doctor -// * @param doctorId Doctor ID to check against -// * @returns Boolean indicating if user is a secretary for that doctor -// */ -// export const useIsDoctorSecretary = (doctorId?: number): boolean => { -// const { responsibilities } = useAuth(); - -// // If no doctorId provided, return false -// if (doctorId === undefined) { -// return false; -// } - -// // Check if user is a secretary for the specified doctor -// return responsibilities?.secretaryFor?.includes(doctorId) || false; -// }; diff --git a/apps/admin-ui/components/context/roles-context.tsx b/apps/admin-ui/components/context/roles-context.tsx deleted file mode 100755 index e8936d5..0000000 --- a/apps/admin-ui/components/context/roles-context.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { createContext, useContext, useEffect, useState, ReactNode } from "react"; -import { AuthContext } from "./auth-context"; -import { ROLE_NAMES } from "common-ui"; -// import { getRoles, saveRoles, deleteRoles } from "../../hooks/useJWT"; -// import { ROLE_NAMES } from "../../lib/constants"; - -// interface RolesContextType { -// roles: string[] | null; -// setRoles: (roles: string[] | null) => void; -// refreshRoles: () => Promise; -// } - -// const RolesContext = createContext(undefined); - -// export const RolesProvider = ({ children }: { children: ReactNode }) => { -// const [roles, setRoles] = useState(null); - -// const refreshRoles = async () => { -// const r = await getRoles(); -// setRoles(r); -// }; - -// useEffect(() => { -// refreshRoles(); -// }, []); - -// return ( -// -// {children} -// -// ); -// }; - -export const useRoles = () => { - const ctx = useContext(AuthContext); - if (!ctx) throw new Error("useRoles must be used within a RolesProvider"); - return ctx.roles; -}; - -export const useIsAdmin = () => { - const roles = useRoles(); - return roles?.includes(ROLE_NAMES.ADMIN); -} diff --git a/apps/admin-ui/components/dashboard-header.tsx b/apps/admin-ui/components/dashboard-header.tsx deleted file mode 100755 index 000f7c4..0000000 --- a/apps/admin-ui/components/dashboard-header.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import React from 'react'; -import { View, TouchableOpacity, Animated, Easing } from 'react-native'; -import { SafeAreaView } from 'react-native-safe-area-context'; -import { MyText , tw , colors } from "common-ui"; -import { Ionicons } from '@expo/vector-icons'; -import { useThemeColor } from '@/hooks/useThemeColor'; -import { IconButton } from 'react-native-paper'; - -interface DashboardHeaderProps { - onMenuPress: () => void; - onNotificationsPress: () => void; - onProfilePress: () => void; - onRefreshPress?: () => void; - refreshing?: boolean; -} - -const DashboardHeader: React.FC = ({ - onMenuPress, - onNotificationsPress, - onProfilePress, - onRefreshPress, - refreshing = false -}) => { - const accentColor = useThemeColor({ light: '#4f46e5', dark: '#818cf8' }, 'tint'); - - // For the refresh animation - const spinAnim = React.useRef(new Animated.Value(0)).current; - - // Update animation when refreshing prop changes - React.useEffect(() => { - let animation: Animated.CompositeAnimation | null = null; - - if (refreshing) { - animation = Animated.loop( - Animated.timing(spinAnim, { - toValue: 1, - duration: 1000, - easing: Easing.linear, - useNativeDriver: true, - }) - ); - animation.start(); - } else { - spinAnim.stopAnimation(); - spinAnim.setValue(0); - } - - return () => { - if (animation) { - animation.stop(); - } - }; - }, [refreshing]); - - const spin = spinAnim.interpolate({ - inputRange: [0, 1], - outputRange: ['0deg', '360deg'], - }); - - return ( - - - {/* Menu Button */} - - - - - {/* Logo/App Name */} - - HealthPetal - - - {/* Right Actions */} - - {/* Refresh Button */} - {onRefreshPress && ( - - - - )} - - {/* Notifications */} - - - {/* Notification Badge */} - - - - {/* Profile */} - - - - - - - ); -}; - -export default DashboardHeader; \ No newline at end of file diff --git a/apps/admin-ui/components/date-time-picker.tsx b/apps/admin-ui/components/date-time-picker.tsx deleted file mode 100755 index ca43829..0000000 --- a/apps/admin-ui/components/date-time-picker.tsx +++ /dev/null @@ -1,278 +0,0 @@ -// import { useTheme } from "@/hooks/theme-context"; -import { MaterialCommunityIcons } from "@expo/vector-icons"; -import DateTimePicker, { - AndroidNativeProps, - DateTimePickerAndroid, - DateTimePickerEvent, -} from "@react-native-community/datetimepicker"; -import React, { useState } from "react"; -import { - Modal, - Platform, - StyleSheet, - Text, - TouchableOpacity, - View, -} from "react-native"; - -import { useTheme, MyText } from "common-ui"; - -interface Props { - value: Date | null; - setValue: (date: Date | null) => void; - showLabels?: boolean; // Optional prop to control label visibility - timeOnly?: boolean; // Optional prop to show only time picker -} - -type Mode = "date" | "time" | "datetime"; - -function DateTimePickerMod(props: Props) { - const { value, setValue, showLabels = true, timeOnly = false } = props; - const [show, setShow] = useState(false); - const [mode, setMode] = useState("date"); - - const onChange = (event: DateTimePickerEvent, selectedDate?: Date) => { - const currentDate = selectedDate || value; - if (Platform.OS === "ios") setShow(false); - setValue(currentDate); - }; - - const showMode = (currentMode: Mode) => { - if (Platform.OS === "android") { - DateTimePickerAndroid.open({ - value: value || new Date(), - onChange: onChange, - mode: currentMode, - is24Hour: true, - display: "default", - } as AndroidNativeProps); - } else { - setShow(true); - setMode(currentMode); - } - }; - const showDatepicker = () => { - showMode("date"); - }; - - const showTimepicker = () => { - showMode("time"); - }; - const { theme } = useTheme(); - - return ( - - {timeOnly ? ( - - {showLabels && Select Time} - - - {value?.toLocaleTimeString([], { - hour: "2-digit", - minute: "2-digit", - }) || "Select Time"} - - - - - ) : ( - - - {showLabels && Select Date} - - {value?.toLocaleDateString() || "Select Date"} - - - - - - {showLabels && Select Time} - - - {value?.toLocaleTimeString([], { - hour: "2-digit", - minute: "2-digit", - }) || "Select Time"} - - - - - - )} - {/* Conditional rendering for iOS, as it uses the declarative API */} - {show && Platform.OS === "ios" && ( - setShow(false)} - > - - - - setShow(false)} - style={styles.doneButton} - > - Done - - - - - )} - - ); -} - -export default DateTimePickerMod; - -const styles = StyleSheet.create({ - container: { - // flex: 1, // Remove flex to avoid taking up extra space - justifyContent: "center", - alignItems: "flex-start", - padding: 0, // Reduce padding for compactness - marginBottom: 16, // Add margin for spacing in forms - }, - iconRow: { - flexDirection: "row", - alignItems: "center", - justifyContent: "center", - marginBottom: 20, - }, - iconRowSingleLine: { - flexDirection: "row", - alignItems: "center", - justifyContent: "center", - marginBottom: 0, - }, - iconNoBg: { - backgroundColor: "transparent", - borderRadius: 0, - padding: 0, - elevation: 0, - }, - spacerHorizontal: { - width: 30, - }, - spacerHorizontalSmall: { - width: 8, - }, - spacer: { - height: 20, // Add some space between buttons - }, - selectedText: { - marginTop: 30, - fontSize: 18, - fontWeight: "bold", - textAlign: "center", - }, - timeTextContainer: { - justifyContent: "center", - alignItems: "center", - }, - timeText: { - fontSize: 15, - fontWeight: "500", - color: "#333", - marginLeft: 2, - }, - dateText: { - fontSize: 15, - fontWeight: "500", - color: "#333", - marginLeft: 2, - marginRight: 2, - }, - - modalOverlay: { - flex: 1, - justifyContent: "center", - alignItems: "center", - backgroundColor: "rgba(0, 0, 0, 0.5)", - }, - pickerContainer: { - width: "80%", - backgroundColor: "white", - borderRadius: 10, - padding: 20, - elevation: 5, - }, - doneButton: { - marginTop: 10, - backgroundColor: "#007bff", - borderRadius: 5, - padding: 10, - alignItems: "center", - }, - doneButtonText: { - color: "white", - fontWeight: "bold", - }, -}); diff --git a/apps/admin-ui/components/day-account-view.tsx b/apps/admin-ui/components/day-account-view.tsx deleted file mode 100755 index 686d9e7..0000000 --- a/apps/admin-ui/components/day-account-view.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React from 'react'; -import { View } from 'react-native'; -import { MyText , tw } from "common-ui"; -import { Ionicons } from '@expo/vector-icons'; - -// Define the types -export interface DoctorWiseCount { - doctorName: string; - doctorId: number; - fee: number; - issuedTokens: number; - totalAmount: number; -} - -export interface DayAccountData { - doctorWiseCount: DoctorWiseCount[]; - date: string; - totalAmount: number; - settled: boolean; -} - -interface DayAccountViewProps { - dayData: DayAccountData; -} - -const DayAccountView: React.FC = ({ dayData }) => { - return ( - - - - {dayData.date} - - - - ₹{dayData.totalAmount} - - {dayData.settled ? ( - - - Settled - - ) : ( - - - Pending - - )} - - - - - {dayData.doctorWiseCount.map((doctor, idx) => ( - - - - {doctor.doctorName} - - - ₹{doctor.fee} × {doctor.issuedTokens} tokens - - - - ₹{doctor.totalAmount} - - - ))} - - - ); -}; - -export default DayAccountView; \ No newline at end of file diff --git a/apps/admin-ui/components/ui/IconSymbol.ios.tsx b/apps/admin-ui/components/ui/IconSymbol.ios.tsx deleted file mode 100755 index 9177f4d..0000000 --- a/apps/admin-ui/components/ui/IconSymbol.ios.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols'; -import { StyleProp, ViewStyle } from 'react-native'; - -export function IconSymbol({ - name, - size = 24, - color, - style, - weight = 'regular', -}: { - name: SymbolViewProps['name']; - size?: number; - color: string; - style?: StyleProp; - weight?: SymbolWeight; -}) { - return ( - - ); -} diff --git a/apps/admin-ui/components/ui/IconSymbol.tsx b/apps/admin-ui/components/ui/IconSymbol.tsx deleted file mode 100755 index b7ece6b..0000000 --- a/apps/admin-ui/components/ui/IconSymbol.tsx +++ /dev/null @@ -1,41 +0,0 @@ -// Fallback for using MaterialIcons on Android and web. - -import MaterialIcons from '@expo/vector-icons/MaterialIcons'; -import { SymbolWeight, SymbolViewProps } from 'expo-symbols'; -import { ComponentProps } from 'react'; -import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native'; - -type IconMapping = Record['name']>; -type IconSymbolName = keyof typeof MAPPING; - -/** - * Add your SF Symbols to Material Icons mappings here. - * - see Material Icons in the [Icons Directory](https://icons.expo.fyi). - * - see SF Symbols in the [SF Symbols](https://developer.apple.com/sf-symbols/) app. - */ -const MAPPING = { - 'house.fill': 'home', - 'paperplane.fill': 'send', - 'chevron.left.forwardslash.chevron.right': 'code', - 'chevron.right': 'chevron-right', -} as IconMapping; - -/** - * An icon component that uses native SF Symbols on iOS, and Material Icons on Android and web. - * This ensures a consistent look across platforms, and optimal resource usage. - * Icon `name`s are based on SF Symbols and require manual mapping to Material Icons. - */ -export function IconSymbol({ - name, - size = 24, - color, - style, -}: { - name: IconSymbolName; - size?: number; - color: string | OpaqueColorValue; - style?: StyleProp; - weight?: SymbolWeight; -}) { - return ; -} diff --git a/apps/admin-ui/components/ui/TabBarBackground.ios.tsx b/apps/admin-ui/components/ui/TabBarBackground.ios.tsx deleted file mode 100755 index 495b2d4..0000000 --- a/apps/admin-ui/components/ui/TabBarBackground.ios.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; -import { BlurView } from 'expo-blur'; -import { StyleSheet } from 'react-native'; - -export default function BlurTabBarBackground() { - return ( - - ); -} - -export function useBottomTabOverflow() { - return useBottomTabBarHeight(); -} diff --git a/apps/admin-ui/components/ui/TabBarBackground.tsx b/apps/admin-ui/components/ui/TabBarBackground.tsx deleted file mode 100755 index 70d1c3c..0000000 --- a/apps/admin-ui/components/ui/TabBarBackground.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// This is a shim for web and Android where the tab bar is generally opaque. -export default undefined; - -export function useBottomTabOverflow() { - return 0; -} diff --git a/apps/admin-ui/constants/Colors.ts b/apps/admin-ui/constants/Colors.ts deleted file mode 100755 index 14e6784..0000000 --- a/apps/admin-ui/constants/Colors.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Below are the colors that are used in the app. The colors are defined in the light and dark mode. - * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc. - */ - -const tintColorLight = '#0a7ea4'; -const tintColorDark = '#fff'; - -export const Colors = { - light: { - text: '#11181C', - background: '#fff', - tint: tintColorLight, - icon: '#687076', - tabIconDefault: '#687076', - tabIconSelected: tintColorLight, - }, - dark: { - text: '#ECEDEE', - background: '#151718', - tint: tintColorDark, - icon: '#9BA1A6', - tabIconDefault: '#9BA1A6', - tabIconSelected: tintColorDark, - }, -}; diff --git a/apps/admin-ui/e2e/jest.config.js b/apps/admin-ui/e2e/jest.config.js deleted file mode 100644 index 4f98020..0000000 --- a/apps/admin-ui/e2e/jest.config.js +++ /dev/null @@ -1,12 +0,0 @@ -/** @type {import('@jest/types').Config.InitialOptions} */ -module.exports = { - rootDir: '..', - testMatch: ['/e2e/**/*.test.js'], - testTimeout: 120000, - maxWorkers: 1, - globalSetup: 'detox/runners/jest/globalSetup', - globalTeardown: 'detox/runners/jest/globalTeardown', - reporters: ['detox/runners/jest/reporter'], - testEnvironment: 'detox/runners/jest/testEnvironment', - verbose: true, -}; diff --git a/apps/admin-ui/e2e/starter.test.js b/apps/admin-ui/e2e/starter.test.js deleted file mode 100644 index 054c2a1..0000000 --- a/apps/admin-ui/e2e/starter.test.js +++ /dev/null @@ -1,23 +0,0 @@ -describe('Example', () => { - beforeAll(async () => { - await device.launchApp(); - }); - - beforeEach(async () => { - await device.reloadReactNative(); - }); - - it('should have welcome screen', async () => { - await expect(element(by.id('welcome'))).toBeVisible(); - }); - - it('should show hello screen after tap', async () => { - await element(by.id('hello_button')).tap(); - await expect(element(by.text('Hello!!!'))).toBeVisible(); - }); - - it('should show world screen after tap', async () => { - await element(by.id('world_button')).tap(); - await expect(element(by.text('World!!!'))).toBeVisible(); - }); -}); diff --git a/apps/admin-ui/hooks/useColorScheme.ts b/apps/admin-ui/hooks/useColorScheme.ts deleted file mode 100755 index 17e3c63..0000000 --- a/apps/admin-ui/hooks/useColorScheme.ts +++ /dev/null @@ -1 +0,0 @@ -export { useColorScheme } from 'react-native'; diff --git a/apps/admin-ui/hooks/useColorScheme.web.ts b/apps/admin-ui/hooks/useColorScheme.web.ts deleted file mode 100755 index 7eb1c1b..0000000 --- a/apps/admin-ui/hooks/useColorScheme.web.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useEffect, useState } from 'react'; -import { useColorScheme as useRNColorScheme } from 'react-native'; - -/** - * To support static rendering, this value needs to be re-calculated on the client side for web - */ -export function useColorScheme() { - const [hasHydrated, setHasHydrated] = useState(false); - - useEffect(() => { - setHasHydrated(true); - }, []); - - const colorScheme = useRNColorScheme(); - - if (hasHydrated) { - return colorScheme; - } - - return 'light'; -} diff --git a/apps/admin-ui/hooks/useCurrentUserId.ts b/apps/admin-ui/hooks/useCurrentUserId.ts deleted file mode 100755 index 7f92190..0000000 --- a/apps/admin-ui/hooks/useCurrentUserId.ts +++ /dev/null @@ -1,13 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { getCurrentUserId } from '@/utils/getCurrentUserId'; - -export function useCurrentUserId(): {userId:number|null, refetchUserId: () => void} { - const [userId, setUserId] = useState(null); - const refetchUserId = React.useCallback(() => { - getCurrentUserId().then(setUserId); - },[]) - useEffect(() => { - getCurrentUserId().then(setUserId); - }, []); - return {userId,refetchUserId}; -} diff --git a/apps/admin-ui/hooks/useHideDrawerHeader.ts b/apps/admin-ui/hooks/useHideDrawerHeader.ts deleted file mode 100755 index c277ec2..0000000 --- a/apps/admin-ui/hooks/useHideDrawerHeader.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { useFocusEffect, useNavigation } from "expo-router"; -import React from "react"; - - -function useHideDrawerHeader() { - - const navigation = useNavigation(); - useFocusEffect(() => { - let drawerNav = navigation.getParent(); - const drawerNavList:any = []; - // Collect all parent navigators - while (drawerNav) { - drawerNavList.push(drawerNav); - drawerNav = drawerNav.getParent(); - } - - drawerNavList.at(-3)?.setOptions({ headerShown: false }); - - return () => { - drawerNavList.at(-3)?.setOptions({ headerShown: true }); - }; - }); - return null; -} - -export default useHideDrawerHeader; diff --git a/apps/admin-ui/hooks/useJWT.ts b/apps/admin-ui/hooks/useJWT.ts index 03a9246..8576f18 100755 --- a/apps/admin-ui/hooks/useJWT.ts +++ b/apps/admin-ui/hooks/useJWT.ts @@ -1,49 +1,15 @@ -// import { StorageService } from '@/lib/StorageService'; -import {StorageService} from 'common-ui'; +import { StorageService } from 'common-ui' -export const JWT_KEY = 'jwt_token'; -export const ROLES_KEY = 'user_roles'; -export const USER_ID_KEY = 'userId'; - -export async function saveUserId(userId:string) { - await StorageService.setItem(USER_ID_KEY, userId); -} - -export async function getUserId() { - return await StorageService.getItem(USER_ID_KEY); -} +export const JWT_KEY = 'jwt_token' export async function saveJWT(token: string) { - await StorageService.setItem(JWT_KEY, token); + await StorageService.setItem(JWT_KEY, token) } export async function getJWT() { - return await StorageService.getItem(JWT_KEY); + return await StorageService.getItem(JWT_KEY) } export async function deleteJWT() { - await StorageService.removeItem(JWT_KEY); -} - -export async function saveRoles(roles: string[]) { - await StorageService.setItem(ROLES_KEY, JSON.stringify(roles)); -} - -export async function getRoles(): Promise { - const jwt = await getJWT(); - if (!jwt) { - StorageService.removeItem(ROLES_KEY); - return null; - } - const rolesStr = await StorageService.getItem(ROLES_KEY); - if (!rolesStr) return null; - try { - return JSON.parse(rolesStr); - } catch { - return null; - } -} - -export async function deleteRoles() { - await StorageService.removeItem(ROLES_KEY); + await StorageService.removeItem(JWT_KEY) } diff --git a/apps/admin-ui/hooks/usePhonepeSdk.ts b/apps/admin-ui/hooks/usePhonepeSdk.ts deleted file mode 100755 index 0ba4f0a..0000000 --- a/apps/admin-ui/hooks/usePhonepeSdk.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { usePhonepeCreds } from '@/api-hooks/payment.api'; -import { useEffect } from 'react'; -import PhonePePaymentSDK from 'react-native-phonepe-pg'; - -export function usePhonepeSdk() { - const { data: creds, isLoading, isError } = usePhonepeCreds(); - - useEffect(() => { - if (creds && creds.clientId && creds.clientVersion) { - PhonePePaymentSDK.init('SANDBOX', creds.clientId, creds.clientId, true); - } - }, [creds]); - - const startTransaction = async (orderId: string, token: string) => { - try { - const request = { - orderId, - token, - merchantId: creds?.merchantId, - paymentMode: { type: 'PAY_PAGE' } - }; - const stringReq = JSON.stringify(request); - const response = await PhonePePaymentSDK.startTransaction(stringReq, null); - return response; - } catch (error) { - throw error; - } - }; - - return { startTransaction, isLoading, isError, creds }; -} diff --git a/apps/admin-ui/hooks/useThemeColor.ts b/apps/admin-ui/hooks/useThemeColor.ts deleted file mode 100755 index 0608e73..0000000 --- a/apps/admin-ui/hooks/useThemeColor.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Learn more about light and dark modes: - * https://docs.expo.dev/guides/color-schemes/ - */ - -import { Colors } from '@/constants/Colors'; -import { useColorScheme } from '@/hooks/useColorScheme'; - -export function useThemeColor( - props: { light?: string; dark?: string }, - colorName: keyof typeof Colors.light & keyof typeof Colors.dark -) { - const theme = useColorScheme() ?? 'light'; - const colorFromProps = props[theme]; - - if (colorFromProps) { - return colorFromProps; - } else { - return Colors[theme][colorName]; - } -} diff --git a/apps/admin-ui/scripts/reset-project.js b/apps/admin-ui/scripts/reset-project.js deleted file mode 100755 index 51dff15..0000000 --- a/apps/admin-ui/scripts/reset-project.js +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env node - -/** - * This script is used to reset the project to a blank state. - * It deletes or moves the /app, /components, /hooks, /scripts, and /constants directories to /app-example based on user input and creates a new /app directory with an index.tsx and _layout.tsx file. - * You can remove the `reset-project` script from package.json and safely delete this file after running it. - */ - -const fs = require("fs"); -const path = require("path"); -const readline = require("readline"); - -const root = process.cwd(); -const oldDirs = ["app", "components", "hooks", "constants", "scripts"]; -const exampleDir = "app-example"; -const newAppDir = "app"; -const exampleDirPath = path.join(root, exampleDir); - -const indexContent = `import { Text, View } from "react-native"; - -export default function Index() { - return ( - - Edit app/index.tsx to edit this screen. - - ); -} -`; - -const layoutContent = `import { Stack } from "expo-router"; - -export default function RootLayout() { - return ; -} -`; - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, -}); - -const moveDirectories = async (userInput) => { - try { - if (userInput === "y") { - // Create the app-example directory - await fs.promises.mkdir(exampleDirPath, { recursive: true }); - console.log(`📁 /${exampleDir} directory created.`); - } - - // Move old directories to new app-example directory or delete them - for (const dir of oldDirs) { - const oldDirPath = path.join(root, dir); - if (fs.existsSync(oldDirPath)) { - if (userInput === "y") { - const newDirPath = path.join(root, exampleDir, dir); - await fs.promises.rename(oldDirPath, newDirPath); - console.log(`➡️ /${dir} moved to /${exampleDir}/${dir}.`); - } else { - await fs.promises.rm(oldDirPath, { recursive: true, force: true }); - console.log(`❌ /${dir} deleted.`); - } - } else { - console.log(`➡️ /${dir} does not exist, skipping.`); - } - } - - // Create new /app directory - const newAppDirPath = path.join(root, newAppDir); - await fs.promises.mkdir(newAppDirPath, { recursive: true }); - console.log("\n📁 New /app directory created."); - - // Create index.tsx - const indexPath = path.join(newAppDirPath, "index.tsx"); - await fs.promises.writeFile(indexPath, indexContent); - console.log("📄 app/index.tsx created."); - - // Create _layout.tsx - const layoutPath = path.join(newAppDirPath, "_layout.tsx"); - await fs.promises.writeFile(layoutPath, layoutContent); - console.log("📄 app/_layout.tsx created."); - - console.log("\n✅ Project reset complete. Next steps:"); - console.log( - `1. Run \`npx expo start\` to start a development server.\n2. Edit app/index.tsx to edit the main screen.${ - userInput === "y" - ? `\n3. Delete the /${exampleDir} directory when you're done referencing it.` - : "" - }` - ); - } catch (error) { - console.error(`❌ Error during script execution: ${error.message}`); - } -}; - -rl.question( - "Do you want to move existing files to /app-example instead of deleting them? (Y/n): ", - (answer) => { - const userInput = answer.trim().toLowerCase() || "y"; - if (userInput === "y" || userInput === "n") { - moveDirectories(userInput).finally(() => rl.close()); - } else { - console.log("❌ Invalid input. Please enter 'Y' or 'N'."); - rl.close(); - } - } -); diff --git a/apps/admin-ui/services/axios-admin-ui.ts b/apps/admin-ui/services/axios-admin-ui.ts deleted file mode 100644 index 5fac5e4..0000000 --- a/apps/admin-ui/services/axios-admin-ui.ts +++ /dev/null @@ -1,59 +0,0 @@ -import axiosParent from 'axios'; -import { FORCE_LOGOUT_EVENT } from 'common-ui/src/lib/const-strs'; -import { DeviceEventEmitter } from 'react-native' -import { getJWT } from '@/hooks/useJWT'; -import { BASE_API_URL } from 'common-ui'; - -// export const API_BASE_URL = 'http://192.168.100.95:4000'; // Change to your API base URL -// const API_BASE_URL = 'https://www.technocracy.ovh/mf'; // Change to your API base URL -// const API_BASE_URL = 'http://10.195.26.42:4000'; // Change to your API base URL -// const API_BASE_URL = 'http://localhost:4000/api/mobile/'; // Change to your API base URL -// const API_BASE_URL = 'https://car-safar.com/api/mobile/'; // Change to your API base URL - -const axios = axiosParent.create({ - baseURL: BASE_API_URL + '/api/v1', - timeout: 60000, - // headers: { - // 'Content-Type': 'application/json', - // }, -}); - - -axios.interceptors.request.use( - async (config) => { - const token = await getJWT(); - - if (token) { - config.headers = config.headers || {}; - config.headers['Authorization'] = `Bearer ${token}`; - } - return config; - }, - (error) => Promise.reject(error) -); - -axios.interceptors.response.use( - (response) => response, - (error) => { - - const status = error?.status; - const msg = error.response?.data?.error; - - if (status === 401 && msg.startsWith('Access denied')) { - // Handle unauthorized access - DeviceEventEmitter.emit(FORCE_LOGOUT_EVENT); - } - const message = error?.response?.data?.error; - - if (msg) { - // Optionally, you can attach the message to the error object or throw a new error - const err = new Error(msg); - // Optionally attach the original error for debugging - (err as any).original = error; - return Promise.reject(err); - } - return Promise.reject(error); - } -); - -export default axios; diff --git a/apps/admin-ui/services/notif-service/notif-checker.tsx b/apps/admin-ui/services/notif-service/notif-checker.tsx deleted file mode 100755 index 40cd786..0000000 --- a/apps/admin-ui/services/notif-service/notif-checker.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import {useAddPushToken, useHasPushToken } from "@/api-hooks/user.api"; -import React from "react"; -import { useNotification } from "./notif-context"; -import { BottomDialog } from "common-ui"; -import { MyText } from "common-ui"; -import { View, Linking } from "react-native"; -import { tw } from "common-ui"; -import { MyButton } from "common-ui"; -import { useAuth } from "@/components/context/auth-context"; - -interface Props {} - -function NotifChecker(props: Props) { - const {} = props; - const [showPermissionDialog, setShowPermissionDialog] = React.useState(false); - - const {isLoggedIn} = useAuth(); - const { data: hasPushToken, isLoading, isError } = useHasPushToken({enabled: isLoggedIn}); - const { mutate: addPushToken } = useAddPushToken(); - const { notifPermission, expoPushToken } = useNotification(); - React.useEffect(() => { - if(isLoggedIn && !hasPushToken && notifPermission =='granted') { - addPushToken(expoPushToken!); - } - },[isLoggedIn, hasPushToken]) - - React.useEffect(() => { - if (notifPermission === "denied") { - setShowPermissionDialog(true); - } - }, [notifPermission]); - - return ( - <> - setShowPermissionDialog(false)} - > - - - Notification Permission Denied - - - It seems you have denied notification permissions. Please enable - them in your device settings. - - - setShowPermissionDialog(false)} - style={tw`flex-1`} - > - Cancel - - { - Linking.openSettings(); - }} - style={tw`flex-1`} - > - Settings - - - - - - ); -} - -export default NotifChecker; diff --git a/apps/admin-ui/services/notif-service/notif-context.tsx b/apps/admin-ui/services/notif-service/notif-context.tsx deleted file mode 100755 index 52ad74e..0000000 --- a/apps/admin-ui/services/notif-service/notif-context.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import React, { - createContext, - useContext, - useState, - useEffect, - useRef, - ReactNode, -} from "react"; -import * as Notifications from "expo-notifications"; -import { registerForPushNotificationsAsync } from "./notif-register"; -import { useRouter } from "expo-router"; -import { NotificationToast } from "../toaster"; -import { NOTIF_PERMISSION_DENIED } from "common-ui/src/lib/const-strs"; - -interface NotificationContextType { - expoPushToken: string | null; - notification: Notifications.Notification | null; - error: Error | null; - notifPermission: 'pending' | 'granted' | 'denied' -} - -export const NotificationContext = createContext< - NotificationContextType | undefined ->(undefined); - -export const useNotification = () => { - const context = useContext(NotificationContext); - if (context === undefined) { - throw new Error( - "useNotification must be used within a NotificationProvider" - ); - } - return context; -}; - -interface NotificationProviderProps { - children: ReactNode; -} - -export const NotificationProvider: React.FC = ({ - children, -}) => { - const [expoPushToken, setExpoPushToken] = useState(null); - const [notification, setNotification] = - useState(null); - const [error, setError] = useState(null); - const [notifPermission, setNotifPermission] = React.useState("pending"); - - const notificationListener = useRef(null); - const responseListener = useRef(null); - const router = useRouter(); - - useEffect(() => { - registerForPushNotificationsAsync() - .then((token) => { - setExpoPushToken(token); - setNotifPermission("granted"); - }) - .catch((errorRaw) => { - - const err = String(errorRaw).slice(7); //remove the "Error: " string component in beginning - - if (err === NOTIF_PERMISSION_DENIED) { - setNotifPermission("denied"); - } - }); - - notificationListener.current = - Notifications.addNotificationReceivedListener((notification) => { - setNotification(notification); - // Show a visible toast when app is in foreground - const content = notification.request?.content; - if (content) { - NotificationToast( - content.title || "Notification", - content.body || "", - content.data || {} - ); - } - }); - - responseListener.current = - Notifications.addNotificationResponseReceivedListener((response) => { - const data = response.notification.request.content.data; - if (data && data.doctorId) { - router.navigate(`/(drawer)/dashboard`); - } else if (data && data.tokenId) { - router.navigate(`/(drawer)/dashboard`); - } - }); - - return () => { - if (notificationListener.current) { - Notifications.removeNotificationSubscription( - notificationListener.current - ); - } - if (responseListener.current) { - Notifications.removeNotificationSubscription(responseListener.current); - } - }; - }, []); - - return ( - - {children} - - ); -}; diff --git a/apps/admin-ui/services/notif-service/notif-register.ts b/apps/admin-ui/services/notif-service/notif-register.ts deleted file mode 100755 index dc317f6..0000000 --- a/apps/admin-ui/services/notif-service/notif-register.ts +++ /dev/null @@ -1,51 +0,0 @@ -import * as Notifications from "expo-notifications"; -import * as Device from "expo-device"; -import Constants from "expo-constants"; -import { Platform } from "react-native"; -import { NOTIF_PERMISSION_DENIED } from "common-ui/src/lib/const-strs"; - -export async function registerForPushNotificationsAsync() { - if (Platform.OS === "android") { - await Notifications.setNotificationChannelAsync("default", { - name: "default", - importance: Notifications.AndroidImportance.MAX, - vibrationPattern: [0, 250, 250, 250], - lightColor: "#FF231F7C", - }); - } - - if (Device.isDevice) { - const { status: existingStatus } = - await Notifications.getPermissionsAsync(); - let finalStatus = existingStatus; - if (existingStatus !== "granted") { - const { status } = await Notifications.requestPermissionsAsync(); - finalStatus = status; - } - - if (finalStatus !== "granted") { - throw new Error( - NOTIF_PERMISSION_DENIED - ); - } - const projectId = - Constants?.expoConfig?.extra?.eas?.projectId ?? - Constants?.easConfig?.projectId; - if (!projectId) { - throw new Error("Project ID not found"); - } - try { - const pushTokenString = ( - await Notifications.getExpoPushTokenAsync({ - projectId, - }) - ).data; - console.log(pushTokenString); - return pushTokenString; - } catch (e: unknown) { - throw new Error(`${e}`); - } - } else { - throw new Error("Must use physical device for push notifications"); - } -} \ No newline at end of file diff --git a/apps/admin-ui/src/api-hooks/banner.api.ts b/apps/admin-ui/src/api-hooks/banner.api.ts deleted file mode 100644 index cdcefbe..0000000 --- a/apps/admin-ui/src/api-hooks/banner.api.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Types -export interface Banner { - id: number; - name: string; - imageUrl: string; - description?: string; - skuIds?: number[]; - redirectUrl?: string; - serialNum: number; - isActive: boolean; - createdAt: string; - lastUpdated: string; -} - -export interface CreateBannerPayload { - name: string; - imageUrl: string; - description?: string; - skuIds?: number[]; - redirectUrl?: string; - serialNum: number; -} - -export interface UpdateBannerPayload extends Partial { - isActive?: boolean; -} diff --git a/apps/admin-ui/src/components/CouponForm.tsx b/apps/admin-ui/src/components/CouponForm.tsx index 1e33c2e..a6b94d9 100644 --- a/apps/admin-ui/src/components/CouponForm.tsx +++ b/apps/admin-ui/src/components/CouponForm.tsx @@ -150,7 +150,6 @@ export default function CouponForm({ onSubmit, isLoading, initialValues }: Coupo const newSelection = current.includes(userId) ? current.filter(id => id !== userId) : [...current, userId]; - console.log('Toggling user:', userId, 'New selection:', newSelection); setFieldValue('applicableUsers', newSelection); }; diff --git a/apps/admin-ui/utils/getCurrentUserId.ts b/apps/admin-ui/utils/getCurrentUserId.ts deleted file mode 100755 index d2a8af4..0000000 --- a/apps/admin-ui/utils/getCurrentUserId.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {jwtDecode} from 'jwt-decode'; -import { getJWT } from '@/hooks/useJWT'; - -export async function getCurrentUserId(): Promise { - const token = await getJWT(); - if (!token) return null; - try { - const decoded: any = jwtDecode(token); - // Adjust this if your JWT uses a different field for user id - return decoded.id || decoded.userId || null; - } catch { - return null; - } -} diff --git a/apps/user-ui/app/(drawer)/(tabs)/me/about/_layout.tsx b/apps/user-ui/app/(drawer)/(tabs)/me/about/_layout.tsx deleted file mode 100644 index 51cdaa5..0000000 --- a/apps/user-ui/app/(drawer)/(tabs)/me/about/_layout.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Stack } from 'expo-router' - -function AboutLayout() { - return ( - - ) -} - -export default AboutLayout \ No newline at end of file diff --git a/apps/user-ui/app/(drawer)/(tabs)/me/about/index.tsx b/apps/user-ui/app/(drawer)/(tabs)/me/about/index.tsx deleted file mode 100644 index 845bbd1..0000000 --- a/apps/user-ui/app/(drawer)/(tabs)/me/about/index.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import React from 'react'; -import { View, ScrollView, Linking } from 'react-native'; -import { Image } from 'expo-image'; -import { AppContainer, MyText, tw, MyTouchableOpacity } from 'common-ui'; -import MaterialIcons from '@expo/vector-icons/MaterialIcons'; -import FontAwesome5 from '@expo/vector-icons/FontAwesome5'; - -export default function About() { - const openLink = (url: string) => { - Linking.openURL(url).catch((err) => {}); - }; - - return ( - - - {/* Hero Section */} - - - - - - - - Meat Farmer - - - Bringing local trust and online convenience together. - - - - - {/* Mission Cards */} - - Our Mission - - - - - - Local Roots - Based in MBNR, supporting our community. - - - - - - Best Price - Minimizing costs to enhance your buying experience. - - - - - - Quality First - Committed to fresh, high-quality meat products. - - - - - - Farmers First - Dedicated to supporting local farmers. - - - - - {/* Sourcing Section */} - - - - - - - Sourcing & Quality - - - - - - - All items are procured directly from authorized dealers. - - - - - - 100% local products sourced from trusted suppliers. - - - - - - All products are purely Halal certified. - - - - - - - {/* Payments & Refunds Section */} - - - - - - - Payments & Refunds - - - - - Payment Options: Online or Cash on Delivery (COD). - - - Complaints: Must be raised within 12 hours of delivery. - - - - - - - - Refunds are processed to the original payment method. - - - - - - Alternatively, receive a refund coupon for future purchases. - - - - - - Processing time: Up to 3 business days. - - - - - - - {/* Footer */} - - Follow us - - - - - - - - - - - - - © 2024 Meat Farmer. All rights reserved. - - - - - ); -} \ No newline at end of file diff --git a/apps/user-ui/app/(drawer)/(tabs)/me/my-orders/index.tsx b/apps/user-ui/app/(drawer)/(tabs)/me/my-orders/index.tsx index 119b25c..57f308e 100755 --- a/apps/user-ui/app/(drawer)/(tabs)/me/my-orders/index.tsx +++ b/apps/user-ui/app/(drawer)/(tabs)/me/my-orders/index.tsx @@ -561,34 +561,6 @@ export default function MyOrders() { createRazorpayOrderMutation.mutate({ orderId: orderId.toString() }); }; - // const initiateRazorpayPayment = (razorpayOrderId: string, key: string, amount: number) => { - // const options = { - // key, - // amount: amount * 100, // in paisa - // currency: 'INR', - // order_id: razorpayOrderId, - // name: 'Meat Farmer', - // description: 'Order Payment Retry', - // prefill: { - // // Add user details if available - // }, - // }; - - // RazorpayCheckout.open(options) - // .then((data: any) => { - // // Payment success - // verifyPaymentMutation.mutate({ - // razorpay_payment_id: data.razorpay_payment_id, - // razorpay_order_id: data.razorpay_order_id, - // razorpay_signature: data.razorpay_signature, - // }); - // }) - // .catch((error: any) => { - // Alert.alert('Payment Failed', 'Payment failed. Please try again.'); - // refetch(); - // }); - // }; - if (isLoading && currentPage === 1) { return ( diff --git a/apps/user-ui/app/_layout.tsx b/apps/user-ui/app/_layout.tsx index f6da538..4efd7af 100755 --- a/apps/user-ui/app/_layout.tsx +++ b/apps/user-ui/app/_layout.tsx @@ -8,7 +8,7 @@ import { Stack } from "expo-router"; import "react-native-reanimated"; import { useColorScheme } from "@/hooks/useColorScheme"; -import { Appearance, Dimensions, StatusBar, View } from "react-native"; +import { Appearance, StatusBar, View } from "react-native"; import { QueryClientProvider } from "@tanstack/react-query"; import { theme , MyStatusBar } from "common-ui"; import queryClient from "@/utils/queryClient"; @@ -37,8 +37,6 @@ export default function RootLayout() { SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"), }); - console.log('from layout') - React.useEffect(() => { Appearance.setColorScheme('light') }, []); diff --git a/apps/user-ui/app/api/auth/authorize+api.ts b/apps/user-ui/app/api/auth/authorize+api.ts deleted file mode 100644 index 215e170..0000000 --- a/apps/user-ui/app/api/auth/authorize+api.ts +++ /dev/null @@ -1,55 +0,0 @@ -import constants from "@/src/constants"; - -const GOOGLE_CLIENT_ID = constants.GOOGLE_CLIENT_ID; -export async function GET(request: Request) { - - if (!GOOGLE_CLIENT_ID) { - return Response.json( - { error: "Missing GOOGLE_CLIENT_ID environment variable" }, - { status: 500 } - ); - } - - const url = new URL(request.url); - let idpClientId: string; - - const internalClient = url.searchParams.get("client_id"); - - const redirectUri = url.searchParams.get("redirect_uri"); - - - let platform; - - if (redirectUri === constants.APP_SCHEME) { - platform = "mobile"; - } else if (redirectUri === constants.BASE_URL) { - platform = "web"; - } else { - return Response.json({ error: "Invalid redirect_uri" }, { status: 400 }); - } - - // use state to drive redirect back to platform - let state = platform + "|" + url.searchParams.get("state"); - - if (internalClient === "google") { - idpClientId = GOOGLE_CLIENT_ID; - } else { - return Response.json({ error: "Invalid client" }, { status: 400 }); - } - - // additional enforcement - if (!state) { - return Response.json({ error: "Invalid state" }, { status: 400 }); - } - - const params = new URLSearchParams({ - client_id: idpClientId, - redirect_uri: constants.BASE_URL + "/api/auth/callback", - response_type: "code", - scope: url.searchParams.get("scope") || "identity", - state: state, - prompt: "select_account", - }); - - return Response.redirect(constants.GOOGLE_AUTH_URL + "?" + params.toString()); -} \ No newline at end of file diff --git a/apps/user-ui/app/api/auth/callback+api.ts b/apps/user-ui/app/api/auth/callback+api.ts deleted file mode 100644 index 06ac1d2..0000000 --- a/apps/user-ui/app/api/auth/callback+api.ts +++ /dev/null @@ -1,28 +0,0 @@ -// import { BASE_URL, APP_SCHEME } from "@/utils/constants"; - -import constants from "@/src/constants"; - -const BASE_URL = constants.BASE_URL; -const APP_SCHEME = constants.APP_SCHEME; - -export async function GET(request: Request) { - const incomingParams = new URLSearchParams(request.url.split("?")[1]); - const combinedPlatformAndState = incomingParams.get("state"); - if (!combinedPlatformAndState) { - return Response.json({ error: "Invalid state" }, { status: 400 }); - } - // strip platform to return state as it was set on the client - const platform = combinedPlatformAndState.split("|")[0]; - const state = combinedPlatformAndState.split("|")[1]; - - const outgoingParams = new URLSearchParams({ - code: incomingParams.get("code")?.toString() || "", - state, - }); - - return Response.redirect( - (platform === "web" ? BASE_URL : APP_SCHEME) + - "?" + - outgoingParams.toString() - ); -} \ No newline at end of file diff --git a/apps/user-ui/app/api/auth/token+api.ts b/apps/user-ui/app/api/auth/token+api.ts deleted file mode 100644 index e89e4c2..0000000 --- a/apps/user-ui/app/api/auth/token+api.ts +++ /dev/null @@ -1,3 +0,0 @@ -export async function GET(request:Request) { - -} \ No newline at end of file diff --git a/apps/user-ui/assets/images/adaptive-icon.png b/apps/user-ui/assets/images/adaptive-icon.png deleted file mode 100755 index 03d6f6b..0000000 Binary files a/apps/user-ui/assets/images/adaptive-icon.png and /dev/null differ diff --git a/apps/user-ui/assets/images/farm2door-logo.png b/apps/user-ui/assets/images/farm2door-logo.png deleted file mode 100644 index 95f9b8b..0000000 Binary files a/apps/user-ui/assets/images/farm2door-logo.png and /dev/null differ diff --git a/apps/user-ui/assets/images/freshyo-logoo.png b/apps/user-ui/assets/images/freshyo-logoo.png deleted file mode 100644 index f8d701c..0000000 Binary files a/apps/user-ui/assets/images/freshyo-logoo.png and /dev/null differ diff --git a/apps/user-ui/assets/images/freshyo-logoo.svg b/apps/user-ui/assets/images/freshyo-logoo.svg deleted file mode 100644 index 345afcf..0000000 --- a/apps/user-ui/assets/images/freshyo-logoo.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/user-ui/assets/images/logo_mini.jpg b/apps/user-ui/assets/images/logo_mini.jpg deleted file mode 100644 index 4782a53..0000000 Binary files a/apps/user-ui/assets/images/logo_mini.jpg and /dev/null differ diff --git a/apps/user-ui/assets/images/partial-react-logo.png b/apps/user-ui/assets/images/partial-react-logo.png deleted file mode 100755 index 66fd957..0000000 Binary files a/apps/user-ui/assets/images/partial-react-logo.png and /dev/null differ diff --git a/apps/user-ui/assets/images/react-logo.png b/apps/user-ui/assets/images/react-logo.png deleted file mode 100755 index 9d72a9f..0000000 Binary files a/apps/user-ui/assets/images/react-logo.png and /dev/null differ diff --git a/apps/user-ui/assets/images/react-logo@2x.png b/apps/user-ui/assets/images/react-logo@2x.png deleted file mode 100755 index 2229b13..0000000 Binary files a/apps/user-ui/assets/images/react-logo@2x.png and /dev/null differ diff --git a/apps/user-ui/assets/images/react-logo@3x.png b/apps/user-ui/assets/images/react-logo@3x.png deleted file mode 100755 index a99b203..0000000 Binary files a/apps/user-ui/assets/images/react-logo@3x.png and /dev/null differ diff --git a/apps/user-ui/assets/images/splash-icon.png b/apps/user-ui/assets/images/splash-icon.png deleted file mode 100755 index 03d6f6b..0000000 Binary files a/apps/user-ui/assets/images/splash-icon.png and /dev/null differ diff --git a/apps/user-ui/assets/images/symbuyote.png b/apps/user-ui/assets/images/symbuyote.png deleted file mode 100644 index 4f32b0c..0000000 Binary files a/apps/user-ui/assets/images/symbuyote.png and /dev/null differ diff --git a/apps/user-ui/components/BannerCarousel.tsx b/apps/user-ui/components/BannerCarousel.tsx deleted file mode 100644 index 6d0a811..0000000 --- a/apps/user-ui/components/BannerCarousel.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import React, { useState, useRef, useEffect } from 'react'; -import { View, Dimensions, Image, ScrollView, NativeSyntheticEvent, NativeScrollEvent } from 'react-native'; -import { MyTouchableOpacity, MyText, tw } from 'common-ui'; -import { useRouter } from 'expo-router'; -import { useBanners } from '@/src/hooks/prominent-api-hooks'; -import MaterialIcons from '@expo/vector-icons/MaterialIcons'; - -const { width: screenWidth } = Dimensions.get('window'); - -interface Banner { - id: number; - name: string; - imageUrl: string; - description?: string | null; - skuIds?: number[] | null; - redirectUrl?: string | null; - serialNum?: number | null; - isActive: boolean; -} - -export default function BannerCarousel() { - const router = useRouter(); - const scrollViewRef = useRef(null); - const [currentIndex, setCurrentIndex] = useState(0); - const [isAutoPlaying, setIsAutoPlaying] = useState(true); - - // Fetch banners data - const { data: bannersData, isLoading, error } = useBanners(); - - const banners = bannersData?.banners || []; - - // Auto-play functionality - useEffect(() => { - if (banners.length <= 1 || !isAutoPlaying) return; // Don't auto-play if conditions not met - - const interval = setInterval(() => { - setCurrentIndex((prevIndex) => { - const nextIndex = (prevIndex + 1) % banners.length; - // Auto-scroll to next slide - if (scrollViewRef.current) { - scrollViewRef.current.scrollTo({ - x: nextIndex * (screenWidth - 32), - animated: true, - }); - } - return nextIndex; - }); - }, 6000); // 6 seconds - - return () => clearInterval(interval); // Cleanup on unmount - }, [banners.length, isAutoPlaying]); - - if (isLoading) { - return ( - - Loading banners... - - ); - } - - if (error || !banners || banners.length === 0) return null; - - const handleBannerPress = (banner: Banner) => { - if (banner.skuIds && banner.skuIds.length > 0) { - // Navigate to the first product's detail page - router.push(`/(drawer)/(tabs)/home/product-detail/${banner.skuIds[0]}`); - } else if (banner.redirectUrl) { - // Handle external URL - could open in browser or handle deep links - } - // If no skuIds or redirectUrl, banner is just for display - }; - - const handleScroll = (event: NativeSyntheticEvent) => { - const slideSize = screenWidth - 32; // width minus horizontal padding - const index = Math.round(event.nativeEvent.contentOffset.x / slideSize); - setCurrentIndex(index); - }; - - const goToSlide = (index: number) => { - setIsAutoPlaying(false); // Pause auto-play when user manually navigates - if (scrollViewRef.current) { - scrollViewRef.current.scrollTo({ - x: index * (screenWidth - 32), - animated: true, - }); - } - setCurrentIndex(index); - // Resume auto-play after a short delay - setTimeout(() => setIsAutoPlaying(true), 1000); - }; - - return ( - - setIsAutoPlaying(false)} - onTouchEnd={() => setIsAutoPlaying(true)} - onMomentumScrollEnd={() => setIsAutoPlaying(true)} - > - {banners.map((banner: Banner) => ( - handleBannerPress(banner)} - style={tw`mr-4 rounded-2xl overflow-hidden`} - activeOpacity={0.9} - > - - - ))} - - - {/* Pagination Dots */} - {banners.length > 1 && ( - - {banners.map((_: Banner, index: number) => ( - goToSlide(index)} - style={tw`mx-1`} - > - - - ))} - - )} - - ); -} diff --git a/apps/user-ui/components/PaymentAndOrderComponent.tsx b/apps/user-ui/components/PaymentAndOrderComponent.tsx index 72025a7..3a3af7e 100644 --- a/apps/user-ui/components/PaymentAndOrderComponent.tsx +++ b/apps/user-ui/components/PaymentAndOrderComponent.tsx @@ -94,15 +94,6 @@ const PaymentAndOrderComponent: React.FC = ({ }, }); - // const createRazorpayOrderMutation = trpc.user.payment.createRazorpayOrder.useMutation({ - // onSuccess: (paymentData) => { - // initiateRazorpayPayment(paymentData.razorpayOrderId, paymentData.key, finalTotal); - // }, - // onError: (error: any) => { - // Alert.alert('Error', error.message || 'Failed to create payment order'); - // }, - // }); - const verifyPaymentMutation = trpc.user.payment.verifyPayment.useMutation({ onSuccess: () => { const orders = placeOrderMutation.data?.data || []; @@ -167,51 +158,6 @@ const PaymentAndOrderComponent: React.FC = ({ placeOrderMutation.mutate(orderData); }; - // const initiateRazorpayPayment = (razorpayOrderId: string, key: string, amount: number) => { - // const options = { - // key, - // amount: amount * 100, - // currency: 'INR', - // order_id: razorpayOrderId, - // name: 'Meat Farmer', - // description: 'Order Payment', - // prefill: {}, - // }; - - // RazorpayCheckout.open(options) - // .then((data: any) => { - // verifyPaymentMutation.mutate({ - // razorpay_payment_id: data.razorpay_payment_id, - // razorpay_order_id: data.razorpay_order_id, - // razorpay_signature: data.razorpay_signature, - // }); - // }) - // .catch((error: any) => { - // markPaymentFailedMutation.mutate({ merchantOrderId: razorpayOrderId }); - // Alert.alert( - // 'Payment Failed', - // 'Payment failed or was cancelled. What would you like to do?', - // [ - // { - // text: 'Retry Now', - // onPress: () => { - // const orders = placeOrderMutation.data?.data || []; - // const firstOrder = orders[0]; - // const orderId = firstOrder?.id.toString(); - // if (orderId) { - // createRazorpayOrderMutation.mutate({ orderId }); - // } - // } - // }, - // { - // text: 'Retry Later', - // onPress: () => router.push('/(drawer)/(tabs)/me/my-orders') - // } - // ] - // ); - // }); - // }; - return ( <> {/* Back Button */} diff --git a/apps/user-ui/constants/Colors.ts b/apps/user-ui/constants/Colors.ts deleted file mode 100755 index 14e6784..0000000 --- a/apps/user-ui/constants/Colors.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Below are the colors that are used in the app. The colors are defined in the light and dark mode. - * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc. - */ - -const tintColorLight = '#0a7ea4'; -const tintColorDark = '#fff'; - -export const Colors = { - light: { - text: '#11181C', - background: '#fff', - tint: tintColorLight, - icon: '#687076', - tabIconDefault: '#687076', - tabIconSelected: tintColorLight, - }, - dark: { - text: '#ECEDEE', - background: '#151718', - tint: tintColorDark, - icon: '#9BA1A6', - tabIconDefault: '#9BA1A6', - tabIconSelected: tintColorDark, - }, -}; diff --git a/apps/user-ui/hooks/useJWT.ts b/apps/user-ui/hooks/useJWT.ts index 33e742b..4590554 100755 --- a/apps/user-ui/hooks/useJWT.ts +++ b/apps/user-ui/hooks/useJWT.ts @@ -2,7 +2,6 @@ import {StorageService} from 'common-ui'; export const AUTH_TOKEN_KEY = 'authToken'; -export const ROLES_KEY = 'user_roles'; export const USER_ID_KEY = 'userId'; export async function saveUserId(userId:string) { @@ -24,26 +23,3 @@ export async function getAuthToken() { export async function deleteAuthToken() { await StorageService.removeItem(AUTH_TOKEN_KEY); } - -export async function saveRoles(roles: string[]) { - await StorageService.setItem(ROLES_KEY, JSON.stringify(roles)); -} - -export async function getRoles(): Promise { - const token = await getAuthToken(); - if (!token) { - StorageService.removeItem(ROLES_KEY); - return null; - } - const rolesStr = await StorageService.getItem(ROLES_KEY); - if (!rolesStr) return null; - try { - return JSON.parse(rolesStr); - } catch { - return null; - } -} - -export async function deleteRoles() { - await StorageService.removeItem(ROLES_KEY); -} diff --git a/apps/user-ui/services/toaster.tsx b/apps/user-ui/services/toaster.tsx index 55e6697..2d02503 100755 --- a/apps/user-ui/services/toaster.tsx +++ b/apps/user-ui/services/toaster.tsx @@ -2,40 +2,6 @@ import Toast from "react-native-toast-message"; import React from "react"; import { useRouter } from "expo-router"; -export function InfoToast(message: string) { - Toast.show({ - type: "info", - text1: message, - position: "top", - visibilityTime: 10000, - onPress: () => { - Toast.hide(); - }, - }); -} - -export function ErrorToast(message: string) { - Toast.show({ - type: "error", - text1: message, - position: "top", - onPress: () => { - Toast.hide(); - }, - }); -} - -export function SuccessToast(message: string) { - Toast.show({ - type: "success", - text1: message, - position: "top", - onPress: () => { - Toast.hide(); - }, - }); -} - export function NotificationToast(title: string, subtitle: string, data: any) { const router = useRouter(); Toast.show({ diff --git a/apps/user-ui/src/components/google-sign-in.tsx b/apps/user-ui/src/components/google-sign-in.tsx deleted file mode 100644 index 60f1876..0000000 --- a/apps/user-ui/src/components/google-sign-in.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react'; -import * as AuthSession from 'expo-auth-session'; -import * as WebBrowser from 'expo-web-browser'; -import { Button, View } from 'react-native'; -import * as Google from 'expo-auth-session/providers/google'; - - -WebBrowser.maybeCompleteAuthSession(); - -const discovery = { - authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth', - tokenEndpoint: 'https://oauth2.googleapis.com/token', -}; - - -WebBrowser.maybeCompleteAuthSession(); -export default function GoogleSignInPKCE() { - - - - - // const [request, response, promptAsync] = Google.useAuthRequest({ - // androidClientId: androidClientId, - // iosClientId: iosClientId, - // webClientId: webClientId, - // redirectUri: 'https://www.freshyo.in/oauthredirect', - // // redirectUri: AuthSession.makeRedirectUri({ scheme: 'freshyo', path: 'oauthredirect' }), - // scopes: ["openid", "profile", "email"], - // }); - - - return ( - -