diff --git a/.env.example b/.env.example index 4b39060..96d0c9e 100644 --- a/.env.example +++ b/.env.example @@ -162,3 +162,13 @@ PROFILE_ADMIN_MOBILES= # Api/ApiMobileController::setOrder:740-743). Blank means nobody is notified — # the order, the customer's SMS and the sales expert's SMS still go through. ORDER_ADMIN_MOBILES= + +# --------------------------------------------------------------------------- +# Brand +# --------------------------------------------------------------------------- +# The name at the top of every SMS («زرتاج\n…») and the site link in the +# welcome SMS. Blank = the defaults in apps/api/src/common/brand.ts. The +# frontends take their brand from the repo-root brand.ts instead; the full +# rebrand checklist is docs/BRANDING.md. +BRAND_NAME= +BRAND_SITE_URL= diff --git a/apps/admin-panel/index.html b/apps/admin-panel/index.html index 65c0db5..04ce988 100644 --- a/apps/admin-panel/index.html +++ b/apps/admin-panel/index.html @@ -4,7 +4,7 @@ - منتزر — پنل مدیریت + %BRAND_TITLE%
diff --git a/apps/admin-panel/src/App.vue b/apps/admin-panel/src/App.vue index 8628286..ea0b843 100644 --- a/apps/admin-panel/src/App.vue +++ b/apps/admin-panel/src/App.vue @@ -37,6 +37,7 @@ import { onMounted, onUnmounted, ref, watch } from 'vue'; import { notification } from 'ant-design-vue'; import faIR from 'ant-design-vue/es/locale/fa_IR'; import themeConfig from './themeConfig'; +import { brand } from './brand'; import { useLayoutStore } from './stores/layout'; import AppUpdateGate from './components/common/AppUpdateGate.vue'; import { userName } from './utils'; @@ -96,7 +97,7 @@ onMounted(() => { notification.open({ message: `${user && user.name ? user.name : ' کاربر '} عزیز `, placement: 'topLeft', - description: 'به منتزر خوش آمدید', + description: `به ${brand.name} خوش آمدید`, style: { color: 'var(--primary-color)', marginLeft: `20px`, diff --git a/apps/admin-panel/src/assets/images/logo/montzar-horizontal.png b/apps/admin-panel/src/assets/images/logo/brand-horizontal.png similarity index 100% rename from apps/admin-panel/src/assets/images/logo/montzar-horizontal.png rename to apps/admin-panel/src/assets/images/logo/brand-horizontal.png diff --git a/apps/admin-panel/src/assets/images/logo/montzar-icon.png b/apps/admin-panel/src/assets/images/logo/brand-icon.png similarity index 100% rename from apps/admin-panel/src/assets/images/logo/montzar-icon.png rename to apps/admin-panel/src/assets/images/logo/brand-icon.png diff --git a/apps/admin-panel/src/assets/images/logo/montzar-icon.webp b/apps/admin-panel/src/assets/images/logo/brand-icon.webp similarity index 100% rename from apps/admin-panel/src/assets/images/logo/montzar-icon.webp rename to apps/admin-panel/src/assets/images/logo/brand-icon.webp diff --git a/apps/admin-panel/src/assets/styles/utilities.less b/apps/admin-panel/src/assets/styles/utilities.less index 0b3c205..6a3f7d3 100644 --- a/apps/admin-panel/src/assets/styles/utilities.less +++ b/apps/admin-panel/src/assets/styles/utilities.less @@ -29,7 +29,7 @@ // ant-design-pro boilerplate in Vue's own palette, inherited verbatim from // legacy and used as `@border-color-base`. That file is deleted (ADV4 has no // LESS build to feed); nothing in the app should reference `--primary`/ -// `--accent` any more — use the Montzar tokens below instead. +// `--accent` any more — use the brand tokens below instead. :root { --primary-color: #1c2d56; --secondary-color: #836447; diff --git a/apps/admin-panel/src/brand.ts b/apps/admin-panel/src/brand.ts new file mode 100644 index 0000000..0fc3747 --- /dev/null +++ b/apps/admin-panel/src/brand.ts @@ -0,0 +1,2 @@ +// The brand lives in the repo-root brand.ts, shared by all three frontends. +export { brand } from '../../../brand'; diff --git a/apps/admin-panel/src/components/accounting/CustomerAccountingCard.vue b/apps/admin-panel/src/components/accounting/CustomerAccountingCard.vue index 6c54ac0..053d6e8 100644 --- a/apps/admin-panel/src/components/accounting/CustomerAccountingCard.vue +++ b/apps/admin-panel/src/components/accounting/CustomerAccountingCard.vue @@ -4,50 +4,86 @@ linked to, and both balances side by side (the customer sees the accounting one; the credit limit is checked against the app's own). --> - +
+
+

حسابداری

+ لینک شده + لینک نشده +
+ - - +
+
+ کد حساب - لینک نشده - - - — - - - {{ num(info?.internal?.gold, 3) }} / - {{ num(info?.internal?.rial, 0) }} -
مبنای سقف اعتبار
-
- +
-
- آخرین ارسال: {{ STATUS[lastJob.status] ?? lastJob.status }} — {{ jdt(lastJob.updatedAt) }} - — {{ lastJob.lastError }} +
+
+
مانده‌ی حسابداری
+ + +
+
+
مانده‌ی دفتر اپ
+
+ {{ num(info?.internal?.gold, 3) }} + گرم +
+
+ {{ num(info?.internal?.rial, 0) }} + ریال +
+
مبنای سقف اعتبار
+
+
+ +
+ + آخرین ارسال: {{ STATUS[lastJob.status] ?? lastJob.status }} — {{ jdt(lastJob.updatedAt) }} +
{{ lastJob.lastError }}
+
+ +
- - - - لینک دستی - - حذف لینک - - - +
diff --git a/apps/admin-panel/src/components/x-table/XTable.vue b/apps/admin-panel/src/components/x-table/XTable.vue index 7ffca72..1554ff1 100644 --- a/apps/admin-panel/src/components/x-table/XTable.vue +++ b/apps/admin-panel/src/components/x-table/XTable.vue @@ -293,7 +293,10 @@ const opOptions = [ { value: 'between', label: 'بین' }, ]; -const cols = computed(() => props.model?.cols ?? []); +// The model is a plain class instance (see model.ts), so its columns are not +// reactive on their own. Wrapping it here lets the column picker's `col.show` +// checkbox toggles re-run visibleCols / antColumns. +const cols = computed(() => (props.model ? (reactive(props.model) as XTbl).cols : [])); const visibleCols = computed(() => cols.value.filter((c) => c.show)); const filterableOptions = computed(() => cols.value.filter((c) => c.filtered).map((c) => ({ value: c.__fkey ?? c.key, label: c.title })), diff --git a/apps/admin-panel/src/components/x-table/model.ts b/apps/admin-panel/src/components/x-table/model.ts index 6467829..e251dbb 100644 --- a/apps/admin-panel/src/components/x-table/model.ts +++ b/apps/admin-panel/src/components/x-table/model.ts @@ -42,6 +42,9 @@ export class Xtc { this.key = key; this.title = title; this.dataIndex = key; + // The record id ('کد') is kept out of every table by default. It can still be + // turned on from the column picker. + if (key === 'id') this.show = false; } private __filter() { diff --git a/apps/admin-panel/src/layouts/components/VerticalNavMenu.vue b/apps/admin-panel/src/layouts/components/VerticalNavMenu.vue index 5a14960..4c54541 100644 --- a/apps/admin-panel/src/layouts/components/VerticalNavMenu.vue +++ b/apps/admin-panel/src/layouts/components/VerticalNavMenu.vue @@ -19,7 +19,7 @@ > - طلای منتزر + %BRAND_TITLE%
diff --git a/apps/user-app-v2/public/img/montzar-logo.png b/apps/user-app-v2/public/img/brand-logo.png similarity index 100% rename from apps/user-app-v2/public/img/montzar-logo.png rename to apps/user-app-v2/public/img/brand-logo.png diff --git a/apps/user-app-v2/public/img/montzar-logo.webp b/apps/user-app-v2/public/img/brand-logo.webp similarity index 100% rename from apps/user-app-v2/public/img/montzar-logo.webp rename to apps/user-app-v2/public/img/brand-logo.webp diff --git a/apps/user-app-v2/src/api/client.ts b/apps/user-app-v2/src/api/client.ts index 17c6b2a..65a4e83 100644 --- a/apps/user-app-v2/src/api/client.ts +++ b/apps/user-app-v2/src/api/client.ts @@ -260,6 +260,17 @@ export interface GoldPriceQuote { quotedAt: string; } +/** Body of POST customer/auth/register — the app register form, field for field. */ +export interface RegisterBody { + fname: string; + lname: string; + mobile: string; + store_name: string; + phone: string; + address: string; + city: string; +} + /** One admin-uploaded home banner slide — raw shape as saved by the admin * panel's manage/Const.vue "اسلایدر موبایل" tab (image + optional link). */ export interface AdminSlide { @@ -444,6 +455,13 @@ export const api = { * which used to be derived by scanning the whole catalogue in the browser. */ getCatalogFacets: () => request('/catalog/products/facets'), + /** App self-registration. The new customer waits for admin approval before signing in. */ + register: (body: RegisterBody) => + request<{ ok: boolean }>('/customer/auth/register', { + method: 'POST', + body: JSON.stringify(body), + }), + /** * Step 1 of login — ports henza_server ApiMobileController::userAuth. * Always resolves `{ sent: true }`, even for an unregistered number, so the diff --git a/apps/user-app-v2/src/assets/img/montzar-logo.png b/apps/user-app-v2/src/assets/img/brand-logo.png similarity index 100% rename from apps/user-app-v2/src/assets/img/montzar-logo.png rename to apps/user-app-v2/src/assets/img/brand-logo.png diff --git a/apps/user-app-v2/src/assets/styles/style.less b/apps/user-app-v2/src/assets/styles/style.less index ee301d0..d7e9dde 100644 --- a/apps/user-app-v2/src/assets/styles/style.less +++ b/apps/user-app-v2/src/assets/styles/style.less @@ -704,6 +704,24 @@ html.motion-reduced .toast { background: alpha(@canvas, 97%) !important; } +/* Browser autofill paints its own pale-blue fill (and dark text) over the + field, which can't be overridden with `background`. Cover it with an inset + shadow in the field's own colour instead. Inside an ant affix wrapper only + the inner gets autofilled, so without this it shows as a blue box + floating inside the bordered wrapper. */ +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +textarea:-webkit-autofill, +textarea:-webkit-autofill:hover, +textarea:-webkit-autofill:focus { + -webkit-text-fill-color: @ink; + caret-color: @ink; + -webkit-box-shadow: 0 0 0 1000px @canvas inset !important; + box-shadow: 0 0 0 1000px @canvas inset !important; + transition: background-color 9999s ease-out 0s; +} + /* ── Dark theme: third-party surfaces ────────────────────────── ant-design-vue compiles its theme at build time with black text (fade(@black, 85%)) and white fills; only its surface backgrounds were diff --git a/apps/user-app-v2/src/brand.ts b/apps/user-app-v2/src/brand.ts new file mode 100644 index 0000000..0fc3747 --- /dev/null +++ b/apps/user-app-v2/src/brand.ts @@ -0,0 +1,2 @@ +// The brand lives in the repo-root brand.ts, shared by all three frontends. +export { brand } from '../../../brand'; diff --git a/apps/user-app-v2/src/components/Spinner.vue b/apps/user-app-v2/src/components/Spinner.vue index 76e0eb0..765576b 100644 --- a/apps/user-app-v2/src/components/Spinner.vue +++ b/apps/user-app-v2/src/components/Spinner.vue @@ -2,7 +2,7 @@