Skip to content

Commit

Permalink
feat: move status to dropdown info
Browse files Browse the repository at this point in the history
  • Loading branch information
cmgriffing committed Jan 19, 2024
1 parent 4c8933b commit 63a4aad
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 96 deletions.
6 changes: 2 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,12 @@ export function App() {
</Group>
<Group>
<Button
rightSection={<IconSettings />}
onClick={() => {
openSettingsModal();
}}
>
Settings
<Box ml={4}>
<IconSettings />
</Box>
</Button>
</Group>
</Flex>
Expand All @@ -117,12 +115,12 @@ export function App() {
<Text>Books</Text>
<Group>
<Button
rightSection={<IconPlus stroke={3} />}
onClick={() => {
openCreateBookModal();
}}
>
Book
<IconPlus stroke={3} />
</Button>
</Group>
</Flex>
Expand Down
4 changes: 2 additions & 2 deletions src/components/SnippetForm.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@

.other-snippet-label {
border-radius: 1rem;
background: gray;
background: #efefef;
margin: 0 auto;
padding: 0.5rem 1rem;
color: white;
color: black;
width: 10rem;
text-align: center;
}
Expand Down
93 changes: 76 additions & 17 deletions src/components/SnippetForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import { RefObject, useEffect, useState } from "react";
import { TextInput, Textarea, Flex, Group, Button, Box } from "@mantine/core";
import { IconMicrophone, IconTrash } from "@tabler/icons-react";
import {
TextInput,
Textarea,
Flex,
Group,
Button,
Box,

Check failure on line 8 in src/components/SnippetForm.tsx

View workflow job for this annotation

GitHub Actions / Deploy

'Box' is declared but its value is never read.
Popover,
Text,
} from "@mantine/core";
import {
IconMicrophone,
IconTrash,
IconCaretDownFilled,
} from "@tabler/icons-react";
import { clsx } from "clsx";
import { Link } from "react-router-dom";

Expand All @@ -11,6 +24,11 @@ dayjs.extend(relativeTime);
import { SnippetModel } from "../data/repositories/snippets";

import "./SnippetForm.scss";
import {
SnippetStatus,
SnippetStatusIcon,
getSnippetStatus,
} from "./SnippetStatusIcon";

interface BaseSnippetProps {
bookId: string;
Expand Down Expand Up @@ -49,27 +67,67 @@ export function SnippetForm({
}: SnippetFormProps | DisabledSnippetProps) {
const [labelValue, setLabelValue] = useState(snippet?.label || "");
const [contentValue, setContentValue] = useState(snippet?.content || "");
const status = getSnippetStatus(snippet);

useEffect(() => {
setLabelValue(snippet?.label || "");
setContentValue(snippet?.content || "");
}, [snippet]);

console.log({ status });

console.log({ snippet });

const contents = (
<>
<Box>
<Box>Created At: {dayjs(snippet?.createdAt).fromNow()}</Box>
<Box>Modified At: {dayjs(snippet?.modifiedAt).fromNow()}</Box>
{!!snippet?.recordedAt && (
<Box>Recorded At: {dayjs(snippet?.recordedAt).fromNow()}</Box>
)}
{!!snippet?.recordedAt && (
<Box>Processed At: {dayjs(snippet?.processedAt).fromNow()}</Box>
)}
{!!snippet?.recordedAt && (
<Box>Finished At: {dayjs(snippet?.finishedAt).fromNow()}</Box>
)}
</Box>
<Flex justify={"flex-end"}>
<Popover width={240} trapFocus position="bottom" withArrow shadow="md">
<Popover.Target>
<Button
variant={"outline"}
leftSection={<SnippetStatusIcon snippet={snippet!} height={24} />}
rightSection={<IconCaretDownFilled width={12} />}
>
Status
</Button>
</Popover.Target>
<Popover.Dropdown>
<Flex justify={"space-between"}>
<Text>Status:</Text> <Text>{SnippetStatus[status]}</Text>
</Flex>
<Flex justify="space-between">
<Text>Created:</Text>
{dayjs(snippet?.createdAt).fromNow()}
</Flex>
<Flex justify="space-between">
<Text>Modified:</Text>
{dayjs(snippet?.modifiedAt).fromNow()}
</Flex>
{snippet &&
snippet?.recordedAt > 0 &&
status > SnippetStatus.New && (
<Flex justify="space-between">
<Text>Recorded:</Text>
{dayjs(snippet?.recordedAt).fromNow()}
</Flex>
)}
{snippet &&
snippet?.processedAt > 0 &&
status > SnippetStatus.Processing && (
<Flex justify="space-between">
<Text>Processed:</Text>
{dayjs(snippet?.processedAt).fromNow()}
</Flex>
)}
{/* {status > SnippetStatus.Raw && status <= SnippetStatus.Finished && (
<Flex justify="space-between">
<Text>Finished:</Text>
{dayjs(snippet?.finishedAt).fromNow()}
</Flex>
)} */}
</Popover.Dropdown>
</Popover>
</Flex>

<TextInput
label="Label"
Expand Down Expand Up @@ -99,18 +157,19 @@ export function SnippetForm({
onRecord();
}}
disabled={disabled}
rightSection={<IconMicrophone />}
>
Record Audio
<IconMicrophone />
</Button>
<Button
color="red"
onClick={() => {
onDelete();
}}
disabled={disabled}
rightSection={<IconTrash />}
>
Delete <IconTrash />
Delete
</Button>
</Group>
</>
Expand Down
101 changes: 101 additions & 0 deletions src/components/SnippetStatusIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from "react";

Check failure on line 2 in src/components/SnippetStatusIcon.tsx

View workflow job for this annotation

GitHub Actions / Deploy

'React' is declared but its value is never read.
import { Flex } from "@mantine/core";

Check failure on line 3 in src/components/SnippetStatusIcon.tsx

View workflow job for this annotation

GitHub Actions / Deploy

'Flex' is declared but its value is never read.

import {
IconHelpCircle,
IconCircle,
IconCircleDashed,
IconCircleFilled,
IconCircleCheck,
TablerIconsProps,
} from "@tabler/icons-react";

import { SnippetModel } from "../data/repositories/snippets";

export enum SnippetStatus {
Unknown,
New,
Processing,
Raw,
Edited,
Finished,
}

export function getSnippetStatus(snippet?: SnippetModel): SnippetStatus {
if (!snippet) {
return SnippetStatus.Unknown;
}

if (snippet.content === "" && snippet.recordedAt === 0) {
return SnippetStatus.New;
} else if (snippet.recordedAt > snippet.processedAt) {
return SnippetStatus.Processing;
} else if (snippet.processedAt >= snippet.modifiedAt) {
return SnippetStatus.Raw;
} else if (snippet.finishedAt < snippet.modifiedAt) {
return SnippetStatus.Edited;
} else {
return SnippetStatus.Finished;
}
}

const iconLookupTable: Record<
SnippetStatus,
{
color: string;
label: string;
component: (props: TablerIconsProps) => Element;
}
> = {
[SnippetStatus.Unknown]: {
color: "gray",
label: "Unknown",
component: IconHelpCircle as any,
},
[SnippetStatus.New]: {
color: "gray",
label: "No Content",
component: IconCircle as any,
},
[SnippetStatus.Processing]: {
color: "blue",
label: "Processing",
component: IconCircleDashed as any,
},
[SnippetStatus.Raw]: {
color: "gray",
label: "Unedited",
component: IconCircleFilled as any,
},
[SnippetStatus.Edited]: {
color: "blue",
label: "Edited",
component: IconCircleCheck as any,
},
[SnippetStatus.Finished]: {
color: "green",
label: "Finished",
component: IconCircleCheck as any,
},
};

export function SnippetStatusIcon({
snippet,
height,
}: {
snippet?: SnippetModel;
height: number;
}) {
const status = getSnippetStatus(snippet);
const statusComponent = iconLookupTable[status];
const Component = statusComponent.component as any;

return (
<Component
height={height}
color={statusComponent.color}
aria-label={statusComponent.label}
/>
);
}
75 changes: 9 additions & 66 deletions src/routes/Chapter.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import { useEffect } from "react";
import { Link, Outlet, useNavigate, useParams } from "react-router-dom";
import { ActionIcon, Box, Flex, Menu, Text, ScrollArea } from "@mantine/core";
import { ActionIcon, Flex, Menu, Text, ScrollArea } from "@mantine/core";
import { Tree } from "react-arborist";
import { useAtom } from "jotai";
import { useDisclosure } from "@mantine/hooks";
import { clsx } from "clsx";

import { SnippetsCRUD, SnippetModel } from "../data/repositories/snippets";
import {
IconDots,
IconTextSize,
IconPlus,
IconTrash,
IconCircle,
IconCircleDashed,
IconCircleCheck,
IconCircleFilled,
IconHelpCircle,
} from "@tabler/icons-react";

import {
currentChapter,
currentChapterId,
Expand All @@ -24,10 +21,11 @@ import {
currentSnippets,
fetchTimestamp,
} from "../state/main";

import { ChaptersCRUD } from "../data/repositories/chapters";
import { SnippetsCRUD } from "../data/repositories/snippets";
import { CreateOrUpdateModal } from "../components/CreateOrUpdateModal";
import { useDisclosure } from "@mantine/hooks";
import { clsx } from "clsx";
import { SnippetStatusIcon } from "../components/SnippetStatusIcon";

export function Chapter() {
const navigate = useNavigate();
Expand All @@ -43,7 +41,7 @@ export function Chapter() {

useEffect(() => {
setCurrentSnippetId(snippetId ? parseInt(snippetId) : undefined);
}, [snippetId]);
}, [snippetId, setCurrentSnippetId]);

const [
editChapterModalOpened,
Expand Down Expand Up @@ -152,7 +150,7 @@ export function Chapter() {
})}
>
<Flex align="center">
<SnippetIcon snippet={node.data} height={24} />
<SnippetStatusIcon snippet={node.data} height={24} />
<Text>{node.data.label}</Text>
</Flex>
</Link>
Expand Down Expand Up @@ -190,58 +188,3 @@ export function Chapter() {
</Flex>
);
}

// enum SnippetStatus {
// Unknown = "unknown",
// New = "new",
// Processing = "processing",
// Raw = "raw",
// Edited = "edited",
// Finished = "finished",
// }

function SnippetIcon({
snippet,
height,
}: {
snippet: SnippetModel;
height: number;
}) {
// let status = SnippetStatus.Unknown;
let statusComponent = (
<IconHelpCircle color="gray" aria-label="Unknown" height={height} />
);

if (snippet.content === "" && snippet.recordedAt === 0) {
// status = SnippetStatus.New;
statusComponent = (
<IconCircle color="gray" aria-label="No Content" height={height} />
);
} else if (snippet.recordedAt > snippet.processedAt) {
// status = SnippetStatus.Processing;
statusComponent = (
<IconCircleDashed color="blue" aria-label="Processing" height={height} />
);
} else if (snippet.processedAt >= snippet.modifiedAt) {
// status = SnippetStatus.Raw;
statusComponent = (
<IconCircleFilled color="gray" aria-label="Unedited" height={height} />
);
} else if (snippet.finishedAt < snippet.modifiedAt) {
// status = SnippetStatus.Edited;
statusComponent = (
<IconCircleFilled color="blue" aria-label="Edited" height={height} />
);
} else {
// status = SnippetStatus.Finished;
statusComponent = (
<IconCircleCheck color="green" aria-label="Finished" height={height} />
);
}

return (
<Flex mr={4} align="center">
{statusComponent}
</Flex>
);
}
Loading

0 comments on commit 63a4aad

Please sign in to comment.