feat(webhooks): add webhook fields to frontend types, api, and edit sheet
This commit is contained in:
@@ -756,6 +756,8 @@ interface EditChannelSheetProps {
|
||||
logo?: string | null;
|
||||
logo_position?: LogoPosition;
|
||||
logo_opacity?: number;
|
||||
webhook_url?: string | null;
|
||||
webhook_poll_interval_secs?: number;
|
||||
},
|
||||
) => void;
|
||||
isPending: boolean;
|
||||
@@ -787,6 +789,8 @@ export function EditChannelSheet({
|
||||
const [logo, setLogo] = useState<string | null>(null);
|
||||
const [logoPosition, setLogoPosition] = useState<LogoPosition>("top_right");
|
||||
const [logoOpacity, setLogoOpacity] = useState(100);
|
||||
const [webhookUrl, setWebhookUrl] = useState("");
|
||||
const [webhookPollInterval, setWebhookPollInterval] = useState<number | "">(5);
|
||||
const [selectedBlockId, setSelectedBlockId] = useState<string | null>(null);
|
||||
const [fieldErrors, setFieldErrors] = useState<FieldErrors>({});
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -804,6 +808,8 @@ export function EditChannelSheet({
|
||||
setLogo(channel.logo ?? null);
|
||||
setLogoPosition(channel.logo_position ?? "top_right");
|
||||
setLogoOpacity(Math.round((channel.logo_opacity ?? 1) * 100));
|
||||
setWebhookUrl(channel.webhook_url ?? "");
|
||||
setWebhookPollInterval(channel.webhook_poll_interval_secs ?? 5);
|
||||
setSelectedBlockId(null);
|
||||
setFieldErrors({});
|
||||
}
|
||||
@@ -836,6 +842,10 @@ export function EditChannelSheet({
|
||||
logo: logo,
|
||||
logo_position: logoPosition,
|
||||
logo_opacity: logoOpacity / 100,
|
||||
webhook_url: webhookUrl || null,
|
||||
...(webhookUrl
|
||||
? { webhook_poll_interval_secs: webhookPollInterval === "" ? 5 : webhookPollInterval }
|
||||
: {}),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1085,6 +1095,28 @@ export function EditChannelSheet({
|
||||
onChange={setRecyclePolicy}
|
||||
/>
|
||||
</section>
|
||||
|
||||
{/* Webhook */}
|
||||
<section className="space-y-3">
|
||||
<h3 className="text-xs font-semibold uppercase tracking-wider text-zinc-500">Webhook</h3>
|
||||
<Field label="Webhook URL" hint="POST events to this URL on broadcast changes">
|
||||
<TextInput
|
||||
value={webhookUrl}
|
||||
onChange={setWebhookUrl}
|
||||
placeholder="https://example.com/webhook"
|
||||
/>
|
||||
</Field>
|
||||
{webhookUrl && (
|
||||
<Field label="Poll interval (seconds)" hint="How often to check for broadcast changes">
|
||||
<NumberInput
|
||||
value={webhookPollInterval}
|
||||
onChange={setWebhookPollInterval}
|
||||
min={1}
|
||||
placeholder="5"
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
|
||||
@@ -147,6 +147,8 @@ export interface ChannelResponse {
|
||||
logo?: string | null;
|
||||
logo_position: LogoPosition;
|
||||
logo_opacity: number;
|
||||
webhook_url?: string | null;
|
||||
webhook_poll_interval_secs?: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
@@ -157,6 +159,8 @@ export interface CreateChannelRequest {
|
||||
description?: string;
|
||||
access_mode?: AccessMode;
|
||||
access_password?: string;
|
||||
webhook_url?: string;
|
||||
webhook_poll_interval_secs?: number;
|
||||
}
|
||||
|
||||
export interface UpdateChannelRequest {
|
||||
@@ -173,6 +177,9 @@ export interface UpdateChannelRequest {
|
||||
logo?: string | null;
|
||||
logo_position?: LogoPosition;
|
||||
logo_opacity?: number;
|
||||
/** null = clear webhook */
|
||||
webhook_url?: string | null;
|
||||
webhook_poll_interval_secs?: number;
|
||||
}
|
||||
|
||||
// Media & Schedule
|
||||
|
||||
100
k-tv-frontend/package-lock.json
generated
100
k-tv-frontend/package-lock.json
generated
@@ -16,6 +16,7 @@
|
||||
"cmdk": "^1.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"embla-carousel-react": "^8.6.0",
|
||||
"hls.js": "^1.6.15",
|
||||
"input-otp": "^1.4.2",
|
||||
"lucide-react": "^0.577.0",
|
||||
"next": "16.1.6",
|
||||
@@ -30,17 +31,20 @@
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"vaul": "^1.1.2"
|
||||
"vaul": "^1.1.2",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/chromecast-caf-sender": "^1.0.11",
|
||||
"@types/hls.js": "^1.0.0",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.1.6",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
"typescript": "5.9.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
@@ -1493,13 +1497,6 @@
|
||||
"version": "1.0.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@modelcontextprotocol/sdk/node_modules/zod": {
|
||||
"version": "4.3.6",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
},
|
||||
"node_modules/@mswjs/interceptors": {
|
||||
"version": "0.41.3",
|
||||
"license": "MIT",
|
||||
@@ -3551,6 +3548,27 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/chrome": {
|
||||
"version": "0.1.37",
|
||||
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.37.tgz",
|
||||
"integrity": "sha512-IJE4ceuDO7lrEuua7Pow47zwNcI8E6qqkowRP7aFPaZ0lrjxh6y836OPqqkIZeTX64FTogbw+4RNH0+QrweCTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/filesystem": "*",
|
||||
"@types/har-format": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/chromecast-caf-sender": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/chromecast-caf-sender/-/chromecast-caf-sender-1.0.11.tgz",
|
||||
"integrity": "sha512-Pv3xvNYtxD/cTM/tKfuZRlLasvpxAm+CFni0GJd6Cp8XgiZS9g9tMZkR1uymsi5fIFv057SZKKAWVFFgy7fJtw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/chrome": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-array": {
|
||||
"version": "3.2.2",
|
||||
"license": "MIT"
|
||||
@@ -3601,6 +3619,41 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/filesystem": {
|
||||
"version": "0.0.36",
|
||||
"resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.36.tgz",
|
||||
"integrity": "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/filewriter": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/filewriter": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz",
|
||||
"integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/har-format": {
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.16.tgz",
|
||||
"integrity": "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/hls.js": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/hls.js/-/hls.js-1.0.0.tgz",
|
||||
"integrity": "sha512-EGY2QJefX+Z9XH4PAxI7RFoNqBlQEk16UpYR3kbr82CIgMX5SlMe0PjFdFV0JytRhyVPQCiwSyONuI6S1KdSag==",
|
||||
"deprecated": "This is a stub types definition. hls.js provides its own type definitions, so you do not need this installed.",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hls.js": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"dev": true,
|
||||
@@ -5862,14 +5915,6 @@
|
||||
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-react-hooks/node_modules/zod": {
|
||||
"version": "4.3.6",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-react/node_modules/resolve": {
|
||||
"version": "2.0.0-next.6",
|
||||
"dev": true,
|
||||
@@ -6654,6 +6699,12 @@
|
||||
"hermes-estree": "0.25.1"
|
||||
}
|
||||
},
|
||||
"node_modules/hls.js": {
|
||||
"version": "1.6.15",
|
||||
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.15.tgz",
|
||||
"integrity": "sha512-E3a5VwgXimGHwpRGV+WxRTKeSp2DW5DI5MWv34ulL3t5UNmyJWCQ1KmLEHbYzcfThfXG8amBL+fCYPneGHC4VA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/hono": {
|
||||
"version": "4.12.7",
|
||||
"license": "MIT",
|
||||
@@ -9321,6 +9372,15 @@
|
||||
"shadcn": "dist/index.js"
|
||||
}
|
||||
},
|
||||
"node_modules/shadcn/node_modules/zod": {
|
||||
"version": "3.25.76",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
},
|
||||
"node_modules/sharp": {
|
||||
"version": "0.34.5",
|
||||
"hasInstallScript": true,
|
||||
@@ -10005,6 +10065,8 @@
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@@ -10525,7 +10587,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.25.76",
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
|
||||
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "16.1.6",
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
"typescript": "5.9.3"
|
||||
},
|
||||
"ignoreScripts": [
|
||||
"sharp",
|
||||
|
||||
Reference in New Issue
Block a user