From dceb30ed8c167192b78ae9755116bd414e198d94 Mon Sep 17 00:00:00 2001 From: Antigravity AI Date: Mon, 6 Jul 2026 22:10:47 +0800 Subject: [PATCH] feat: add falah-souq marketplace plugin and native falah_wallet widget - [falah-souq] new standalone plugin with [souq_marketplace] shortcode Fiverr-style service grid with Islamic luxury design (Emerald/Gold/Cream/Navy) Custom post type 'souq_service', category filter bar, card hover states - [falah_wallet] replace iframe with native balance+transactions widget Balance card with loading state, send/receive action buttons Recent transactions list, login-gated with smooth reveal CSS tokens matching Islamic design system - Rebuild falah-shortcodes.zip with updated wallet widget --- wordpress-plugins/falah-shortcodes.zip | Bin 12643 -> 29806 bytes .../assets/falah-shortcodes.css | 346 ++++++++++++++++++ .../assets/falah-shortcodes.js | 146 ++++++++ .../falah-shortcodes/falah-shortcodes.php | 101 ++++- wordpress-plugins/falah-souq.zip | Bin 0 -> 12456 bytes .../falah-souq/assets/falah-souq.css | 317 ++++++++++++++++ wordpress-plugins/falah-souq/falah-souq.php | 45 +++ .../falah-souq/includes/post-type.php | 51 +++ .../falah-souq/includes/shortcode.php | 153 ++++++++ 9 files changed, 1158 insertions(+), 1 deletion(-) create mode 100644 wordpress-plugins/falah-souq.zip create mode 100644 wordpress-plugins/falah-souq/assets/falah-souq.css create mode 100644 wordpress-plugins/falah-souq/falah-souq.php create mode 100644 wordpress-plugins/falah-souq/includes/post-type.php create mode 100644 wordpress-plugins/falah-souq/includes/shortcode.php diff --git a/wordpress-plugins/falah-shortcodes.zip b/wordpress-plugins/falah-shortcodes.zip index 23902bde88d7812777c5bf36167a7ba60ad7c102..6cf07656572a0715d0e4a18d342e7e9d3a4cc6d7 100644 GIT binary patch delta 15816 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 {}); + // ── Falah Wallet ────────────────────────────────────────────────────────── + + const walletWidget = document.getElementById('falah-wallet-widget'); + if (walletWidget) { + const balanceEl = document.getElementById('falah-wallet-balance'); + const balanceFiat = document.getElementById('falah-wallet-balance-fiat'); + const btnSend = document.getElementById('falah-wallet-btn-send'); + const btnReceive = document.getElementById('falah-wallet-btn-receive'); + const txList = document.getElementById('falah-wallet-tx-list'); + const loginPrompt = document.getElementById('falah-wallet-login-prompt'); + + const sendModal = document.getElementById('falah-wallet-send-modal'); + const receiveModal = document.getElementById('falah-wallet-receive-modal'); + + function openModal(el) { el.style.display = 'flex'; document.body.style.overflow = 'hidden'; } + function closeModal(el) { el.style.display = 'none'; document.body.style.overflow = ''; } + + if (btnSend) btnSend.addEventListener('click', () => sendModal && openModal(sendModal)); + if (btnReceive) btnReceive.addEventListener('click', () => receiveModal && openModal(receiveModal)); + + document.getElementById('falah-wallet-send-backdrop')?.addEventListener('click', () => closeModal(sendModal)); + document.getElementById('falah-wallet-send-close')?.addEventListener('click', () => closeModal(sendModal)); + document.getElementById('falah-wallet-receive-backdrop')?.addEventListener('click', () => closeModal(receiveModal)); + document.getElementById('falah-wallet-receive-close')?.addEventListener('click', () => closeModal(receiveModal)); + + // Copy address + document.getElementById('falah-wallet-copy-addr')?.addEventListener('click', function () { + const addr = document.getElementById('falah-wallet-address-text')?.textContent || ''; + if (!addr) return; + navigator.clipboard?.writeText(addr).then(() => { + this.title = 'Copied!'; + setTimeout(() => { this.title = 'Copy address'; }, 1500); + }); + }); + + // Send form + document.getElementById('falah-wallet-send-submit')?.addEventListener('click', function () { + const to = document.getElementById('falah-wallet-send-to')?.value.trim(); + const amount = parseFloat(document.getElementById('falah-wallet-send-amount')?.value); + const errEl = document.getElementById('falah-wallet-send-err'); + + if (!to || !to.startsWith('0x') || to.length < 10) { + if (errEl) errEl.textContent = 'Please enter a valid recipient address.'; + return; + } + if (!amount || amount <= 0) { + if (errEl) errEl.textContent = 'Please enter a valid amount.'; + return; + } + if (errEl) errEl.textContent = ''; + + // Redirect to wallet app with prefilled params + const base = (cfg.mobileUrl || 'https://falahos.my/mobile').replace(/\/$/, ''); + const url = `${base}/wallet/send?to=${encodeURIComponent(to)}&amount=${encodeURIComponent(amount)}`; + window.open(url, '_blank', 'noopener,noreferrer'); + closeModal(sendModal); + }); + + // Fetch wallet data from Falah Mobile REST API + function fetchWalletData() { + const base = (cfg.mobileUrl || 'https://falahos.my/mobile').replace(/\/$/, ''); + + fetch(`${base}/api/wallet/balance`, { + credentials: 'include', + headers: { 'X-WP-Nonce': cfg.nonce || '' }, + }) + .then(r => { + if (r.status === 401 || r.status === 403) throw new Error('unauthenticated'); + if (!r.ok) throw new Error('api_error'); + return r.json(); + }) + .then(data => { + if (balanceEl) balanceEl.textContent = (data.balance || '0') + ' ' + (data.currency || 'FLH'); + if (balanceFiat && data.fiat_value) balanceFiat.textContent = '≈ ' + data.fiat_value; + if (btnSend) btnSend.disabled = false; + if (btnReceive) btnReceive.disabled = false; + + // Render receive address + QR + if (data.address) { + const addrEl = document.getElementById('falah-wallet-address-text'); + if (addrEl) addrEl.textContent = data.address; + const qrInner = document.getElementById('falah-wallet-qr-inner'); + if (qrInner) { + const img = document.createElement('img'); + img.alt = 'Wallet QR Code'; + img.src = `https://api.qrserver.com/v1/create-qr-code/?data=${encodeURIComponent(data.address)}&size=160x160&margin=4`; + img.width = 160; img.height = 160; + qrInner.innerHTML = ''; + qrInner.appendChild(img); + } + } + + return fetch(`${base}/api/wallet/transactions?limit=5`, { + credentials: 'include', + headers: { 'X-WP-Nonce': cfg.nonce || '' }, + }); + }) + .then(r => r && r.ok ? r.json() : null) + .then(data => { + if (!txList || !data) return; + const items = Array.isArray(data.transactions) ? data.transactions : []; + txList.innerHTML = ''; + if (!items.length) { + txList.innerHTML = '

No transactions yet
'; + return; + } + items.forEach(tx => { + const type = tx.type === 'sent' ? 'sent' : 'received'; + const icon = type === 'sent' ? '↑' : '↓'; + const sign = type === 'sent' ? '−' : '+'; + const date = tx.date ? new Date(tx.date).toLocaleDateString('en-GB', { day: 'numeric', month: 'short' }) : ''; + const desc = tx.description || (type === 'sent' ? 'Sent' : 'Received'); + const amount = (tx.amount || '0') + ' ' + (tx.currency || 'FLH'); + + const row = document.createElement('div'); + row.className = 'falah-wallet-tx-item'; + row.innerHTML = ` +
${icon}
+
+
${escapeHtml(desc)}
+
${escapeHtml(date)}
+
+
${sign}${escapeHtml(amount)}
+ `; + txList.appendChild(row); + }); + }) + .catch(err => { + if (err.message === 'unauthenticated') { + if (balanceEl) balanceEl.textContent = '—'; + if (loginPrompt) loginPrompt.style.display = ''; + if (txList) txList.innerHTML = ''; + } else { + if (balanceEl) balanceEl.textContent = '—'; + if (txList) txList.innerHTML = '
'; + } + }); + } + + fetchWalletData(); + } + + function escapeHtml(str) { + return String(str).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); + } + })(); diff --git a/wordpress-plugins/falah-shortcodes/falah-shortcodes.php b/wordpress-plugins/falah-shortcodes/falah-shortcodes.php index 0e1fbca..e45e725 100644 --- a/wordpress-plugins/falah-shortcodes/falah-shortcodes.php +++ b/wordpress-plugins/falah-shortcodes/falah-shortcodes.php @@ -315,7 +315,106 @@ add_shortcode( 'nur_ai_chat', function ( $atts ) { // ─── [falah_wallet] ─────────────────────────────────────────────────────────── add_shortcode( 'falah_wallet', function ( $atts ) { - return falah_iframe_widget( 'Falah Wallet', '💰', '/wallet', 'Loading Falah Wallet…' ); + falah_sc_enqueue(); + $atts = shortcode_atts( [ + 'currency' => 'FLH', + 'show_tx' => 'true', + ], $atts ); + + $currency = esc_html( $atts['currency'] ); + $show_tx = filter_var( $atts['show_tx'], FILTER_VALIDATE_BOOLEAN ); + + ob_start(); + ?> +
+
+ 💰 +

Falah Wallet

+ +
+ +
+
+
Total Balance
+
+ +
+
+
+ + +
+
+ + + + +
+
+ Recent Transactions + View all → +
+
+
+
+
+
+
+
+
+ +
+ + + + +
+ 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 literal 0 HcmV?d00001 diff --git a/wordpress-plugins/falah-souq/assets/falah-souq.css b/wordpress-plugins/falah-souq/assets/falah-souq.css new file mode 100644 index 0000000..8bea227 --- /dev/null +++ b/wordpress-plugins/falah-souq/assets/falah-souq.css @@ -0,0 +1,317 @@ +/* ============================================================ + Falah Souq — Islamic Marketplace Design System + Emerald #0A5C36 · Gold #C8921A · Cream #FAF7F0 · Navy #0A1628 + ============================================================ */ + +:root { + --souq-emerald: #0A5C36; + --souq-emerald-dk: #084828; + --souq-emerald-lt: #E8F5EE; + --souq-gold: #C8921A; + --souq-gold-lt: #FFF8E6; + --souq-cream: #FAF7F0; + --souq-navy: #0A1628; + --souq-text: #1A1A2E; + --souq-muted: #6B7280; + --souq-border: #E5E0D6; + --souq-white: #FFFFFF; + --souq-shadow-sm: 0 1px 3px rgba(10,28,40,0.08), 0 1px 2px rgba(10,28,40,0.04); + --souq-shadow-md: 0 4px 16px rgba(10,28,40,0.10), 0 2px 6px rgba(10,28,40,0.06); + --souq-shadow-hover:0 8px 32px rgba(10,92,54,0.14), 0 4px 12px rgba(10,92,54,0.08); + --souq-radius: 12px; + --souq-radius-sm: 6px; + --souq-duration: 250ms; + --souq-ease: cubic-bezier(0.16, 1, 0.3, 1); +} + +/* ---- Marketplace Container ---- */ +.souq-marketplace { + font-family: 'Inter', system-ui, sans-serif; + color: var(--souq-text); + padding: clamp(1.5rem, 4vw, 3rem) 0; +} + +/* ---- Filters ---- */ +.souq-filters { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: clamp(1.5rem, 3vw, 2.5rem); +} + +.souq-filter-btn { + padding: 0.45rem 1.1rem; + border: 1.5px solid var(--souq-border); + border-radius: 999px; + background: var(--souq-white); + color: var(--souq-muted); + font-size: 0.875rem; + font-weight: 500; + cursor: pointer; + transition: all var(--souq-duration) var(--souq-ease); + line-height: 1.4; +} + +.souq-filter-btn:hover { + border-color: var(--souq-emerald); + color: var(--souq-emerald); + background: var(--souq-emerald-lt); +} + +.souq-filter-btn.active { + background: var(--souq-emerald); + border-color: var(--souq-emerald); + color: var(--souq-white); + box-shadow: 0 2px 8px rgba(10,92,54,0.25); +} + +/* ---- Grid ---- */ +.souq-grid { + display: grid; + gap: clamp(1rem, 2.5vw, 1.5rem); +} + +.souq-grid--2col { grid-template-columns: repeat(2, 1fr); } +.souq-grid--3col { grid-template-columns: repeat(3, 1fr); } +.souq-grid--4col { grid-template-columns: repeat(4, 1fr); } + +@media (max-width: 1024px) { + .souq-grid--4col { grid-template-columns: repeat(3, 1fr); } +} + +@media (max-width: 768px) { + .souq-grid--3col, + .souq-grid--4col { grid-template-columns: repeat(2, 1fr); } +} + +@media (max-width: 480px) { + .souq-grid--2col, + .souq-grid--3col, + .souq-grid--4col { grid-template-columns: 1fr; } +} + +/* ---- Card ---- */ +.souq-card { + background: var(--souq-white); + border-radius: var(--souq-radius); + border: 1px solid var(--souq-border); + overflow: hidden; + box-shadow: var(--souq-shadow-sm); + transition: transform var(--souq-duration) var(--souq-ease), + box-shadow var(--souq-duration) var(--souq-ease); +} + +.souq-card:hover { + transform: translateY(-4px); + box-shadow: var(--souq-shadow-hover); + border-color: rgba(10,92,54,0.2); +} + +.souq-card__link { + display: flex; + flex-direction: column; + height: 100%; + text-decoration: none; + color: inherit; +} + +/* ---- Thumbnail ---- */ +.souq-card__thumb { + position: relative; + aspect-ratio: 4 / 3; + overflow: hidden; + background: var(--souq-cream); +} + +.souq-card__img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 400ms var(--souq-ease); +} + +.souq-card:hover .souq-card__img { + transform: scale(1.04); +} + +.souq-card__img-placeholder { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + background: var(--souq-emerald-lt); +} + +.souq-card__img-placeholder svg { + width: 80px; + height: 60px; + opacity: 0.6; +} + +.souq-card__badge { + position: absolute; + top: 0.65rem; + left: 0.65rem; + padding: 0.2rem 0.65rem; + background: var(--souq-gold); + color: var(--souq-white); + font-size: 0.7rem; + font-weight: 600; + letter-spacing: 0.05em; + text-transform: uppercase; + border-radius: 999px; +} + +/* ---- Body ---- */ +.souq-card__body { + flex: 1; + padding: 0.9rem 1rem 0.6rem; +} + +.souq-card__seller { + display: flex; + align-items: center; + gap: 0.45rem; + margin-bottom: 0.5rem; +} + +.souq-card__seller-avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--souq-emerald); + color: var(--souq-white); + font-size: 0.7rem; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.souq-card__seller-name { + font-size: 0.78rem; + color: var(--souq-muted); + font-weight: 500; +} + +.souq-card__title { + font-size: 0.9rem; + font-weight: 600; + line-height: 1.4; + color: var(--souq-text); + margin: 0 0 0.5rem; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +/* ---- Stars ---- */ +.souq-card__rating { + display: flex; + align-items: center; + gap: 0.35rem; + margin-top: 0.4rem; +} + +.souq-card__stars { + display: flex; + gap: 1px; +} + +.souq-star { + font-size: 0.8rem; + line-height: 1; +} + +.souq-star--full { color: var(--souq-gold); } +.souq-star--half { color: var(--souq-gold); opacity: 0.6; } +.souq-star--empty { color: var(--souq-border); } + +.souq-card__rating-value { + font-size: 0.78rem; + font-weight: 700; + color: var(--souq-gold); +} + +.souq-card__reviews { + font-size: 0.75rem; + color: var(--souq-muted); +} + +/* ---- Footer ---- */ +.souq-card__footer { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.65rem 1rem 0.85rem; + border-top: 1px solid var(--souq-border); + margin-top: auto; +} + +.souq-card__delivery { + display: flex; + align-items: center; + gap: 0.3rem; + font-size: 0.75rem; + color: var(--souq-muted); +} + +.souq-card__price { + display: flex; + align-items: baseline; + gap: 0.25rem; +} + +.souq-card__price-from { + font-size: 0.7rem; + color: var(--souq-muted); +} + +.souq-card__price-amount { + font-size: 1rem; + font-weight: 700; + color: var(--souq-emerald); +} + +/* ---- Empty State ---- */ +.souq-empty { + text-align: center; + padding: clamp(3rem, 8vw, 6rem) 2rem; + background: var(--souq-cream); + border-radius: var(--souq-radius); + border: 1.5px dashed var(--souq-border); +} + +.souq-empty__icon { + font-size: 2.5rem; + margin-bottom: 1rem; + display: block; +} + +.souq-empty__text { + color: var(--souq-muted); + max-width: 32ch; + margin: 0 auto 1.5rem; + line-height: 1.6; +} + +.souq-empty__cta { + display: inline-flex; + align-items: center; + padding: 0.6rem 1.5rem; + background: var(--souq-emerald); + color: var(--souq-white); + border-radius: var(--souq-radius-sm); + font-weight: 600; + font-size: 0.875rem; + text-decoration: none; + transition: background var(--souq-duration) var(--souq-ease); +} + +.souq-empty__cta:hover { + background: var(--souq-emerald-dk); + color: var(--souq-white); +} diff --git a/wordpress-plugins/falah-souq/falah-souq.php b/wordpress-plugins/falah-souq/falah-souq.php new file mode 100644 index 0000000..61c3385 --- /dev/null +++ b/wordpress-plugins/falah-souq/falah-souq.php @@ -0,0 +1,45 @@ +post_content ?? '', 'souq_marketplace' ) ) { + wp_enqueue_style( + 'falah-souq', + FALAH_SOUQ_URL . 'assets/falah-souq.css', + [], + FALAH_SOUQ_VERSION + ); + } +} +add_action( 'wp_enqueue_scripts', 'falah_souq_enqueue' ); + +function falah_souq_enqueue_always() { + wp_enqueue_style( + 'falah-souq', + FALAH_SOUQ_URL . 'assets/falah-souq.css', + [], + FALAH_SOUQ_VERSION + ); +} +add_action( 'wp_enqueue_scripts', 'falah_souq_enqueue_always' ); + +register_activation_hook( __FILE__, function () { + falah_souq_register_post_type(); + flush_rewrite_rules(); +} ); diff --git a/wordpress-plugins/falah-souq/includes/post-type.php b/wordpress-plugins/falah-souq/includes/post-type.php new file mode 100644 index 0000000..2b0e1dc --- /dev/null +++ b/wordpress-plugins/falah-souq/includes/post-type.php @@ -0,0 +1,51 @@ + [ + 'name' => __( 'Services', 'falah-souq' ), + 'singular_name' => __( 'Service', 'falah-souq' ), + 'add_new_item' => __( 'Add New Service', 'falah-souq' ), + 'edit_item' => __( 'Edit Service', 'falah-souq' ), + ], + 'public' => true, + 'has_archive' => true, + 'rewrite' => [ 'slug' => 'souq' ], + 'supports' => [ 'title', 'editor', 'thumbnail', 'excerpt', 'custom-fields' ], + 'menu_icon' => 'dashicons-store', + 'show_in_rest' => true, + ] ); + + register_post_meta( 'souq_service', '_souq_price', [ + 'type' => 'number', + 'single' => true, + 'show_in_rest' => true, + ] ); + register_post_meta( 'souq_service', '_souq_delivery_days', [ + 'type' => 'integer', + 'single' => true, + 'show_in_rest' => true, + ] ); + register_post_meta( 'souq_service', '_souq_category', [ + 'type' => 'string', + 'single' => true, + 'show_in_rest' => true, + ] ); + register_post_meta( 'souq_service', '_souq_seller_name', [ + 'type' => 'string', + 'single' => true, + 'show_in_rest' => true, + ] ); + register_post_meta( 'souq_service', '_souq_rating', [ + 'type' => 'number', + 'single' => true, + 'show_in_rest' => true, + ] ); + register_post_meta( 'souq_service', '_souq_reviews_count', [ + 'type' => 'integer', + 'single' => true, + 'show_in_rest' => true, + ] ); +} +add_action( 'init', 'falah_souq_register_post_type' ); diff --git a/wordpress-plugins/falah-souq/includes/shortcode.php b/wordpress-plugins/falah-souq/includes/shortcode.php new file mode 100644 index 0000000..fb24613 --- /dev/null +++ b/wordpress-plugins/falah-souq/includes/shortcode.php @@ -0,0 +1,153 @@ + '', + 'limit' => 12, + 'columns' => 3, + ], $atts, 'souq_marketplace' ); + + $query_args = [ + 'post_type' => 'souq_service', + 'post_status' => 'publish', + 'posts_per_page' => (int) $atts['limit'], + 'orderby' => 'date', + 'order' => 'DESC', + ]; + + if ( $atts['category'] ) { + $query_args['meta_query'] = [ [ + 'key' => '_souq_category', + 'value' => sanitize_text_field( $atts['category'] ), + ] ]; + } + + $services = new WP_Query( $query_args ); + + ob_start(); + ?> +
+
+ + + + + + +
+ + have_posts() ) : ?> +
+ have_posts() ) : $services->the_post(); + $price = get_post_meta( get_the_ID(), '_souq_price', true ); + $days = get_post_meta( get_the_ID(), '_souq_delivery_days', true ); + $category = get_post_meta( get_the_ID(), '_souq_category', true ); + $seller = get_post_meta( get_the_ID(), '_souq_seller_name', true ); + $rating = (float) get_post_meta( get_the_ID(), '_souq_rating', true ); + $reviews = (int) get_post_meta( get_the_ID(), '_souq_reviews_count', true ); + $stars_full = floor( $rating ); + $has_half = ( $rating - $stars_full ) >= 0.5; + ?> + + +
+ + +
+ +

No services listed yet. Be the first to offer your skills to the Ummah.

+ + Add Service + +
+ +
+ + +