diff --git a/public/logos/sdt-dot-accent.svg b/public/logos/sdt-dot-accent.svg new file mode 100644 index 0000000..553fc79 --- /dev/null +++ b/public/logos/sdt-dot-accent.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/logos/sdt-dot-grey.svg b/public/logos/sdt-dot-grey.svg new file mode 100644 index 0000000..0d8d4df --- /dev/null +++ b/public/logos/sdt-dot-grey.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/logos/us-dash-accent.svg b/public/logos/us-dash-accent.svg new file mode 100644 index 0000000..ffa18b5 --- /dev/null +++ b/public/logos/us-dash-accent.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/logos/us-dash-grey.svg b/public/logos/us-dash-grey.svg new file mode 100644 index 0000000..3b4c6d8 --- /dev/null +++ b/public/logos/us-dash-grey.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/modules/email-signature/components/email-signature-module.tsx b/src/modules/email-signature/components/email-signature-module.tsx index 72acceb..4c73afe 100644 --- a/src/modules/email-signature/components/email-signature-module.tsx +++ b/src/modules/email-signature/components/email-signature-module.tsx @@ -8,6 +8,7 @@ import { SavedSignaturesPanel } from './saved-signatures-panel'; import { Separator } from '@/shared/components/ui/separator'; import { Button } from '@/shared/components/ui/button'; import { RotateCcw } from 'lucide-react'; +import type { SignatureBanner } from '../types'; export function EmailSignatureModule() { const { @@ -17,6 +18,10 @@ export function EmailSignatureModule() { const { saved, loading, save, remove } = useSavedSignatures(); + const setBanner = (banner: SignatureBanner | undefined) => { + updateField('banner', banner); + }; + return (
{/* Left panel — configurator */} @@ -29,6 +34,7 @@ export function EmailSignatureModule() { onSetVariant={setVariant} onSetCompany={setCompany} onSetAddress={setAddress} + onSetBanner={setBanner} /> diff --git a/src/modules/email-signature/components/signature-configurator.tsx b/src/modules/email-signature/components/signature-configurator.tsx index 3c8bf40..b27aea5 100644 --- a/src/modules/email-signature/components/signature-configurator.tsx +++ b/src/modules/email-signature/components/signature-configurator.tsx @@ -6,6 +6,7 @@ import type { SignatureColors, SignatureLayout, SignatureVariant, + SignatureBanner, } from "../types"; import { COMPANY_BRANDING, @@ -14,9 +15,11 @@ import { SDT_ADDRESSES, } from "../services/company-branding"; import type { AddressKey } from "../services/company-branding"; +import { useAuth } from "@/core/auth"; import { Input } from "@/shared/components/ui/input"; import { Label } from "@/shared/components/ui/label"; import { Switch } from "@/shared/components/ui/switch"; +import { Button } from "@/shared/components/ui/button"; import { Select, SelectContent, @@ -26,6 +29,7 @@ import { } from "@/shared/components/ui/select"; import { Separator } from "@/shared/components/ui/separator"; import { cn } from "@/shared/lib/utils"; +import { UserCheck, ImagePlus, Trash2 } from "lucide-react"; interface SignatureConfiguratorProps { config: SignatureConfig; @@ -38,6 +42,7 @@ interface SignatureConfiguratorProps { onSetVariant: (variant: SignatureVariant) => void; onSetCompany: (company: CompanyId) => void; onSetAddress?: (address: string[]) => void; + onSetBanner?: (banner: SignatureBanner | undefined) => void; } /** Color palette per company */ @@ -108,8 +113,10 @@ export function SignatureConfigurator({ onSetVariant, onSetCompany, onSetAddress, + onSetBanner, }: SignatureConfiguratorProps) { const palette = COMPANY_PALETTES[config.company]; + const { user } = useAuth(); return (
@@ -248,7 +255,25 @@ export function SignatureConfigurator({ {/* Personal data */}
-

Date personale

+
+

Date personale

+ {user && user.name && ( + + )} +

Stil & Aranjare

+ + {/* Logo scale slider */} +
+
+ + + {Math.round((config.layout.logoScale ?? 1) * 100)}% + +
+ + onUpdateLayout("logoScale", parseInt(e.target.value, 10) / 100) + } + className="mt-1 w-full accent-primary" + /> +
+ {LAYOUT_CONTROLS.map(({ key, label, min, max }) => (
@@ -380,6 +427,137 @@ export function SignatureConfigurator({
))}
+ + + + {/* Promotional banner */} + {onSetBanner && ( +
+
+

Banner promoțional

+ {config.banner ? ( + + ) : ( + + )} +
+ {config.banner && ( +
+
+ + + onSetBanner({ + ...config.banner!, + imageUrl: e.target.value, + }) + } + className="mt-1" + /> +
+
+ + + onSetBanner({ + ...config.banner!, + linkUrl: e.target.value, + }) + } + className="mt-1" + /> +
+
+ + + onSetBanner({ ...config.banner!, alt: e.target.value }) + } + className="mt-1" + /> +
+
+
+ + + onSetBanner({ + ...config.banner!, + width: parseInt(e.target.value, 10) || 540, + }) + } + className="mt-1" + /> +
+
+ + + onSetBanner({ + ...config.banner!, + height: parseInt(e.target.value, 10) || 80, + }) + } + className="mt-1" + /> +
+
+ {config.banner.imageUrl && ( +
+

+ Previzualizare: +

+ {/* eslint-disable-next-line @next/next/no-img-element */} + {config.banner.alt +
+ )} +
+ )} +
+ )}
); } diff --git a/src/modules/email-signature/hooks/use-signature-config.ts b/src/modules/email-signature/hooks/use-signature-config.ts index 0b3c1f0..f814ae1 100644 --- a/src/modules/email-signature/hooks/use-signature-config.ts +++ b/src/modules/email-signature/hooks/use-signature-config.ts @@ -1,9 +1,14 @@ -'use client'; +"use client"; -import { useState, useCallback, useMemo } from 'react'; -import type { CompanyId } from '@/core/auth/types'; -import type { SignatureConfig, SignatureVariant, SignatureColors, SignatureLayout } from '../types'; -import { getBranding } from '../services/company-branding'; +import { useState, useCallback, useMemo } from "react"; +import type { CompanyId } from "@/core/auth/types"; +import type { + SignatureConfig, + SignatureVariant, + SignatureColors, + SignatureLayout, +} from "../types"; +import { getBranding } from "../services/company-branding"; const DEFAULT_LAYOUT: SignatureLayout = { greenLineWidth: 97, @@ -14,46 +19,55 @@ const DEFAULT_LAYOUT: SignatureLayout = { sectionSpacing: 10, titleSpacing: 2, logoSpacing: 10, + logoScale: 1, }; -function createDefaultConfig(company: CompanyId = 'beletage'): SignatureConfig { +function createDefaultConfig(company: CompanyId = "beletage"): SignatureConfig { const branding = getBranding(company); return { - prefix: 'arh.', - name: '', - title: '', - phone: '', + prefix: "arh.", + name: "", + title: "", + phone: "", company, colors: { ...branding.defaultColors }, layout: { ...DEFAULT_LAYOUT }, - variant: 'full', + variant: "full", useSvg: false, }; } -export function useSignatureConfig(initialCompany: CompanyId = 'beletage') { - const [config, setConfig] = useState(() => createDefaultConfig(initialCompany)); +export function useSignatureConfig(initialCompany: CompanyId = "beletage") { + const [config, setConfig] = useState(() => + createDefaultConfig(initialCompany), + ); - const updateField = useCallback(( - key: K, - value: SignatureConfig[K] - ) => { - setConfig((prev) => ({ ...prev, [key]: value })); - }, []); + const updateField = useCallback( + (key: K, value: SignatureConfig[K]) => { + setConfig((prev) => ({ ...prev, [key]: value })); + }, + [], + ); - const updateColor = useCallback((key: keyof SignatureColors, value: string) => { - setConfig((prev) => ({ - ...prev, - colors: { ...prev.colors, [key]: value }, - })); - }, []); + const updateColor = useCallback( + (key: keyof SignatureColors, value: string) => { + setConfig((prev) => ({ + ...prev, + colors: { ...prev.colors, [key]: value }, + })); + }, + [], + ); - const updateLayout = useCallback((key: keyof SignatureLayout, value: number) => { - setConfig((prev) => ({ - ...prev, - layout: { ...prev.layout, [key]: value }, - })); - }, []); + const updateLayout = useCallback( + (key: keyof SignatureLayout, value: number) => { + setConfig((prev) => ({ + ...prev, + layout: { ...prev.layout, [key]: value }, + })); + }, + [], + ); const setVariant = useCallback((variant: SignatureVariant) => { setConfig((prev) => ({ ...prev, variant })); @@ -80,15 +94,28 @@ export function useSignatureConfig(initialCompany: CompanyId = 'beletage') { setConfig(loaded); }, []); - return useMemo(() => ({ - config, - updateField, - updateColor, - updateLayout, - setVariant, - setCompany, - setAddress, - resetToDefaults, - loadConfig, - }), [config, updateField, updateColor, updateLayout, setVariant, setCompany, setAddress, resetToDefaults, loadConfig]); + return useMemo( + () => ({ + config, + updateField, + updateColor, + updateLayout, + setVariant, + setCompany, + setAddress, + resetToDefaults, + loadConfig, + }), + [ + config, + updateField, + updateColor, + updateLayout, + setVariant, + setCompany, + setAddress, + resetToDefaults, + loadConfig, + ], + ); } diff --git a/src/modules/email-signature/services/company-branding.ts b/src/modules/email-signature/services/company-branding.ts index 4787e25..6c408c6 100644 --- a/src/modules/email-signature/services/company-branding.ts +++ b/src/modules/email-signature/services/company-branding.ts @@ -103,10 +103,13 @@ export const COMPANY_BRANDING: Record = { svg: "/logos/logo-us-light.svg", }, slashGrey: { - png: "https://beletage.ro/img/Grey-slash.png", - svg: "https://beletage.ro/img/Grey-slash.svg", + png: "/logos/us-dash-grey.svg", + svg: "/logos/us-dash-grey.svg", + }, + slashAccent: { + png: "/logos/us-dash-accent.svg", + svg: "/logos/us-dash-accent.svg", }, - slashAccent: { png: "", svg: "" }, logoDimensions: { width: 140, height: 24 }, address: [...ADDR_CHRISTESCU], website: "www.urbanswitch.ro", @@ -122,10 +125,13 @@ export const COMPANY_BRANDING: Record = { svg: "/logos/logo-sdt-light.svg", }, slashGrey: { - png: "https://beletage.ro/img/Grey-slash.png", - svg: "https://beletage.ro/img/Grey-slash.svg", + png: "/logos/sdt-dot-grey.svg", + svg: "/logos/sdt-dot-grey.svg", + }, + slashAccent: { + png: "/logos/sdt-dot-accent.svg", + svg: "/logos/sdt-dot-accent.svg", }, - slashAccent: { png: "", svg: "" }, logoDimensions: { width: 71, height: 24 }, address: [...ADDR_CHRISTESCU], website: "www.studiideteren.ro", diff --git a/src/modules/email-signature/services/signature-builder.ts b/src/modules/email-signature/services/signature-builder.ts index 7a95caf..cbb7ec1 100644 --- a/src/modules/email-signature/services/signature-builder.ts +++ b/src/modules/email-signature/services/signature-builder.ts @@ -37,13 +37,19 @@ export function generateSignatureHtml(config: SignatureConfig): string { sectionSpacing, titleSpacing, logoSpacing, + logoScale, } = config.layout; const colors = config.colors; const isReply = config.variant === "reply" || config.variant === "minimal"; const isMinimal = config.variant === "minimal"; - const logoDim = branding.logoDimensions ?? { width: 162, height: 24 }; + const rawDim = branding.logoDimensions ?? { width: 162, height: 24 }; + const scale = logoScale ?? 1; + const logoDim = { + width: Math.round(rawDim.width * scale), + height: Math.round(rawDim.height * scale), + }; const hide = "mso-hide:all;display:none!important;max-height:0;overflow:hidden;font-size:0;line-height:0;"; @@ -122,6 +128,7 @@ export function generateSignatureHtml(config: SignatureConfig): string { ${branding.motto ? `${esc(branding.motto)}` : ""} + ${config.banner?.imageUrl ? `${esc(config.banner.alt || ` : ""} `; } diff --git a/src/modules/email-signature/types.ts b/src/modules/email-signature/types.ts index cd220a9..d058d38 100644 --- a/src/modules/email-signature/types.ts +++ b/src/modules/email-signature/types.ts @@ -21,6 +21,16 @@ export interface SignatureLayout { sectionSpacing: number; titleSpacing: number; logoSpacing: number; + /** Logo scale factor (0.5–2.0, default 1.0) */ + logoScale: number; +} + +export interface SignatureBanner { + imageUrl: string; + linkUrl: string; + alt: string; + width: number; + height: number; } export interface CompanyBranding { @@ -52,6 +62,8 @@ export interface SignatureConfig { useSvg: boolean; /** Override the default company address */ addressOverride?: string[]; + /** Optional promotional banner below signature */ + banner?: SignatureBanner; } export interface SavedSignature {