From fe510238c086e1c9e549c2c5375363d5a2a8aa65 Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 20 Sep 2023 15:56:49 +0200 Subject: [PATCH] layout and design improvements --- www/app/(auth)/userInfo.tsx | 7 +- www/app/layout.tsx | 9 +- www/app/styles/button.css | 4 - www/app/styles/globals.scss | 18 +-- www/app/transcripts/[transcriptId]/page.tsx | 54 ++++---- www/app/transcripts/audioInputsDropdown.tsx | 46 ++++--- www/app/transcripts/dashboard.tsx | 129 -------------------- www/app/transcripts/finalSummary.tsx | 2 +- www/app/transcripts/liveTranscription.tsx | 2 +- www/app/transcripts/new/page.tsx | 51 +++++--- www/app/transcripts/recorder.tsx | 21 ++-- www/app/transcripts/scrollToBottom.tsx | 12 +- www/app/transcripts/topicList.tsx | 101 +++++++++++++++ www/tailwind.config.js | 15 +-- 14 files changed, 224 insertions(+), 247 deletions(-) delete mode 100644 www/app/transcripts/dashboard.tsx create mode 100644 www/app/transcripts/topicList.tsx diff --git a/www/app/(auth)/userInfo.tsx b/www/app/(auth)/userInfo.tsx index a8b918b0..5f56cb6e 100644 --- a/www/app/(auth)/userInfo.tsx +++ b/www/app/(auth)/userInfo.tsx @@ -4,20 +4,19 @@ import { useFiefUserinfo, } from "@fief/fief/nextjs/react"; import Link from "next/link"; -import Image from "next/image"; export default function UserInfo() { const isAuthenticated = useFiefIsAuthenticated(); const userinfo = useFiefUserinfo(); return !isAuthenticated ? ( - + Log in or create account ) : ( - + {userinfo?.email} ( - + Log out ) diff --git a/www/app/layout.tsx b/www/app/layout.tsx index 65e9206f..f865357f 100644 --- a/www/app/layout.tsx +++ b/www/app/layout.tsx @@ -6,6 +6,7 @@ import UserInfo from "./(auth)/userInfo"; import { ErrorProvider } from "./(errors)/errorContext"; import ErrorMessage from "./(errors)/errorMessage"; import Image from "next/image"; +import Link from "next/link"; const poppins = Poppins({ subsets: ["latin"], weight: ["200", "400", "600"] }); @@ -63,11 +64,11 @@ export default function RootLayout({ children }) { {/*TODO lvh or svh ? */}
-
+
{/* Logo on the left */} -
+
-
+ {/* Text link on the right */} diff --git a/www/app/styles/button.css b/www/app/styles/button.css index 76d5596a..92c246a5 100644 --- a/www/app/styles/button.css +++ b/www/app/styles/button.css @@ -8,13 +8,9 @@ button { padding: 0; cursor: pointer; /* Visual */ - /* background-color: #3e68ff; */ - /* color: #fff; */ border-radius: 8px; - /* box-shadow: 0 3px 5px rgba(0, 0, 0, 0.18); */ /* Size */ padding: 0.4em 1em; - min-width: 10ch; min-height: 44px; /* Text */ text-align: center; diff --git a/www/app/styles/globals.scss b/www/app/styles/globals.scss index 53dee09d..b9570abb 100644 --- a/www/app/styles/globals.scss +++ b/www/app/styles/globals.scss @@ -12,18 +12,6 @@ body { background: white; } -.temp-transcription { - background: rgb(151 190 255); - border-radius: 5px; - border: solid 1px #808080; - margin: 1em 0; -} - -.temp-transcription h2 { - font-weight: bold; - font-size: 130%; -} - .Dropdown-placeholder { text-wrap: nowrap; } @@ -31,8 +19,6 @@ body { top: 47% !important; } -@media (max-width: 768px) { - .audio-source-dropdown .Dropdown-control { - max-width: 200px; - } +.Dropdown-control.Dropdown-disabled { + background-color: lightgray; } diff --git a/www/app/transcripts/[transcriptId]/page.tsx b/www/app/transcripts/[transcriptId]/page.tsx index e1a31a3b..15391357 100644 --- a/www/app/transcripts/[transcriptId]/page.tsx +++ b/www/app/transcripts/[transcriptId]/page.tsx @@ -4,11 +4,12 @@ import getApi from "../../lib/getApi"; import useTranscript from "../useTranscript"; import useTopics from "../useTopics"; import useWaveform from "../useWaveform"; -import { Dashboard } from "../dashboard"; +import { TopicList } from "../topicList"; import Recorder from "../recorder"; import { Topic } from "../webSocketTypes"; import React, { useEffect, useState } from "react"; import "../../styles/button.css"; +import FinalSummary from "../finalSummary"; type TranscriptDetails = { params: { @@ -34,34 +35,37 @@ export default function TranscriptDetails(details: TranscriptDetails) { return ( <> -
- {transcript?.loading === true || - waveform?.loading == true || - topics?.loading == true ? ( - + ) : ( + <> + - ) : ( - <> - + - - - - )} -
+
+
+ {transcript?.response?.longSummary && ( + + )} +
+
+ + + )} ); } diff --git a/www/app/transcripts/audioInputsDropdown.tsx b/www/app/transcripts/audioInputsDropdown.tsx index f2c8d187..4b7b3cdc 100644 --- a/www/app/transcripts/audioInputsDropdown.tsx +++ b/www/app/transcripts/audioInputsDropdown.tsx @@ -1,36 +1,42 @@ -import React, { useRef, useEffect, useState } from "react"; - +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faMicrophone } from "@fortawesome/free-solid-svg-icons"; +import React, { useEffect, useState } from "react"; import Dropdown, { Option } from "react-dropdown"; import "react-dropdown/style.css"; const AudioInputsDropdown: React.FC<{ - audioDevices?: Option[]; + audioDevices: Option[]; + disabled: boolean; setDeviceId: React.Dispatch>; - disabled?: boolean; -}> = (props) => { +}> = ({ audioDevices, disabled, setDeviceId }) => { const [ddOptions, setDdOptions] = useState([]); useEffect(() => { - if (props.audioDevices) { - setDdOptions(props.audioDevices); - props.setDeviceId( - props.audioDevices.length > 0 ? props.audioDevices[0].value : null, - ); + if (audioDevices) { + setDdOptions(audioDevices); + setDeviceId(audioDevices.length > 0 ? audioDevices[0].value : null); } - }, [props.audioDevices]); + }, [audioDevices]); const handleDropdownChange = (option: Option) => { - props.setDeviceId(option.value); + setDeviceId(option.value); }; - return ( - - ); + if (audioDevices?.length > 0) { + return ( +
+ + +
+ ); + } + return null; }; export default AudioInputsDropdown; diff --git a/www/app/transcripts/dashboard.tsx b/www/app/transcripts/dashboard.tsx deleted file mode 100644 index 3dfa814c..00000000 --- a/www/app/transcripts/dashboard.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { - faChevronRight, - faChevronDown, -} from "@fortawesome/free-solid-svg-icons"; -import { formatTime } from "../lib/time"; -import ScrollToBottom from "./scrollToBottom"; -import DisconnectedIndicator from "./disconnectedIndicator"; -import LiveTrancription from "./liveTranscription"; -import FinalSummary from "./finalSummary"; -import { Topic, FinalSummary as FinalSummaryType } from "./webSocketTypes"; - -type DashboardProps = { - transcriptionText: string; - finalSummary: FinalSummaryType; - topics: Topic[]; - disconnected: boolean; - useActiveTopic: [ - Topic | null, - React.Dispatch>, - ]; -}; - -export function Dashboard({ - transcriptionText, - finalSummary, - topics, - disconnected, - useActiveTopic, -}: DashboardProps) { - const [activeTopic, setActiveTopic] = useActiveTopic; - const [autoscrollEnabled, setAutoscrollEnabled] = useState(true); - - useEffect(() => { - if (autoscrollEnabled) scrollToBottom(); - console.log(topics); - }, [topics.length]); - - const scrollToBottom = () => { - const topicsDiv = document.getElementById("topics-div"); - - if (!topicsDiv) - console.error("Could not find topics div to scroll to bottom"); - else topicsDiv.scrollTop = topicsDiv.scrollHeight; - }; - - const handleScroll = (e) => { - const bottom = - e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight; - if (!bottom && autoscrollEnabled) { - setAutoscrollEnabled(false); - } else if (bottom && !autoscrollEnabled) { - setAutoscrollEnabled(true); - } - }; - - return ( -
- {/* Topic Section */} -
- {topics.length > 0 ? ( - <> - - -
- {topics.map((item, index) => ( -
- setActiveTopic(activeTopic?.id == item.id ? null : item) - } - > -
-

- - [{formatTime(item.timestamp)}] - -   - {item.title} -

- -
- {activeTopic?.id == item.id && ( -
- {item.transcript} -
- )} -
- ))} -
- - ) : ( -
- Discussion topics will appear here after you start recording. It may - take up to 5 minutes of conversation for the first topic to appear. -
- )} -
- -
- {finalSummary.summary ? ( - - ) : ( - - )} -
- - {disconnected && } -
- ); -} diff --git a/www/app/transcripts/finalSummary.tsx b/www/app/transcripts/finalSummary.tsx index 24ff91c3..a9646cee 100644 --- a/www/app/transcripts/finalSummary.tsx +++ b/www/app/transcripts/finalSummary.tsx @@ -5,7 +5,7 @@ type FinalSummaryProps = { export default function FinalSummary(props: FinalSummaryProps) { return (
-

Final Summary

+

Final Summary

{props.text}

); diff --git a/www/app/transcripts/liveTranscription.tsx b/www/app/transcripts/liveTranscription.tsx index d5ba2373..2c913a91 100644 --- a/www/app/transcripts/liveTranscription.tsx +++ b/www/app/transcripts/liveTranscription.tsx @@ -5,7 +5,7 @@ type LiveTranscriptionProps = { export default function LiveTrancription(props: LiveTranscriptionProps) { return (
-

+

{/* Nous allons prendre quelques appels téléphoniques et répondre à quelques questions */} {props.text}

diff --git a/www/app/transcripts/new/page.tsx b/www/app/transcripts/new/page.tsx index 3c5d2804..eddf4fcc 100644 --- a/www/app/transcripts/new/page.tsx +++ b/www/app/transcripts/new/page.tsx @@ -1,7 +1,7 @@ "use client"; import React, { useEffect, useState } from "react"; import Recorder from "../recorder"; -import { Dashboard } from "../dashboard"; +import { TopicList } from "../topicList"; import useWebRTC from "../useWebRTC"; import useTranscript from "../useTranscript"; import { useWebSockets } from "../useWebSockets"; @@ -10,11 +10,15 @@ import "../../styles/button.css"; import { Topic } from "../webSocketTypes"; import getApi from "../../lib/getApi"; import AudioInputsDropdown from "../audioInputsDropdown"; +import LiveTrancription from "../liveTranscription"; +import DisconnectedIndicator from "../disconnectedIndicator"; const TranscriptCreate = () => { const [stream, setStream] = useState(null); const [disconnected, setDisconnected] = useState(false); const useActiveTopic = useState(null); + const [deviceId, setDeviceId] = useState(null); + const [recordStarted, setRecordStarted] = useState(false); useEffect(() => { if (process.env.NEXT_PUBLIC_ENV === "development") { @@ -40,13 +44,18 @@ const TranscriptCreate = () => { } = useAudioDevice(); const getCurrentStream = async () => { - return audioDevices.length - ? await getAudioStream(audioDevices[0].value) - : null; + setRecordStarted(true); + return deviceId ? await getAudioStream(deviceId) : null; }; + useEffect(() => { + if (audioDevices.length > 0) { + setDeviceId[audioDevices[0].value]; + } + }, [audioDevices]); + return ( -
+ <> {permissionOk ? ( <> { useActiveTopic={useActiveTopic} isPastMeeting={false} /> +
+ +
+
+ +
+
+
+ +
+
+
- + {disconnected && } +
) : ( <> @@ -87,7 +110,7 @@ const TranscriptCreate = () => { : "Please grant permission to continue."}

)} -
+ ); }; diff --git a/www/app/transcripts/recorder.tsx b/www/app/transcripts/recorder.tsx index f235ecaf..87e9955a 100644 --- a/www/app/transcripts/recorder.tsx +++ b/www/app/transcripts/recorder.tsx @@ -213,10 +213,7 @@ export default function Recorder(props: RecorderProps) { return (
-
+
{isRecording && (
@@ -229,8 +226,10 @@ export default function Recorder(props: RecorderProps) { <>