From 680697b78cde025048afc979fabf4eccd94a60d5 Mon Sep 17 00:00:00 2001 From: smoothwizz Date: Tue, 2 Apr 2024 19:29:49 +0300 Subject: [PATCH] feat(dashboard): simplify task editor --- client/components/common/Modal/Modal.tsx | 48 +++++++++++ client/components/common/Modal/index.ts | 3 + .../components/forms/buttons/ButtonCircle.tsx | 11 +-- .../DescriptionField.component.tsx | 2 - .../components/overview/OverviewSection.tsx | 83 ++++++++----------- .../TemplateSection.component.tsx | 79 ++++++++++++++---- .../overview/TemplateSection/templates.ts | 2 +- 7 files changed, 156 insertions(+), 72 deletions(-) create mode 100644 client/components/common/Modal/Modal.tsx create mode 100644 client/components/common/Modal/index.ts diff --git a/client/components/common/Modal/Modal.tsx b/client/components/common/Modal/Modal.tsx new file mode 100644 index 0000000..e0b1c14 --- /dev/null +++ b/client/components/common/Modal/Modal.tsx @@ -0,0 +1,48 @@ +// Modal as a separate component +import ButtonSecondary from '@/components/forms/buttons/ButtonSecondary' +import { useEffect, useRef } from 'react' + +interface Props { + isOpen: boolean + children: React.ReactElement + onModalClose: () => void +} +function Modal({ isOpen, children, onModalClose }: Props) { + const ref = useRef(null) + + useEffect(() => { + if (isOpen) { + ref.current?.showModal() + } else { + ref.current?.close() + } + }, [isOpen]) + + return ( + +
+
+
+
+
+
{children}
+
+
+ onModalClose()}> + Cancel + +
+
+
+
+
+
+ ) +} + +export default Modal diff --git a/client/components/common/Modal/index.ts b/client/components/common/Modal/index.ts new file mode 100644 index 0000000..498702f --- /dev/null +++ b/client/components/common/Modal/index.ts @@ -0,0 +1,3 @@ +import Modal from './Modal' + +export default Modal diff --git a/client/components/forms/buttons/ButtonCircle.tsx b/client/components/forms/buttons/ButtonCircle.tsx index a9e6305..1844af0 100644 --- a/client/components/forms/buttons/ButtonCircle.tsx +++ b/client/components/forms/buttons/ButtonCircle.tsx @@ -1,13 +1,13 @@ import React from 'react' interface Props { - text: string + children: string | React.ReactElement action: () => void isDisabled?: boolean style?: string } -const ButtonCircle = ({ text, action, isDisabled, style = '' }: Props) => { +const ButtonCircle = ({ children, action, isDisabled, style = '' }: Props) => { return ( ) } -const buttonStyles = `mx-auto w-6 h-6 rounded-full text-white font-medium text-xs leading-tight +const buttonStyles = `w-6 h-6 rounded-full text-white font-medium text-xs leading-tight uppercase shadow-md cursor-pointer - border border-gray-800 bg-gray-600 + border border-gray-800 dark:border-slate-600 bg-gray-600 hover:bg-gray-800 hover:shadow-lg hover:outline-none hover:ring-0 + flex justify-center items-center focus:bg-gray-800 focus:shadow-lg focus:outline-none focus:ring-0 disabled:pointer-events-none active:bg-gray-800 active:shadow-lg disabled:opacity-25 transition duration-150 ease-in-out` diff --git a/client/components/overview/DescriptionField/DescriptionField.component.tsx b/client/components/overview/DescriptionField/DescriptionField.component.tsx index b667901..089fee6 100644 --- a/client/components/overview/DescriptionField/DescriptionField.component.tsx +++ b/client/components/overview/DescriptionField/DescriptionField.component.tsx @@ -24,8 +24,6 @@ const DescriptionField = () => { label="Task Details" value={description} handleCursorPositionUpdate={(pos: number) => setCursorPosition(pos)} - helpText="* A brief overview of what needs to be accomplished, in which you can - use markdown for detailed formatting." /> ) diff --git a/client/components/overview/OverviewSection.tsx b/client/components/overview/OverviewSection.tsx index 78f9128..fc85fe6 100644 --- a/client/components/overview/OverviewSection.tsx +++ b/client/components/overview/OverviewSection.tsx @@ -10,8 +10,6 @@ import Seo from '../Seo' import SnippetsSection from './SnippetsSection/SnippetsSection' import Timer from '../timer' import MarkdownPreview from './MarkdownPreview' -import Tabs from '../tabs' -import { Tab, TabVariant } from '../tabs/Tabs' import TaskDetails from './TaskDetails' import SubtasksSection from './SubtasksSection' import Greeting from '../common/Greeting' @@ -25,6 +23,8 @@ import { } from './TemplateSection/templates' import { TemplateVariant } from './TemplateSection/TemplateSection.component' import { getCurrentDate } from 'utils/functions' +import ButtonCircle from '../forms/buttons/ButtonCircle' +import { FaEye, FaEyeSlash } from 'react-icons/fa' type Props = { handleReset: () => void @@ -37,7 +37,8 @@ const OverviewSection = ({ handleReset }: Props) => { const pageTitle = OVERVIEW_PAGE_TITLE const myStore = createStore() const [showConfetti, setShowConfetti] = useState(false) - const [activeTab, setActiveTab] = useState('edit') + const [isPreview, setIsPreview] = useState(false) + const [, setTitle] = useAtom(atom_title) const [, setDescription] = useAtom(atom_description) @@ -66,48 +67,37 @@ const OverviewSection = ({ handleReset }: Props) => { ) function renderTaskDashboard() { - const tabList: Array = [ - { - id: 1, - name: 'edit', - label: 'Plan & Write', - }, - { - id: 2, - name: 'preview', - label: 'Focused Task', - }, - ] - return (
- {activeTab === 'edit' && ( - <> -
-

- Ready for a focused session? -

- <> -

Define your task.

-

- - Need help getting started? - -

- -
- - - - )} - {activeTab === 'preview' && } - - setActiveTab(tab)} - /> - {activeTab === 'preview' && renderInfoMessages()} +
+
+

+ Ready for a focused session? +

+ <> +

Define your task.

+

+ + Need help getting started? + +

+ +
+
+ setIsPreview(!isPreview)}> + {isPreview ? : } + + { + loadTemplate(variant) + setIsPreview(false) + }} + /> +
+ {!isPreview && } + {isPreview && } +
+ {renderInfoMessages()}
@@ -123,8 +113,8 @@ const OverviewSection = ({ handleReset }: Props) => { function handleTutorialStart(): () => void { return () => { + setIsPreview(true) loadTemplate('tutorial') - setActiveTab('preview') } } @@ -137,7 +127,7 @@ const OverviewSection = ({ handleReset }: Props) => { } return ( - <> +
{showConfetti ? 'Congratulations! Starting up a new one...' @@ -149,14 +139,13 @@ const OverviewSection = ({ handleReset }: Props) => { )} {showConfetti && } - +
) } function markTaskAsCompleted() { setShowConfetti(true) setTimeout(() => { - setActiveTab('edit') handleReset() setShowConfetti(false) }, CONFETTI_TIMER - 1000) diff --git a/client/components/overview/TemplateSection/TemplateSection.component.tsx b/client/components/overview/TemplateSection/TemplateSection.component.tsx index e104795..3261974 100644 --- a/client/components/overview/TemplateSection/TemplateSection.component.tsx +++ b/client/components/overview/TemplateSection/TemplateSection.component.tsx @@ -1,5 +1,7 @@ +import Modal from '@/components/common/Modal' +import ButtonFontIcon from '@/components/forms/buttons/ButtonFontIcon' import ButtonSecondary from '@/components/forms/buttons/ButtonSecondary' -import React from 'react' +import React, { useState } from 'react' export type TemplateVariant = | 'feature' @@ -10,9 +12,9 @@ export type TemplateVariant = | 'tutorial' type Template = { - id: number name: TemplateVariant label: string + description: string } interface Props { @@ -20,49 +22,92 @@ interface Props { } const TemplateSection = ({ handleTemplateChange }: Props) => { + const [isModalOpen, setIsModalOpen] = useState(false) + const templateList: Array