Polish product image upload feedback and integration brand headers.
continuous-integration/drone/push Build is passing
Show upload loading with immediate preview, and use brand marks beside names in settings. Co-authored-by: Cursor <cursoragent@cursor.com>
No files matched your search
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#FF5A00"/>
|
||||
<path fill="#fff" d="M18.5 42.5 28.2 18h7.6l9.7 24.5h-7.1l-1.7-4.6H27.3l-1.7 4.6h-7.1zm11.2-10.2h7.1l-3.5-9.4-3.6 9.4z"/>
|
||||
<circle cx="46" cy="40" r="3.2" fill="#fff"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 308 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#232F3E"/>
|
||||
<path fill="#fff" d="M18 28.5c0-5.2 3.8-8.5 9.2-8.5 3.4 0 5.8 1.2 7.4 3.2l-3.6 2.6c-1-.9-2.2-1.5-3.8-1.5-2.8 0-4.7 1.9-4.7 4.2s1.9 4.2 4.7 4.2c1.6 0 2.8-.6 3.8-1.5l3.6 2.6c-1.6 2-4 3.2-7.4 3.2-5.4 0-9.2-3.3-9.2-8.5z"/>
|
||||
<path fill="#FF9900" d="M20 42.2c4.8 2.6 11.2 4 17.2 4 5.4 0 10.2-1.1 13.4-3.1.6-.4.2-1-.3-.7-3.4 2.2-9 3.4-14.2 3.4-6.6 0-12.5-1.5-16.6-3.7-.6-.3-1.1.3-.5.1z"/>
|
||||
<path fill="#FF9900" d="M46.5 39.2c.4-.5 2.1.2 2.9.6.8.4 1.4.6 1.2 1-.2.5-1.9.1-2.8-.3-.9-.4-1.6-.8-1.3-1.3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 635 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#FFCC00"/>
|
||||
<path fill="#D40511" d="M12 22h8.4c4.8 0 7.8 2.6 7.8 7s-3 7-7.8 7H17.6V42H12V22zm5.6 9.4h2.5c1.9 0 3-1 3-2.9s-1.1-2.9-3-2.9h-2.5v5.8zM30.2 22h5.4l6.2 10.6V22H47v20h-5.4L35.4 31.4V42h-5.2V22z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 332 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#DC0032"/>
|
||||
<path fill="#fff" d="M14 20h12.4c7.4 0 12.2 4.2 12.2 11.2S33.8 42.4 26.4 42.4H14V20zm8.2 15.6h3.6c3.4 0 5.4-1.8 5.4-5.2s-2-5.2-5.4-5.2h-3.6v10.4zM41.2 42.4c-5.4 0-9-3.5-9-8.8 0-5.4 3.7-8.9 9.1-8.9 3.3 0 5.8 1.2 7.4 3.3l-4.2 3c-.9-1.1-2.1-1.7-3.4-1.7-2.3 0-3.8 1.6-3.8 4.2s1.5 4.3 3.9 4.3c1.4 0 2.6-.6 3.5-1.7l4.1 2.8c-1.6 2.3-4.3 3.5-7.6 3.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 484 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#0B6E4F"/>
|
||||
<path fill="#fff" d="M18 18h8.2v6.4H18V18zm0 10.2h8.2V46H18V28.2zM30.5 28.2H46V34H38.7v12H30.5V28.2z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 242 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#FFCC00"/>
|
||||
<path fill="#1A1A1A" d="M16 20h7.2v24H16V20zm11.4 0H40c6.8 0 11.2 3.9 11.2 10.3S46.8 40.6 40 40.6H27.4V20zm7.2 14.2H39c2.8 0 4.5-1.5 4.5-3.9s-1.7-3.9-4.5-3.9h-4.4v7.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 309 B |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
|
||||
<rect width="64" height="64" rx="14" fill="#A6C300"/>
|
||||
<path fill="#fff" d="M18 18h14.2c7.1 0 11.5 3.8 11.5 10.2 0 6.5-4.5 10.4-11.7 10.4H26.6V46H18V18zm8.6 13.4h4.7c2.9 0 4.6-1.5 4.6-3.9s-1.7-3.8-4.6-3.8h-4.7v7.7z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 301 B |
@@ -8,7 +8,12 @@ export function resolveProductImageUrl(
|
||||
return '';
|
||||
}
|
||||
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
if (
|
||||
url.startsWith('http://') ||
|
||||
url.startsWith('https://') ||
|
||||
url.startsWith('blob:') ||
|
||||
url.startsWith('data:')
|
||||
) {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,9 +119,12 @@
|
||||
@for (c of d.byChannel; track c.source) {
|
||||
<tr>
|
||||
<td>
|
||||
<span class="channel-badge" [attr.data-channel]="c.source">
|
||||
{{ 'orders.source.' + c.source | translate }}
|
||||
</span>
|
||||
<app-order-channel-icons
|
||||
[source]="c.source"
|
||||
[showDelivery]="false"
|
||||
[showLabels]="true"
|
||||
[iconSize]="14"
|
||||
/>
|
||||
</td>
|
||||
<td>{{ c.orders }}</td>
|
||||
<td class="cell-strong">{{ c.revenue | i18nCurrency }}</td>
|
||||
|
||||
@@ -27,6 +27,7 @@ import { I18nCurrencyPipe } from '../../core/i18n/i18n-currency.pipe';
|
||||
import { TranslatePipe } from '../../core/i18n/translate.pipe';
|
||||
import { AdminSkeletonComponent } from '../../shared/admin-skeleton.component';
|
||||
import { ToastService } from '../../shared/toast.service';
|
||||
import { OrderChannelIconsComponent } from '../orders/order-channel-icons.component';
|
||||
|
||||
Chart.register(
|
||||
BarController,
|
||||
@@ -86,6 +87,7 @@ interface AnalyticsDto {
|
||||
TranslatePipe,
|
||||
I18nCurrencyPipe,
|
||||
AdminSkeletonComponent,
|
||||
OrderChannelIconsComponent,
|
||||
],
|
||||
templateUrl: './analytics-admin.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
|
||||
@@ -57,6 +57,7 @@ import {
|
||||
}
|
||||
</span>
|
||||
|
||||
@if (showDelivery()) {
|
||||
<span
|
||||
class="meta-icon delivery-badge"
|
||||
[attr.data-carrier]="carrier()"
|
||||
@@ -80,6 +81,7 @@ import {
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
@@ -93,6 +95,7 @@ export class OrderChannelIconsComponent {
|
||||
ShippingServiceType | string | null | undefined
|
||||
>('parcelLocker');
|
||||
readonly showLabels = input(false);
|
||||
readonly showDelivery = input(true);
|
||||
readonly iconSize = input(14);
|
||||
|
||||
protected channel(): OrderSource {
|
||||
|
||||
@@ -259,6 +259,11 @@
|
||||
<div class="card-pad">
|
||||
<label
|
||||
class="state-box"
|
||||
[attr.aria-disabled]="uploadingImageIndex() !== null"
|
||||
[style.opacity]="uploadingImageIndex() !== null ? 0.6 : 1"
|
||||
[style.pointer-events]="
|
||||
uploadingImageIndex() !== null ? 'none' : 'auto'
|
||||
"
|
||||
style="
|
||||
display: block;
|
||||
padding: 28px 12px;
|
||||
@@ -269,7 +274,13 @@
|
||||
margin-bottom: 16px;
|
||||
"
|
||||
>
|
||||
<strong>{{ 'products.uploadImage' | translate }}</strong>
|
||||
<strong>
|
||||
@if (uploadingImageIndex() !== null) {
|
||||
{{ 'products.uploading' | translate }}
|
||||
} @else {
|
||||
{{ 'products.uploadImage' | translate }}
|
||||
}
|
||||
</strong>
|
||||
<div class="cell-muted" style="margin-top: 4px">
|
||||
{{ 'products.uploadHint' | translate }}
|
||||
</div>
|
||||
@@ -277,6 +288,7 @@
|
||||
type="file"
|
||||
accept="image/jpeg,image/png,image/gif,image/webp,image/bmp"
|
||||
class="sr-only"
|
||||
[disabled]="uploadingImageIndex() !== null"
|
||||
(change)="handleNewImageUpload($event)"
|
||||
/>
|
||||
</label>
|
||||
@@ -286,7 +298,14 @@
|
||||
<div class="card" style="padding: 12px">
|
||||
<div
|
||||
class="thumb"
|
||||
style="width: 100%; height: 140px; border-radius: 8px; overflow: hidden"
|
||||
style="
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: var(--surface-2, #f3f4f6);
|
||||
"
|
||||
>
|
||||
@if (img.url) {
|
||||
<img
|
||||
@@ -295,6 +314,23 @@
|
||||
style="width: 100%; height: 100%; object-fit: cover"
|
||||
/>
|
||||
}
|
||||
@if (uploadingImageIndex() === $index) {
|
||||
<div
|
||||
style="
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(15, 23, 42, 0.45);
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
"
|
||||
>
|
||||
{{ 'products.uploading' | translate }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="field mt-16">
|
||||
<label>{{ 'products.imageAlt' | translate }}</label>
|
||||
|
||||
@@ -169,7 +169,7 @@ export class ProductFormModalComponent {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const file = input.files?.[0];
|
||||
input.value = '';
|
||||
if (!file) {
|
||||
if (!file || this.uploadingImageIndex() !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ export class ProductFormModalComponent {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const file = input.files?.[0];
|
||||
input.value = '';
|
||||
if (!file) {
|
||||
if (!file || this.uploadingImageIndex() !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -190,10 +190,23 @@ export class ProductFormModalComponent {
|
||||
}
|
||||
|
||||
#uploadToIndex(index: number, file: File): void {
|
||||
this.error.set('');
|
||||
this.uploadingImageIndex.set(index);
|
||||
|
||||
const localUrl = URL.createObjectURL(file);
|
||||
const previousUrl = this.images[index]?.url ?? '';
|
||||
this.images[index] = {
|
||||
...this.images[index],
|
||||
url: localUrl,
|
||||
altText: this.images[index].altText || this.names.pl,
|
||||
};
|
||||
this.images = [...this.images];
|
||||
|
||||
this.#api
|
||||
.upload<{ url: string }>('/admin/products/images/upload', file)
|
||||
.subscribe({
|
||||
next: (res) => {
|
||||
URL.revokeObjectURL(localUrl);
|
||||
this.images[index] = {
|
||||
...this.images[index],
|
||||
url: res.url,
|
||||
@@ -203,6 +216,12 @@ export class ProductFormModalComponent {
|
||||
this.uploadingImageIndex.set(null);
|
||||
},
|
||||
error: () => {
|
||||
URL.revokeObjectURL(localUrl);
|
||||
this.images[index] = {
|
||||
...this.images[index],
|
||||
url: previousUrl.startsWith('blob:') ? '' : previousUrl,
|
||||
};
|
||||
this.images = [...this.images];
|
||||
this.uploadingImageIndex.set(null);
|
||||
this.error.set('products.errorUpload');
|
||||
},
|
||||
|
||||
@@ -255,7 +255,9 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="cell-strong">InPost</td>
|
||||
<td>
|
||||
<app-integration-brand brand="inPost" [compact]="true" />
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -280,7 +282,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cell-strong">DHL</td>
|
||||
<td>
|
||||
<app-integration-brand brand="dhl" [compact]="true" />
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -305,7 +309,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="cell-strong">DPD</td>
|
||||
<td>
|
||||
<app-integration-brand brand="dpd" [compact]="true" />
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -350,8 +356,9 @@
|
||||
</p>
|
||||
|
||||
<section class="stack" style="gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span class="badge badge-info">PayU</span>
|
||||
<div class="integration-head">
|
||||
<app-integration-brand brand="payu" />
|
||||
<div class="integration-head__actions">
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -362,6 +369,7 @@
|
||||
{{ 'settings.sandbox' | translate }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<div class="field">
|
||||
<label for="payu-pos">{{ 'settings.payuPosId' | translate }}</label>
|
||||
@@ -457,8 +465,8 @@
|
||||
<hr style="border: 0; border-top: 1px solid var(--border)" />
|
||||
|
||||
<section class="stack" style="gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span class="delivery-badge" data-carrier="inPost">InPost</span>
|
||||
<div class="integration-head">
|
||||
<app-integration-brand brand="inPost" />
|
||||
</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<div class="field">
|
||||
@@ -554,8 +562,8 @@
|
||||
<hr style="border: 0; border-top: 1px solid var(--border)" />
|
||||
|
||||
<section class="stack" style="gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span class="delivery-badge" data-carrier="dhl">DHL</span>
|
||||
<div class="integration-head">
|
||||
<app-integration-brand brand="dhl" />
|
||||
</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<div class="field">
|
||||
@@ -616,8 +624,8 @@
|
||||
<hr style="border: 0; border-top: 1px solid var(--border)" />
|
||||
|
||||
<section class="stack" style="gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span class="delivery-badge" data-carrier="dpd">DPD</span>
|
||||
<div class="integration-head">
|
||||
<app-integration-brand brand="dpd" />
|
||||
</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<div class="field">
|
||||
@@ -679,8 +687,9 @@
|
||||
<hr style="border: 0; border-top: 1px solid var(--border)" />
|
||||
|
||||
<section class="stack" style="gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span class="channel-badge" data-channel="allegro">Allegro</span>
|
||||
<div class="integration-head">
|
||||
<app-integration-brand brand="allegro" />
|
||||
<div class="integration-head__actions">
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -691,6 +700,7 @@
|
||||
{{ 'settings.enabled' | translate }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<div class="field">
|
||||
<label for="allegro-client">{{ 'settings.allegroClientId' | translate }}</label>
|
||||
@@ -733,8 +743,9 @@
|
||||
<hr style="border: 0; border-top: 1px solid var(--border)" />
|
||||
|
||||
<section class="stack" style="gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span class="channel-badge" data-channel="amazon">Amazon</span>
|
||||
<div class="integration-head">
|
||||
<app-integration-brand brand="amazon" />
|
||||
<div class="integration-head__actions">
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -745,6 +756,7 @@
|
||||
{{ 'settings.enabled' | translate }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<div class="field">
|
||||
<label for="amazon-seller">{{ 'settings.amazonSellerId' | translate }}</label>
|
||||
@@ -806,8 +818,9 @@
|
||||
<hr style="border: 0; border-top: 1px solid var(--border)" />
|
||||
|
||||
<section class="stack" style="gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<span class="badge badge-info">iFirma</span>
|
||||
<div class="integration-head">
|
||||
<app-integration-brand brand="ifirma" />
|
||||
<div class="integration-head__actions">
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -818,6 +831,7 @@
|
||||
{{ 'settings.enabled' | translate }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-3 sm:grid-cols-2">
|
||||
<div class="field">
|
||||
<label for="ifirma-login">{{ 'settings.ifirmaLogin' | translate }}</label>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ApiService } from '../../core/api.service';
|
||||
import { TranslatePipe } from '../../core/i18n/translate.pipe';
|
||||
import { ToastService } from '../../shared/toast.service';
|
||||
import { AdminSkeletonComponent } from '../../shared/admin-skeleton.component';
|
||||
import { IntegrationBrandComponent } from '../../shared/integration-brand.component';
|
||||
import {
|
||||
AdminSettings,
|
||||
DEFAULT_ADMIN_SETTINGS,
|
||||
@@ -100,7 +101,12 @@ interface StoreSettingsApi {
|
||||
@Component({
|
||||
selector: 'app-settings-admin',
|
||||
standalone: true,
|
||||
imports: [FormsModule, TranslatePipe, AdminSkeletonComponent],
|
||||
imports: [
|
||||
FormsModule,
|
||||
TranslatePipe,
|
||||
AdminSkeletonComponent,
|
||||
IntegrationBrandComponent,
|
||||
],
|
||||
templateUrl: './settings-admin.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
||||
|
||||
/** Supported integration brand keys. */
|
||||
export type IntegrationBrandId =
|
||||
| 'payu'
|
||||
| 'inPost'
|
||||
| 'dhl'
|
||||
| 'dpd'
|
||||
| 'allegro'
|
||||
| 'amazon'
|
||||
| 'ifirma';
|
||||
|
||||
const BRAND_META: Record<
|
||||
IntegrationBrandId,
|
||||
{ label: string; src: string }
|
||||
> = {
|
||||
payu: { label: 'PayU', src: 'brands/payu.svg' },
|
||||
inPost: { label: 'InPost', src: 'brands/inpost.svg' },
|
||||
dhl: { label: 'DHL', src: 'brands/dhl.svg' },
|
||||
dpd: { label: 'DPD', src: 'brands/dpd.svg' },
|
||||
allegro: { label: 'Allegro', src: 'brands/allegro.svg' },
|
||||
amazon: { label: 'Amazon', src: 'brands/amazon.svg' },
|
||||
ifirma: { label: 'iFirma', src: 'brands/ifirma.svg' },
|
||||
};
|
||||
|
||||
/**
|
||||
* Brand mark + name for settings integration sections.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-integration-brand',
|
||||
standalone: true,
|
||||
template: `
|
||||
<div
|
||||
class="integration-brand"
|
||||
[attr.data-brand]="brand()"
|
||||
[class.integration-brand--compact]="compact()"
|
||||
>
|
||||
<span class="integration-brand__mark" aria-hidden="true">
|
||||
<img [src]="meta().src" [alt]="" width="40" height="40" />
|
||||
</span>
|
||||
@if (showName()) {
|
||||
<span class="integration-brand__name">{{ meta().label }}</span>
|
||||
}
|
||||
</div>
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class IntegrationBrandComponent {
|
||||
readonly brand = input.required<IntegrationBrandId>();
|
||||
readonly showName = input(true);
|
||||
readonly compact = input(false);
|
||||
|
||||
protected meta(): { label: string; src: string } {
|
||||
return BRAND_META[this.brand()];
|
||||
}
|
||||
}
|
||||
@@ -1855,6 +1855,108 @@ table.data tbody tr.is-selected {
|
||||
color: #1e40af;
|
||||
}
|
||||
|
||||
.integration-brand {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.integration-brand__mark {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
||||
}
|
||||
|
||||
.integration-brand__mark img {
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.integration-brand__name {
|
||||
font-size: 15px;
|
||||
font-weight: 650;
|
||||
letter-spacing: -0.01em;
|
||||
color: var(--text);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.integration-brand--compact {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.integration-brand--compact .integration-brand__mark,
|
||||
.integration-brand--compact .integration-brand__mark img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.integration-brand--compact .integration-brand__name {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.integration-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px 16px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.integration-head__actions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.integration-brand[data-brand='payu'] .integration-brand__mark {
|
||||
border-color: #c5db6a;
|
||||
background: #f4f9d9;
|
||||
}
|
||||
|
||||
.integration-brand[data-brand='inPost'] .integration-brand__mark {
|
||||
border-color: #f5d76e;
|
||||
background: #fff8db;
|
||||
}
|
||||
|
||||
.integration-brand[data-brand='dhl'] .integration-brand__mark {
|
||||
border-color: #f0c84a;
|
||||
background: #fff6d6;
|
||||
}
|
||||
|
||||
.integration-brand[data-brand='dpd'] .integration-brand__mark {
|
||||
border-color: #f3a4b4;
|
||||
background: #fde8ed;
|
||||
}
|
||||
|
||||
.integration-brand[data-brand='allegro'] .integration-brand__mark {
|
||||
border-color: #ffb081;
|
||||
background: #fff1e8;
|
||||
}
|
||||
|
||||
.integration-brand[data-brand='amazon'] .integration-brand__mark {
|
||||
border-color: #f0c26b;
|
||||
background: #fff8e8;
|
||||
}
|
||||
|
||||
.integration-brand[data-brand='ifirma'] .integration-brand__mark {
|
||||
border-color: #8fc4b0;
|
||||
background: #e8f5ef;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.reveal,
|
||||
.soft-in,
|
||||
|
||||