poprawki graficzne, zdjęcia, panel administarcyjny oraz układ stron
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { apiFetch } from '../auth';
|
||||
import { RichTextEditor } from '../RichText';
|
||||
|
||||
type IconComponent = (props: { name: string }) => JSX.Element | null;
|
||||
|
||||
@@ -289,14 +290,14 @@ function LeadsSection({ Icon }: { Icon: IconComponent }) {
|
||||
<tbody>
|
||||
{leads.map((lead) => (
|
||||
<tr key={lead.id}>
|
||||
<td>{lead.name || '—'}</td>
|
||||
<td>{lead.name || '-'}</td>
|
||||
<td>
|
||||
<div className="mkt-contact">
|
||||
{lead.email && <span>{lead.email}</span>}
|
||||
{lead.phone && <span className="mkt-muted">{lead.phone}</span>}
|
||||
</div>
|
||||
</td>
|
||||
<td>{lead.city || '—'}</td>
|
||||
<td>{lead.city || '-'}</td>
|
||||
<td><span className="mkt-chip">{SOURCE_LABEL[lead.source]}</span></td>
|
||||
<td>{STATUS_LABEL[lead.status]}</td>
|
||||
<td>
|
||||
@@ -324,7 +325,7 @@ function LeadsSection({ Icon }: { Icon: IconComponent }) {
|
||||
|
||||
<div className="mkt-import">
|
||||
<h3><Icon name="document" /> Import kontaktów (CSV)</h3>
|
||||
<p className="mkt-muted">Kolumny: <code>nazwa;email;telefon;miasto</code> — jeden kontakt w wierszu, nagłówek opcjonalny.</p>
|
||||
<p className="mkt-muted">Kolumny: <code>nazwa;email;telefon;miasto</code> - jeden kontakt w wierszu, nagłówek opcjonalny.</p>
|
||||
<textarea
|
||||
rows={4}
|
||||
value={csv}
|
||||
@@ -430,7 +431,7 @@ function TargetGroupsSection({ Icon }: { Icon: IconComponent }) {
|
||||
<div className="mkt-grid-2">
|
||||
<div className="admin-card mkt-card">
|
||||
<div className="admin-card-head"><h2>Nowa grupa docelowa</h2></div>
|
||||
<p className="mkt-muted">Grupa to dynamiczny segment — odbiorcy wyliczają się na bieżąco z kryteriów.</p>
|
||||
<p className="mkt-muted">Grupa to dynamiczny segment - odbiorcy wyliczają się na bieżąco z kryteriów.</p>
|
||||
<div className="mkt-form">
|
||||
<label>Nazwa
|
||||
<input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="np. Deweloperzy Warszawa" />
|
||||
@@ -485,7 +486,7 @@ function TargetGroupsSection({ Icon }: { Icon: IconComponent }) {
|
||||
<li key={g.id}>
|
||||
<div>
|
||||
<strong>{g.name}</strong>
|
||||
{g.description && <span className="mkt-muted"> — {g.description}</span>}
|
||||
{g.description && <span className="mkt-muted"> - {g.description}</span>}
|
||||
<div className="mkt-group-meta">
|
||||
<span className="mkt-badge">{g.memberCount} odbiorców</span>
|
||||
{g.sources.length > 0 && <span className="mkt-muted">{g.sources.map((s) => SOURCE_LABEL[s]).join(', ')}</span>}
|
||||
@@ -624,7 +625,7 @@ export function AdminCampaignsView({ Icon }: { Icon: IconComponent }) {
|
||||
</label>
|
||||
<label>Grupa docelowa
|
||||
<select value={form.targetGroupId} onChange={(e) => setForm({ ...form, targetGroupId: e.target.value })}>
|
||||
<option value="">— wybierz —</option>
|
||||
<option value="">- wybierz -</option>
|
||||
{groups.map((g) => (
|
||||
<option key={g.id} value={g.id}>{g.name} ({g.memberCount})</option>
|
||||
))}
|
||||
@@ -637,7 +638,11 @@ export function AdminCampaignsView({ Icon }: { Icon: IconComponent }) {
|
||||
</label>
|
||||
)}
|
||||
<label>Treść <span className="mkt-muted">(użyj {'{{name}}'} dla personalizacji; stopka z rezygnacją dodawana automatycznie)</span>
|
||||
<textarea rows={5} value={form.body} onChange={(e) => setForm({ ...form, body: e.target.value })} placeholder="Cześć {{name}}, ..." />
|
||||
{form.channel === 'EMAIL' ? (
|
||||
<RichTextEditor value={form.body} onChange={(html) => setForm({ ...form, body: html })} ariaLabel="Treść kampanii e-mail" placeholder="Cześć {{name}}, ..." />
|
||||
) : (
|
||||
<textarea rows={5} value={form.body} onChange={(e) => setForm({ ...form, body: e.target.value })} placeholder="Cześć {{name}}, ..." />
|
||||
)}
|
||||
</label>
|
||||
<div className="mkt-form-row">
|
||||
<label>Dzienny limit
|
||||
|
||||
Reference in New Issue
Block a user