Reshape the account lifecycle to match how operators actually want to work the system: - Add Account → creates a row with status='unpaired'. No QR yet; the operator lands on the detail page. - Pair / Re-pair → transitions an unpaired account to status='pending' and opens the live QR flow. Works for first-time pair AND for re-pair of an account that was previously unpaired. - Unpair → asks the bot to stop the live Baileys session and clean session files; sets status='unpaired' but KEEPS the row (and its reminders) so the operator can re-pair without retyping anything. - Delete → permanently removes the account and cascades to its groups, reminders, run history. Schema: - whatsapp_groups.account_id and reminders.account_id now have ON DELETE CASCADE so deleting an account fans out cleanly. UI: - /accounts list shows everything except the transient 'pending' state. - /accounts/[id] shows state-aware buttons: Pair (when unpaired/banned/ disconnected), Sync + Unpair (when connected), Delete (always). - /accounts/new is now an "Add Account" form (label only). Other fixes: - next.config.ts: allowedDevOrigins includes 192.168.0.253 + test/rexwa subdomains so Server Actions work across the LAN. - packages/shared/src/rrule.ts: rrule@2.8.1 has no exports field and ships ESM that some bundlers can't resolve via default OR named import. Use createRequire to bridge — works under both NodeNext (bot runtime) and Turbopack (web SSR).
60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
import Link from "next/link";
|
|
import { redirect } from "next/navigation";
|
|
import { ArrowLeftIcon } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { ComposeFormClient } from "./compose-form-client";
|
|
|
|
interface StepComposeParams {
|
|
step?: string;
|
|
accountId?: string;
|
|
groupIds?: string;
|
|
text?: string;
|
|
mediaId?: string;
|
|
caption?: string;
|
|
scheduledAt?: string;
|
|
}
|
|
|
|
interface StepComposeProps {
|
|
params: StepComposeParams;
|
|
}
|
|
|
|
export function StepCompose({ params }: StepComposeProps) {
|
|
const { accountId, groupIds, text, mediaId, caption } = params;
|
|
|
|
if (!accountId || !groupIds) {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
redirect("/reminders/new" as any);
|
|
}
|
|
|
|
const backHref = `/reminders/new?step=2&accountId=${accountId}&groupIds=${groupIds}` as const;
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<div>
|
|
<Button asChild variant="ghost" size="sm" className="-ml-2">
|
|
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
|
|
<Link href={backHref as any}>
|
|
<ArrowLeftIcon />
|
|
Back
|
|
</Link>
|
|
</Button>
|
|
</div>
|
|
|
|
<p className="text-sm text-muted-foreground">
|
|
Write your reminder message. You can also attach an image or document.
|
|
</p>
|
|
|
|
<ComposeFormClient
|
|
accountId={accountId}
|
|
groupIds={groupIds}
|
|
initialText={text ?? ""}
|
|
initialMediaId={mediaId}
|
|
initialCaption={caption}
|
|
passThroughParams={{
|
|
scheduledAt: params.scheduledAt,
|
|
}}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|