Files
reflector/www/app/(app)/transcripts/new/page.tsx
Mathieu Virbel fbeeff4c4d feat: complete migration from @hey-api/openapi-ts to openapi-react-query
- Migrated all components from useApi compatibility layer to direct React Query hooks
- Added new hooks for participant operations, room meetings, and speaker operations
- Updated all imports from old api module to api-types
- Fixed TypeScript types and API endpoint signatures
- Removed deprecated useApi.ts compatibility layer
- Fixed SourceKind enum values to match OpenAPI spec
- Added @ts-ignore for Zulip endpoints not in OpenAPI spec yet
- Fixed all compilation errors and type issues
2025-08-29 09:36:55 -06:00

232 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import React, { useEffect, useState } from "react";
import useAudioDevice from "../useAudioDevice";
import "react-select-search/style.css";
import "../../../styles/form.scss";
import About from "../../../(aboutAndPrivacy)/about";
import Privacy from "../../../(aboutAndPrivacy)/privacy";
import { useRouter } from "next/navigation";
import useCreateTranscript from "../createTranscript";
import SelectSearch from "react-select-search";
import { supportedLanguages } from "../../../supportedLanguages";
import useSessionStatus from "../../../lib/useSessionStatus";
import { featureEnabled } from "../../../domainContext";
import { signIn } from "next-auth/react";
import {
Flex,
Box,
Spinner,
Heading,
Button,
Card,
Center,
Link,
CardBody,
Stack,
Text,
Icon,
Grid,
IconButton,
Spacer,
Menu,
Tooltip,
Input,
} from "@chakra-ui/react";
const TranscriptCreate = () => {
const isClient = typeof window !== "undefined";
const router = useRouter();
const { isLoading, isAuthenticated } = useSessionStatus();
const requireLogin = featureEnabled("requireLogin");
const [name, setName] = useState<string>("");
const nameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
};
const [targetLanguage, setTargetLanguage] = useState<string>("NOTRANSLATION");
const onLanguageChange = (newval) => {
(!newval || typeof newval === "string") && setTargetLanguage(newval);
};
const createTranscript = useCreateTranscript();
const [loadingRecord, setLoadingRecord] = useState(false);
const [loadingUpload, setLoadingUpload] = useState(false);
const getTargetLanguage = () => {
if (targetLanguage === "NOTRANSLATION") return undefined;
return targetLanguage;
};
const send = () => {
if (loadingRecord || createTranscript.loading || permissionDenied) return;
setLoadingRecord(true);
const targetLang = getTargetLanguage();
createTranscript.create({
name,
source_language: "en",
target_language: targetLang || "en",
});
};
const uploadFile = () => {
if (loadingUpload || createTranscript.loading || permissionDenied) return;
setLoadingUpload(true);
const targetLang = getTargetLanguage();
createTranscript.create({
name,
source_language: "en",
target_language: targetLang || "en",
});
};
useEffect(() => {
let action = "record";
if (loadingUpload) action = "upload";
createTranscript.transcript &&
router.push(`/transcripts/${createTranscript.transcript.id}/${action}`);
}, [createTranscript.transcript]);
useEffect(() => {
if (createTranscript.error) setLoadingRecord(false);
}, [createTranscript.error]);
const { loading, permissionOk, permissionDenied, requestPermission } =
useAudioDevice();
return (
<Flex
maxW="container.xl"
flexDir="column"
margin="auto"
gap={2}
maxH="100%"
px={{ base: 5, md: 10 }}
py={5}
>
<Flex
flexDir={{ base: "column", md: "row" }}
justifyContent="space-between"
alignItems="center"
gap={8}
>
<Flex
flexDir="column"
h="full"
justifyContent="evenly"
flexBasis="1"
flexGrow={1}
>
<Heading size="2xl" textAlign={{ base: "center", md: "left" }}>
Welcome to Reflector
</Heading>
<Text mt={6}>
Reflector is a transcription and summarization pipeline that
transforms audio into knowledge.
<span className="hidden md:block">
The output is meeting minutes and topic summaries enabling
topic-specific analyses stored in your systems of record. This is
accomplished on your infrastructure without 3rd parties
keeping your data private, secure, and organized.
</span>
</Text>
<About buttonText="Learn more" />
<Text mt={6}>
In order to use Reflector, we kindly request permission to access
your microphone during meetings and events.
</Text>
{featureEnabled("privacy") && <Privacy buttonText="Privacy policy" />}
</Flex>
<Flex flexDir="column" h="full" flexBasis="1" flexGrow={1}>
<Center>
{isLoading ? (
<Spinner />
) : requireLogin && !isAuthenticated ? (
<Button onClick={() => signIn("authentik")}>Log in</Button>
) : (
<Flex
rounded="xl"
bg="blue.primary"
color="white"
maxW="96"
p={8}
flexDir="column"
my={4}
>
<Heading size="xl" mb={4}>
Try Reflector
</Heading>
<Box mb={4}>
<Text>Recording name</Text>
<div className="select-search-container">
<input
className="select-search-input"
type="text"
onChange={nameChange}
placeholder="Optional"
/>
</div>
</Box>
<Box mb={4}>
<Text>Do you want to enable live translation?</Text>
<SelectSearch
search
options={supportedLanguages}
value={targetLanguage}
onChange={onLanguageChange}
onBlur={() => {}}
onFocus={() => {}}
placeholder="Choose your language"
/>
</Box>
{isClient && !loading ? (
permissionOk ? (
<Spacer />
) : permissionDenied ? (
<Text className="">
Permission to use your microphone was denied, please
change the permission setting in your browser and refresh
this page.
</Text>
) : (
<Button
colorPalette="whiteAlpha"
onClick={requestPermission}
disabled={permissionDenied}
>
Request Microphone Permission
</Button>
)
) : (
<Text className="">Checking permissions...</Text>
)}
<Button
colorPalette="whiteAlpha"
onClick={send}
disabled={!permissionOk || loadingRecord || loadingUpload}
mt={2}
>
{loadingRecord ? "Loading..." : "Record Meeting"}
</Button>
<Text textAlign="center" m="2">
OR
</Text>
<Button
colorPalette="whiteAlpha"
onClick={uploadFile}
disabled={loadingRecord || loadingUpload}
>
{loadingUpload ? "Loading..." : "Upload File"}
</Button>
</Flex>
)}
</Center>
</Flex>
</Flex>
</Flex>
);
};
export default TranscriptCreate;