mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
adds about and privacy pages
This commit is contained in:
28
www/app/about.tsx
Normal file
28
www/app/about.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
"use client";
|
||||
import React, { useState } from "react";
|
||||
import FullscreenModal from "./transcripts/fullsreenModal";
|
||||
import AboutContent from "./aboutContent";
|
||||
|
||||
type AboutProps = {
|
||||
buttonText: string;
|
||||
};
|
||||
|
||||
export default function About({ buttonText }: AboutProps) {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className="hover:underline focus-within:underline underline-offset-2 decoration-[.5px] font-light px-2"
|
||||
onClick={() => setModalOpen(true)}
|
||||
>
|
||||
{buttonText}
|
||||
</button>
|
||||
{modalOpen && (
|
||||
<FullscreenModal close={() => setModalOpen(false)}>
|
||||
<AboutContent />
|
||||
</FullscreenModal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
53
www/app/aboutContent.tsx
Normal file
53
www/app/aboutContent.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Paragraph, Subtitle, Title } from "./lib/textComponents";
|
||||
|
||||
export default () => (
|
||||
<div className="max-w-xl">
|
||||
<Title>About us</Title>
|
||||
<Paragraph>
|
||||
Reflector is a transcription and summarization pipeline that transforms
|
||||
audio into knowledge. 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.
|
||||
</Paragraph>
|
||||
<Title>FAQs</Title>
|
||||
<Subtitle>1. How does it work?</Subtitle>
|
||||
<Paragraph>
|
||||
Reflector simplifies tasks, turning spoken words into organized
|
||||
information. Just press "record" to start and "stop" to finish. You'll get
|
||||
notes divided by topic, a meeting summary, and the option to download
|
||||
recordings.
|
||||
</Paragraph>
|
||||
<Subtitle>2. What makes Reflector different?</Subtitle>
|
||||
<Paragraph>
|
||||
Monadical prioritizes safeguarding your data. Reflector operates
|
||||
exclusively on your infrastructure, ensuring guaranteed security.
|
||||
</Paragraph>
|
||||
<Subtitle>3. Any industry-specific use cases?</Subtitle>
|
||||
<p>Absolutely! We have two custom deployments pre-built:</p>
|
||||
<ul className="mb-2 md:mb-4">
|
||||
<li>
|
||||
· Reflector Media: Ideal for meetings, providing real-time notes and
|
||||
topic summaries.
|
||||
</li>
|
||||
<li>
|
||||
· Projector Reflector: Suited for larger events, offering live topic
|
||||
summaries, translations, and agenda tracking.
|
||||
</li>
|
||||
</ul>
|
||||
<Subtitle>4. Who’s behind Reflector?</Subtitle>
|
||||
<Paragraph>
|
||||
Monadical is a cohesive and effective team that can connect seamlessly
|
||||
into your workflows, and we are ready to integrate Reflector’s building
|
||||
blocks into your custom tools. We’re committed to building software that
|
||||
outlasts us 🐙.
|
||||
</Paragraph>
|
||||
|
||||
<Paragraph>
|
||||
Contact us at{" "}
|
||||
<a href="mailto:hello@monadical.com" className="underline">
|
||||
hello@monadical.com
|
||||
</a>
|
||||
</Paragraph>
|
||||
</div>
|
||||
);
|
||||
@@ -7,6 +7,8 @@ import { ErrorProvider } from "./(errors)/errorContext";
|
||||
import ErrorMessage from "./(errors)/errorMessage";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import About from "./about";
|
||||
import Privacy from "./privacy";
|
||||
|
||||
const poppins = Poppins({ subsets: ["latin"], weight: ["200", "400", "600"] });
|
||||
|
||||
@@ -59,7 +61,7 @@ export const metadata: Metadata = {
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={poppins.className + " h-screen"}>
|
||||
<body className={poppins.className + " h-screen relative"}>
|
||||
<FiefWrapper>
|
||||
<ErrorProvider>
|
||||
<ErrorMessage />
|
||||
@@ -89,8 +91,12 @@ export default function RootLayout({ children }) {
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
{/* Text link on the right */}
|
||||
<UserInfo />
|
||||
<div>
|
||||
{/* Text link on the right */}
|
||||
<About buttonText="About" />
|
||||
·
|
||||
<Privacy buttonText="Privacy" />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{children}
|
||||
|
||||
16
www/app/lib/textComponents.tsx
Normal file
16
www/app/lib/textComponents.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
type SimpleProps = {
|
||||
children: JSX.Element | string | (JSX.Element | string)[];
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const Title = ({ children, className }: SimpleProps) => (
|
||||
<h2 className={`text-lg md:text-xl ${className}`}>{children}</h2>
|
||||
);
|
||||
const Subtitle = ({ children, className }: SimpleProps) => (
|
||||
<h3 className={`text-base md:text-lg ${className}`}>{children}</h3>
|
||||
);
|
||||
const Paragraph = ({ children, className }: SimpleProps) => (
|
||||
<p className={`md:text-justify mb-2 md:mb-4 ${className}`}>{children}</p>
|
||||
);
|
||||
|
||||
export { Title, Subtitle, Paragraph };
|
||||
28
www/app/privacy.tsx
Normal file
28
www/app/privacy.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
"use client";
|
||||
import React, { useState } from "react";
|
||||
import FullscreenModal from "./transcripts/fullsreenModal";
|
||||
import PrivacyContent from "./privacyContent";
|
||||
|
||||
type PrivacyProps = {
|
||||
buttonText: string;
|
||||
};
|
||||
|
||||
export default function Privacy({ buttonText }: PrivacyProps) {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className="hover:underline focus-within:underline underline-offset-2 decoration-[.5px] font-light px-2"
|
||||
onClick={() => setModalOpen(true)}
|
||||
>
|
||||
{buttonText}
|
||||
</button>
|
||||
{modalOpen && (
|
||||
<FullscreenModal close={() => setModalOpen(false)}>
|
||||
<PrivacyContent />
|
||||
</FullscreenModal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
32
www/app/privacyContent.tsx
Normal file
32
www/app/privacyContent.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { Paragraph, Title } from "./lib/textComponents";
|
||||
|
||||
export default () => (
|
||||
<div className="max-w-xl">
|
||||
<Title>Privacy Policy</Title>
|
||||
<Paragraph className="italic">Last updated on September 22, 2023</Paragraph>
|
||||
<ul className="mb-2 md:mb-4">
|
||||
<li>
|
||||
· Recording Consent: By using Reflector, you grant us permission to
|
||||
record your interactions for the purpose of showcasing Reflector's
|
||||
capabilities during the All In AI conference.
|
||||
</li>
|
||||
<li>
|
||||
· Data Access: You will have convenient access to your recorded sessions
|
||||
and transcriptions via a unique URL, which remains active for a period
|
||||
of seven days. After this time, your recordings and transcripts will be
|
||||
deleted.
|
||||
</li>
|
||||
<li>
|
||||
· Data Confidentiality: Rest assured that none of your audio data will
|
||||
be shared with third parties.
|
||||
</li>
|
||||
</ul>
|
||||
<Paragraph>
|
||||
Questions or Concerns: If you have any questions or concerns regarding
|
||||
your data, please feel free to reach out to us at{" "}
|
||||
<a href="mailto:reflector@monadical.com" className="underline">
|
||||
reflector@monadical.com
|
||||
</a>
|
||||
</Paragraph>
|
||||
</div>
|
||||
);
|
||||
36
www/app/transcripts/fullsreenModal.tsx
Normal file
36
www/app/transcripts/fullsreenModal.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faClose } from "@fortawesome/free-solid-svg-icons";
|
||||
import { MouseEventHandler } from "react";
|
||||
|
||||
type ModalProps = {
|
||||
children: JSX.Element;
|
||||
close: () => void;
|
||||
};
|
||||
const cancelClick: MouseEventHandler<HTMLDivElement> = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
export default function FullscreenModal(props: ModalProps) {
|
||||
return (
|
||||
<div
|
||||
className="fixed z-50 cursor-pointer top-0 bottom-0 left-0 right-0 flex justify-center items-center bg-black/10"
|
||||
onClick={props.close}
|
||||
>
|
||||
<div className="p-3 md:p-5 bg-white rounded-lg border-blue-300 h:auto max-w-[90svw] w-auto md:max-w-[80svw] relative pt-4">
|
||||
<button
|
||||
className="absolute right-2 top-2 p-0 min-h-0"
|
||||
onClick={props.close}
|
||||
>
|
||||
<FontAwesomeIcon icon={faClose} />
|
||||
</button>
|
||||
<div
|
||||
className="h-auto md:max-h-[75svh] max-h-[80svh] overflow-auto px-2 cursor-default text-left"
|
||||
onClick={cancelClick}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -13,6 +13,8 @@ import LiveTrancription from "../liveTranscription";
|
||||
import DisconnectedIndicator from "../disconnectedIndicator";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faGear } from "@fortawesome/free-solid-svg-icons";
|
||||
import About from "../../about";
|
||||
import Privacy from "../../privacy";
|
||||
|
||||
const TranscriptCreate = () => {
|
||||
const [stream, setStream] = useState<MediaStream | null>(null);
|
||||
@@ -99,51 +101,57 @@ const TranscriptCreate = () => {
|
||||
) : (
|
||||
<>
|
||||
<div></div>
|
||||
<section className="flex flex-col w-full h-full items-center justify-evenly p-4 md:px-6 md:py-8">
|
||||
<div className="flex flex-col max-w-2xl items-center justify-center">
|
||||
<h1 className="text-2xl font-bold mb-2">Reflector</h1>
|
||||
<p className="self-start">
|
||||
Meet Monadical's own Reflector, your audio ally for hassle-free
|
||||
insights.
|
||||
</p>
|
||||
<p className="mb-4 md:text-justify">
|
||||
With real-time transcriptions, translations, and summaries,
|
||||
Reflector captures and categorizes the details of your meetings
|
||||
and events, all while keeping your data locked down tight on
|
||||
your own infrastructure. Forget the scribbled notes, endless
|
||||
recordings, or third-party apps. Discover Reflector, a powerful
|
||||
new way to elevate knowledge management and accessibility for
|
||||
all.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex flex-col max-w-2xl items-center justify-center">
|
||||
<h2 className="text-2xl font-bold mb-2">Audio Permissions</h2>
|
||||
{loading ? (
|
||||
<p className="text-gray-500 text-center">
|
||||
Checking permission...
|
||||
<div className="max-h-full overflow-auto">
|
||||
<section className="flex flex-col w-full h-full items-center justify-evenly p-4 md:px-6 md:py-8">
|
||||
<div>
|
||||
<div className="flex flex-col max-w-xl items-center justify-center">
|
||||
<h1 className="text-2xl font-bold mb-2">
|
||||
Welcome to reflector.media
|
||||
</h1>
|
||||
<p>
|
||||
Reflector is a transcription and summarization pipeline that
|
||||
transforms audio into knowledge. 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.
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
<About buttonText="Learn more" />
|
||||
<h2 className="text-2xl font-bold mt-4 mb-2">
|
||||
Audio Permissions
|
||||
</h2>
|
||||
{loading ? (
|
||||
<p className="text-gray-500 text-center">
|
||||
Reflector needs access to your microphone to work.
|
||||
<br />
|
||||
{permissionDenied
|
||||
? "Please reset microphone permissions to continue."
|
||||
: "Please grant permission to continue."}
|
||||
Checking permission...
|
||||
</p>
|
||||
<button
|
||||
className="mt-4 bg-blue-400 hover:bg-blue-500 focus-visible:bg-blue-500 text-white font-bold py-2 px-4 rounded m-auto"
|
||||
onClick={requestPermission}
|
||||
disabled={permissionDenied}
|
||||
>
|
||||
{permissionDenied ? "Access denied" : "Grant Permission"}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
) : (
|
||||
<>
|
||||
<p className="text-gray-500 text-center">
|
||||
To enable Reflector, we kindly request permission to
|
||||
access your microphone during meetings and events.
|
||||
<br />
|
||||
<Privacy buttonText="Privacy policy" />
|
||||
<br />
|
||||
{permissionDenied
|
||||
? "Permission to use your microphone was denied, please change the permission setting in your browser and refresh this page."
|
||||
: "Please grant permission to continue."}
|
||||
</p>
|
||||
<button
|
||||
className="mt-4 bg-blue-400 hover:bg-blue-500 focus-visible:bg-blue-500 text-white font-bold py-2 px-4 rounded m-auto"
|
||||
onClick={requestPermission}
|
||||
disabled={permissionDenied}
|
||||
>
|
||||
{permissionDenied
|
||||
? "Access denied"
|
||||
: "Grant Permission"}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section className="flex justify-center"></section>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user