Integrate local business workflow and SaaS redesign
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useMutation, useQuery } from "convex/react";
|
||||
import { FunctionReturnType } from "convex/server";
|
||||
import { MapPin, Pencil, Play, RefreshCcw, Plus } from "lucide-react";
|
||||
import { Clock3, MapPin, Pencil, Play, RefreshCcw, Plus, ShieldCheck } from "lucide-react";
|
||||
|
||||
import { api } from "@/convex/_generated/api";
|
||||
import { Id } from "@/convex/_generated/dataModel";
|
||||
@@ -256,12 +256,16 @@ export function CampaignsBoard() {
|
||||
onSubmit={submitCampaign}
|
||||
/>
|
||||
|
||||
<div className="flex flex-col gap-3 border-b pb-3 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div className="agency-panel flex flex-col gap-4 p-4 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">Lokale Kampagnenverwaltung</p>
|
||||
<h1 className="mt-2 text-3xl font-semibold tracking-normal">
|
||||
<p className="agency-kicker">Controlled Sourcing</p>
|
||||
<h1 className="mt-2 font-heading text-3xl font-semibold tracking-normal">
|
||||
Kampagnen
|
||||
</h1>
|
||||
<p className="mt-2 max-w-2xl text-sm leading-6 text-muted-foreground">
|
||||
Plane Suchläufe mit festen Limits, sauberem Radius und manuellen
|
||||
Prüfstationen vor Audit und Outreach.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Button onClick={openCreateDialog} className="justify-start sm:w-auto">
|
||||
@@ -275,7 +279,7 @@ export function CampaignsBoard() {
|
||||
{actionLabel ? <p className="text-sm" role="status">{actionLabel}</p> : null}
|
||||
|
||||
{campaignsSorted.length === 0 ? (
|
||||
<Card>
|
||||
<Card className="agency-panel">
|
||||
<CardHeader>
|
||||
<CardTitle>Keine Kampagnen</CardTitle>
|
||||
<CardDescription>
|
||||
@@ -289,7 +293,11 @@ export function CampaignsBoard() {
|
||||
const campaignTitleId = `campaign-title-${campaign._id}`;
|
||||
|
||||
return (
|
||||
<Card aria-labelledby={campaignTitleId} key={campaign._id}>
|
||||
<Card
|
||||
aria-labelledby={campaignTitleId}
|
||||
className="agency-panel overflow-hidden"
|
||||
key={campaign._id}
|
||||
>
|
||||
<CardHeader>
|
||||
<div className="flex flex-wrap items-start justify-between gap-2">
|
||||
<div className="min-w-0">
|
||||
@@ -308,23 +316,26 @@ export function CampaignsBoard() {
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="grid gap-2 text-sm">
|
||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||
<CardContent className="grid gap-3 text-sm">
|
||||
<div className="evidence-surface flex flex-wrap items-center justify-between gap-3 rounded-md px-3 py-2">
|
||||
<div className="inline-flex items-center gap-1 text-muted-foreground">
|
||||
<MapPin className="size-3" />
|
||||
<span>{campaign.postalCode}</span>
|
||||
</div>
|
||||
<span>{campaign.radiusKm} km</span>
|
||||
<span className="font-semibold">{campaign.radiusKm} km</span>
|
||||
</div>
|
||||
<Separator className="bg-border" />
|
||||
<div>
|
||||
<p>Cadence: {recurrenceLabel[campaign.recurrence]}</p>
|
||||
<p>
|
||||
Limits: L {campaign.maxNewLeadsPerRun}, A{" "}
|
||||
{campaign.maxAuditsPerRun}
|
||||
<div className="grid gap-2 rounded-md border border-border/75 bg-background/60 p-3">
|
||||
<p className="inline-flex items-center gap-2 font-medium">
|
||||
<Clock3 className="size-3.5 text-primary" />
|
||||
Cadence: {recurrenceLabel[campaign.recurrence]}
|
||||
</p>
|
||||
<p className="inline-flex items-center gap-2 font-medium">
|
||||
<ShieldCheck className="size-3.5 text-primary" />
|
||||
Lead-Limit: {campaign.maxNewLeadsPerRun}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="grid gap-1 rounded-md bg-muted/45 p-3">
|
||||
<p className="text-muted-foreground">
|
||||
Letzter Lauf: {formatDateTime(campaign.lastRunAt)}
|
||||
</p>
|
||||
@@ -373,7 +384,7 @@ export function CampaignsBoard() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Card>
|
||||
<Card className="agency-panel">
|
||||
<CardHeader>
|
||||
<CardTitle>Aktuelle Run-Logs</CardTitle>
|
||||
<CardDescription>
|
||||
@@ -387,7 +398,7 @@ export function CampaignsBoard() {
|
||||
<p className="text-muted-foreground">Noch keine Kampagnenläufe.</p>
|
||||
) : (
|
||||
visibleRuns.map((run) => (
|
||||
<div className="rounded-md border p-3" key={run._id}>
|
||||
<div className="rounded-md border border-border/75 bg-background/60 p-3" key={run._id}>
|
||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
||||
<p className="font-medium">
|
||||
{statusLabel[run.status] ?? run.status}
|
||||
|
||||
Reference in New Issue
Block a user