feat: update branding and localization for various components and configurations
Production CI / validate-and-build (push) Failing after 1m15s

This commit is contained in:
2026-06-15 21:36:09 +03:30
parent f7f8a91a85
commit d1dd67aee7
22 changed files with 84 additions and 63 deletions
+8 -3
View File
@@ -1,5 +1,6 @@
import { inject, Injectable } from '@angular/core';
import { Router } from '@angular/router';
import config from 'src/config';
import { AuthService } from '../../services/auth.service';
import { BaseState, BaseStore } from '../base-store';
@@ -123,7 +124,7 @@ export class GlobalStore extends BaseStore<GlobalState> {
readonly isOnline = this.computed((state) => state.isOnline);
readonly notifications = this.computed((state) => state.notifications);
readonly unreadNotifications = this.computed((state) =>
state.notifications.filter((n) => !n.read),
state.notifications.filter((n) => !n.read)
);
readonly breadcrumbs = this.computed((state) => state.breadcrumbs);
readonly preferences = this.computed((state) => state.preferences);
@@ -144,7 +145,11 @@ export class GlobalStore extends BaseStore<GlobalState> {
}
// Load theme from localStorage
const savedTheme = localStorage.getItem('app_theme') as 'light' | 'dark';
const savedTheme = config.isPosApplication
? 'light'
: (localStorage.getItem('app_theme') as 'light' | 'dark');
console.log('savedTheme', savedTheme);
if (savedTheme) {
this.patchState({ theme: savedTheme });
}
@@ -250,7 +255,7 @@ export class GlobalStore extends BaseStore<GlobalState> {
*/
markNotificationRead(id: string): void {
const notifications = this._state().notifications.map((n) =>
n.id === id ? { ...n, read: true } : n,
n.id === id ? { ...n, read: true } : n
);
this.patchState({ notifications });
}
@@ -18,12 +18,12 @@ export const CONSUMER_MENU_ITEMS = [
routerLink: ['/consumer/poses'],
},
{
label: 'صورت‌حساب‌ها',
label: 'صورت‌حساب‌',
icon: 'pi pi-fw pi-receipt',
routerLink: ['/consumer/sale_invoices'],
},
{
label: 'مشتری‌ها',
label: 'مشتری',
icon: 'pi pi-fw pi-users',
routerLink: ['/consumer/customers'],
},
@@ -28,7 +28,17 @@ export class ConsumerStatisticsLatestInvoicesComponent extends AbstractList<ISta
readonly invoicesPageRoute = consumerSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!();
override setColumns(): void {
this.columns = saleInvoiceListConfig.columns.filter((column) => column.field !== 'created_at');
this.columns = saleInvoiceListConfig.columns
.filter((column) => column.field !== 'created_at')
.map((header) => {
if (header.field === 'status') {
return {
...header,
customDataModel: this.status,
};
}
return header;
});
}
override getDataRequest() {
@@ -35,7 +35,7 @@ export class ConsumerSaleInvoiceStore extends EntityStore<
routerLink: consumerSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!(),
},
{
title: this.entity()?.code,
title: `صورت‌حساب ${this.entity()?.invoice_number}`,
routerLink: consumerSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(invoiceId),
},
],
@@ -53,7 +53,7 @@ export class ConsumerSaleInvoiceStore extends EntityStore<
catchError((error) => {
this.setError(error);
throw error;
}),
})
)
.subscribe((entity) => {
this.patchState({ entity });
@@ -8,20 +8,21 @@ export const PARTNER_MENU_ITEMS = [
routerLink: ['/partner'],
},
{
label: 'حساب‌های کاربری',
icon: 'pi pi-fw pi-user',
routerLink: ['/partner/accounts'],
},
{
label: 'مشتری‌ها',
label: 'مشتری',
icon: 'pi pi-fw pi-users',
routerLink: ['/partner/consumers'],
},
{
label: 'لایسنس‌ها',
label: 'لایسنس',
icon: 'pi pi-fw pi-key',
routerLink: ['/partner/licenses'],
},
{
label: 'حساب‌های کاربری',
icon: 'pi pi-fw pi-user',
routerLink: ['/partner/accounts'],
},
],
},
] as MenuItem[];
@@ -5,7 +5,7 @@
<ng-template #topbarCenter>
@if (posInfo()) {
<a [routerLink]="homeRouteLink" class="flex flex-col items-center justify-center gap-2">
<div class="h-8 w-8">
<div class="h-8 max-w-20">
<img
[src]="posInfo()?.partner?.logo_url ?? placeholderLogo"
alt="Logo"
@@ -7,11 +7,11 @@ export const SUPER_ADMIN_MENU_ITEMS = [
icon: 'pi pi-fw pi-home',
routerLink: ['/'],
},
{
label: 'مشتری‌',
icon: 'pi pi-fw pi-id-card',
routerLink: ['/super_admin/consumers'],
},
// {
// label: 'مشتری‌',
// icon: 'pi pi-fw pi-id-card',
// routerLink: ['/super_admin/consumers'],
// },
{
label: 'شریک تجاری',
@@ -40,11 +40,11 @@ export const SUPER_ADMIN_MENU_ITEMS = [
// icon: 'pi pi-fw pi-barcode',
// routerLink: [stockKeepingUnitsNamedRoutes.stockKeepingUnits.meta.pagePath!()],
// },
{
label: 'لایسنس‌',
icon: 'pi pi-fw pi-key',
routerLink: ['/super_admin/licenses'],
},
// {
// label: 'لایسنس‌',
// icon: 'pi pi-fw pi-key',
// routerLink: ['/super_admin/licenses'],
// },
{
label: 'برند دستگاه',
icon: 'pi pi-fw pi-receipt',
@@ -3,13 +3,12 @@
[(visible)]="visible"
[modal]="true"
[style]="{ width: '500px' }"
[closable]="true"
>
[closable]="true">
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<field-code [control]="form.controls.code" />
<field-name [control]="form.controls.name" />
<field-vat [control]="form.controls.VAT" />
<field-sku-type [control]="form.controls.type" />
<!-- <field-sku-type [control]="form.controls.type" /> -->
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
@@ -9,16 +9,15 @@
[fullHeight]="fullHeight"
[showAdd]="true"
[showEdit]="true"
[showAll]="showAllBtn"
[allItemsPageRoute]="allItemsPageRoute()"
(onEdit)="onEditClick($event)"
(onAdd)="openAddForm()"
(onRefresh)="refresh()"
/>
(onRefresh)="refresh()" />
<stock-keeping-unit-form
[(visible)]="visibleForm"
[initialValues]="selectedItemForEdit() || undefined"
[guildId]="guildId"
[editMode]="editMode()"
(onSubmit)="refresh()"
/>
(onSubmit)="refresh()" />
@@ -19,13 +19,14 @@ import { StockKeepingUnitFormComponent } from './form.component';
export class GuildStockKeepingUnitsListComponent extends AbstractList<IStockKeepingUnitResponse> {
@Input() guildId!: string;
@Input() fullHeight?: boolean;
@Input() showAllBtn?: boolean;
@Input() header: IColumn[] = skuListConfig.columns;
listConfig = skuListConfig;
service = inject(StockKeepingUnitsService);
allItemsPageRoute = computed(() =>
stockKeepingUnitsNamedRoutes.stockKeepingUnits.meta.pagePath!(this.guildId),
stockKeepingUnitsNamedRoutes.stockKeepingUnits.meta.pagePath!(this.guildId)
);
override setColumns(): void {
@@ -8,11 +8,11 @@ export const stockKeepingUnitsNamedRoutes: NamedRoutes<TStockKeepingUnitsRouteNa
path: 'stock-keeping-units',
loadComponent: () =>
import('../../views/stockKeepingUnits/list.component').then(
(m) => m.GuildStockKeepingUnitsComponent,
(m) => m.GuildStockKeepingUnitsComponent
),
meta: {
title: 'شناسه کالاها',
pagePath: () => '/super_admin/guilds/:guildId/stock-keeping-units',
pagePath: (guildId: string) => `/super_admin/guilds/${guildId}/stock-keeping-units`,
},
},
};
@@ -15,7 +15,7 @@
<admin-guild-goods-list [guildId]="guildId()" [showAllBtn]="true" class="w-full" />
</div>
<div class="flex max-h-125">
<admin-guild-stock-keeping-units-list [guildId]="guildId()" class="w-full" />
<admin-guild-stock-keeping-units-list [guildId]="guildId()" [showAllBtn]="true" class="w-full" />
</div>
<admin-guild-form
@@ -7,12 +7,11 @@
(onHide)="close()">
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="تعداد شارژ" [control]="form.controls.quantity" type="number" />
<!-- <uikit-datepicker
<app-datepicker
label="انقضای فروش"
[control]="form.controls.activated_expires_at"
name="activated_expires_at"
[minDate]="minDate"
/> -->
[min]="minDate" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</shared-dialog>
@@ -3,6 +3,7 @@ import { InputComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
// import { UikitFlatpickrJalaliComponent } from '@/uikit';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
import { DatepickerComponent } from '@/uikit';
import { nowJalali } from '@/utils';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
@@ -17,7 +18,7 @@ import { AdminPartnerChargeLicenseTransactionsService } from '../services/charge
ReactiveFormsModule,
InputComponent,
FormFooterActionsComponent,
// UikitFlatpickrJalaliComponent,
DatepickerComponent,
],
})
export class PartnerChargeLicenseFormDialogComponent extends AbstractFormDialog<
@@ -13,8 +13,7 @@
(onAdd)="openAddForm()"
(onDetails)="toSinglePage($event)"
(onEdit)="onEditClick($event)"
(onRefresh)="refresh()"
>
(onRefresh)="refresh()">
<ng-template #name let-item>
<div class="flex items-center gap-2">
<p-avatar
@@ -22,8 +21,7 @@
[title]="item.name"
[label]="item.logo_url ? '' : item.name.slice(0, 2)"
shape="square"
size="large"
></p-avatar>
size="large"></p-avatar>
{{ item.name }}
</div>
</ng-template>
@@ -51,5 +49,4 @@
[editMode]="editMode()"
[partnerId]="selectedItemForEdit()?.id"
[initialValues]="selectedItemForEdit() || undefined"
(onSubmit)="refresh()"
/>
(onSubmit)="refresh()" />
+6 -3
View File
@@ -1,6 +1,7 @@
import { computed, effect, Injectable, signal, TemplateRef } from '@angular/core';
import { MenuItem } from 'primeng/api';
import { BehaviorSubject, Subject } from 'rxjs';
import config from 'src/config';
export interface layoutConfig {
preset?: string;
@@ -39,7 +40,7 @@ export class LayoutService {
preset: 'Aura',
primary: 'surface',
surface: null,
darkTheme: localStorage.getItem('isDarkTheme') === 'true',
darkTheme: config.isPosApplication ? false : localStorage.getItem('isDarkTheme') === 'true',
menuMode: 'static',
};
@@ -81,10 +82,12 @@ export class LayoutService {
overlayOpen$ = this.overlayOpen.asObservable();
theme = computed(() => (this.layoutConfig()?.darkTheme ? 'light' : 'dark'));
theme = computed(() =>
config.isPosApplication ? 'light' : this.layoutConfig()?.darkTheme ? 'light' : 'dark'
);
isSidebarActive = computed(
() => this.layoutState().overlayMenuActive || this.layoutState().staticMenuMobileActive,
() => this.layoutState().overlayMenuActive || this.layoutState().staticMenuMobileActive
);
isDarkTheme = computed(() => this.layoutConfig().darkTheme);
@@ -7,7 +7,7 @@
class="bg-surface-card border-surface-border flex h-auto w-full max-w-md flex-col items-center justify-center rounded-lg border px-12 py-10 shadow">
<div class="mb-10 flex flex-col items-center justify-center gap-4 text-center">
<img [src]="logo" alt="مدیریت صورت‌حساب‌های مالیاتی" class="h-auto w-20" />
<span class="text-lg font-bold"> به پنل مدیریت صورت‌حساب‌های مالیاتی سپاس خوش آمدید. </span>
<span class="text-lg font-bold"> {{ authTitle }}</span>
</div>
<!-- @if (activeStep() === "login") { -->
@@ -1,3 +1,4 @@
import { brandingConfig } from '@/branding/branding.config';
import { IAuthResponse, TRoles } from '@/core';
import { AuthService } from '@/core/services/auth.service';
import { ToastService } from '@/core/services/toast.service';
@@ -34,6 +35,8 @@ export class AuthComponent {
selectedRole = signal<TRoles | undefined>(this.role);
accountRole = signal<string>('');
authTitle = `به پنل مدیریت صورت‌حساب‌های مالیاتی ${brandingConfig.title} خوش آمدید.`;
toSignUp = () => {
this.activeStep.set('signup');
};
@@ -60,6 +60,7 @@
</div>
</shared-light-bottomsheet>
@if (showCorrectionPaymentDialog()) {
<shared-invoice-payment-form-dialog
[(visible)]="showCorrectionPaymentDialog"
[totalAmount]="correctionRequiredPayment()"
@@ -68,4 +69,5 @@
[isUnknownCustomer]="true"
(onSubmitPayment)="confirmCorrectionPayment($event)"
(onClose)="cancelCorrectionPayment()" />
}
}
@@ -1,12 +1,13 @@
import { IListConfig } from './list-config.model';
export const categoryListConfig: IListConfig = {
pageTitle: 'مدیریت دسته‌بندی‌های کالا',
pageTitle: 'مدیریت دسته‌بندی‌ کالا',
addNewCtaLabel: 'افزودن دسته‌بندی',
emptyPlaceholderTitle: 'دسته‌بندی‌ یافت نشد',
emptyPlaceholderDescription: 'برای افزودن دسته‌بندی، روی دکمهٔ بالا کلیک کنید.',
columns: [
{ field: 'image_url', header: 'تصویر', type: 'thumbnail' },
{ field: 'name', header: 'عنوان' },
{ field: 'goods_count', header: 'تعداد کالاها' },
],
};
+1 -1
View File
@@ -19,7 +19,7 @@ export const brandingConfig: BrandingConfig = {
manifestPath: '/favicon/site.webmanifest',
themeColor: '#ffffff',
enableInstallPrompt: false,
title: 'پنل مدیریت',
title: 'سپاس',
fullTitle: 'پنل مدیریت صورت‌حساب‌های مالیاتی',
support: {
phones: [
+2 -2
View File
@@ -1,5 +1,5 @@
import login from 'src/tenants/tis/assets/images/login.jpg';
import logo from 'src/tenants/tis/assets/images/logo.png';
import login from 'src/tenants/sepehr/assets/images/login.jpg';
import logo from 'src/tenants/sepehr/assets/images/logo.png';
export default {
logo,