Skip to content

Commit

Permalink
feat: add settings menu for hiding sections
Browse files Browse the repository at this point in the history
  • Loading branch information
marespopa committed Jan 16, 2025
1 parent a7ee402 commit a92f611
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 54 deletions.
2 changes: 1 addition & 1 deletion client/components/common/Greeting/Greeting.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const Greeting = () => {
const greetingMessage = getGreetingMessage()

return (
<div className="w-full">
<div>
<h2
id="greeting"
className="text-lg text-gray-700 dark:text-gray-100 font-bold mt-3 mb-3"
Expand Down
2 changes: 2 additions & 0 deletions client/components/forms/buttons/ButtonIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import PauseSVG from 'icons/PauseSVG'
import SettingsSVG from 'icons/SettingsSVG'
import MaximizeSVG from 'icons/MaximizeSVG'
import MinimizeSVG from 'icons/MinimizeSVG'
import { FaTimes } from 'react-icons/fa'

const ButtonIconVariants = {
delete: <DeleteSVG />,
Expand All @@ -18,6 +19,7 @@ const ButtonIconVariants = {
log: <LogSVG />,
play: <PlaySVG />,
pause: <PauseSVG />,
close: <FaTimes />,
settings: <SettingsSVG />,
unlock: <span title="Unlock Scroll">🔓</span>,
}
Expand Down
14 changes: 7 additions & 7 deletions client/components/overview/NotesSection/NotesSections.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { useAtom } from 'jotai'
import { atom_notes } from 'jotai/atoms'

import React, { useRef, useState } from 'react'
import React, { Dispatch, SetStateAction, useRef } from 'react'
import SectionHeading from '../common/SectionHeading.component'
import Textarea from '@/components/forms/input/Textarea'

type Props = {}
interface Props {
toggle: Dispatch<SetStateAction<boolean>>
}

export default function NotesSection({}: Props) {
export default function NotesSection({toggle}: Props) {
const [notes, setNotes] = useAtom(atom_notes)
const [isExpanded, setIsExpanded] = useState(true)
const textareaRef = useRef<HTMLTextAreaElement>(null)

return (
Expand All @@ -22,10 +23,9 @@ export default function NotesSection({}: Props) {
subHeading={
'* Jot down distracting but important thoughts to revisit later.'
}
isExpanded={isExpanded}
handleToggle={() => setIsExpanded(!isExpanded)}
handleToggle={toggle}
/>
{isExpanded && renderTextarea()}
{renderTextarea()}
</section>
)

Expand Down
115 changes: 106 additions & 9 deletions client/components/overview/OverviewSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, { useState } from 'react'
'use client'

import React, { useEffect, useState } from 'react'
import { pagePadding } from '../common/common'
import ConfettiExplosion from 'react-confetti-explosion'

Expand All @@ -14,15 +16,22 @@ import TaskDetails from './TaskDetails'
import SubtasksSection from './SubtasksSection'
import Greeting from '../common/Greeting'
import TemplateSection from './TemplateSection'
import { atom_description, atom_filename } from 'jotai/atoms'
import { atom_description, atom_filename, atom_settings } from 'jotai/atoms'
import {
DEFAULT_TEMPLATES,
TEMPLATES_WITH_DATES,
} from './TemplateSection/templates'
import { TemplateVariant } from './TemplateSection/TemplateSection.component'
import { getCurrentDate } from 'utils/functions'
import ButtonCircle from '../forms/buttons/ButtonCircle'
import { FaExpand, FaEye, FaEyeSlash, FaFile, FaTimes } from 'react-icons/fa'
import {
FaCog,
FaExpand,
FaEye,
FaEyeSlash,
FaFile,
FaTimes,
} from 'react-icons/fa'
import OpenFileSection from './OpenFileSection'
import ButtonFontIcon from '../forms/buttons/ButtonFontIcon'
import SaveFileSection from './SaveFileSection'
Expand All @@ -40,18 +49,55 @@ const OverviewSection = ({ handleReset }: Props) => {
const CONFETTI_TIMER = 5000
const pageTitle = OVERVIEW_PAGE_TITLE
const myStore = createStore()
const [isMounted, setIsMounted] = useState(false)
const [isFocused, setIsFocused] = useState(false)
const [showConfetti, setShowConfetti] = useState(false)
const [isPreview, setIsPreview] = useState(false)
const [isUserSettingsMenuExpanded, setIsUserSettingsMenuExtended] =
useState(false)
const [userSettings, setUserSettings] = useAtom(atom_settings)

const toggleNotes = () => {
setUserSettings({ ...userSettings, showNotes: !userSettings.showNotes })
}

const toggleSnippets = () => {
setUserSettings({
...userSettings,
showSnippets: !userSettings.showSnippets,
})
}

const toggleSubtasks = () => {
setUserSettings({
...userSettings,
showSubtasks: !userSettings.showSubtasks,
})
}

const toggleTimer = () => {
setUserSettings({ ...userSettings, showTimer: !userSettings.showTimer })
}

const [, setFilename] = useAtom(atom_filename)
const [, setDescription] = useAtom(atom_description)

useEffect(() => {
setIsMounted(true)
}, [])

if (!isMounted) {
return <></>
}

return (
<Provider store={myStore}>
<Seo title={pageTitle} />
<section className={`${pagePadding}`}>
<Greeting />
<section className={`${pagePadding} pb-16`}>
<div className="flex justify-between flex-wrap">
<Greeting />
{renderSectionToggles()}
</div>
<div className={`${showConfetti && 'opacity-30'}`}>
{renderTaskDashboard()}
</div>
Expand All @@ -69,6 +115,7 @@ const OverviewSection = ({ handleReset }: Props) => {
setFilename(title)
setDescription(description)
}

function renderTask(isFocused: boolean) {
return (
<>
Expand Down Expand Up @@ -111,10 +158,60 @@ const OverviewSection = ({ handleReset }: Props) => {
{!isFocused && renderTask(isFocused)}
</div>
{renderInfoMessages()}
{!isFocused && <Timer />}
<SubtasksSection />
{<NotesSection />}
{<SnippetsSection />}
{!isFocused && userSettings.showTimer && <Timer />}
{userSettings.showSubtasks && (
<SubtasksSection toggle={toggleSubtasks} />
)}
{userSettings.showNotes && <NotesSection toggle={toggleTimer} />}
{userSettings.showSnippets && (
<SnippetsSection toggle={toggleSnippets} />
)}
</div>
)
}

function renderSectionToggles(): React.ReactNode {
return (
<div className="mt-2 text-blue-700 bg-white dark:bg-gray-600 dark:text-blue-300 px-4 py-2 items-center flex gap-2">
<ButtonLink
showAsLink={false}
action={() =>
setIsUserSettingsMenuExtended(!isUserSettingsMenuExpanded)
}
>
<FaCog />
</ButtonLink>
{isUserSettingsMenuExpanded && (
<>
<ButtonLink
showAsLink={false}
action={toggleSubtasks}
style="text-xs"
>
<span>
{userSettings.showSubtasks ? 'Hide' : 'Show'} Subtasks
</span>
</ButtonLink>

<ButtonLink showAsLink={false} action={toggleNotes} style="text-xs">
<span>{userSettings.showNotes ? 'Hide' : 'Show'} Notes</span>
</ButtonLink>

<ButtonLink
showAsLink={false}
action={toggleSnippets}
style="text-xs"
>
<span>
{userSettings.showSnippets ? 'Hide' : 'Show'} Snippets
</span>
</ButtonLink>

<ButtonLink showAsLink={false} action={toggleTimer} style="text-xs">
<span>{userSettings.showTimer ? 'Hide' : 'Show'} Timer</span>
</ButtonLink>
</>
)}
</div>
)
}
Expand Down
14 changes: 7 additions & 7 deletions client/components/overview/SnippetsSection/SnippetsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import { Snippet, atom_snippets } from 'jotai/atoms'
import SnippetItem from './SnippetItem'
import { FaPlusCircle } from 'react-icons/fa'

import React, { useState } from 'react'
import React, { Dispatch, SetStateAction } from 'react'
import { nanoid } from 'nanoid'
import SectionHeading from '../common/SectionHeading.component'

type Props = {}
interface Props {
toggle: Dispatch<SetStateAction<boolean>>
}

export default function SnippetsSection({}: Props) {
export default function SnippetsSection({toggle}: Props) {
const [list, setList] = useAtom(atom_snippets)
const [isExpanded, setIsExpanded] = useState(true)
const hasSnippets = list.length > 0

return (
Expand All @@ -23,10 +24,9 @@ export default function SnippetsSection({}: Props) {
subHeading={
'* Think of a snippet as a paragraph in a textbook: you sometimes want to save it for later'
}
isExpanded={isExpanded}
handleToggle={() => setIsExpanded(!isExpanded)}
handleToggle={toggle}
/>
{isExpanded && renderList()}
{renderList()}
</section>
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import SectionHeading from '@/components/overview/common/SectionHeading.component'
import SubtasksList from './SubtasksList'
import { useState } from 'react'
import { Dispatch, SetStateAction } from 'react'

const SubtasksSection = () => {
interface Props {
toggle: Dispatch<SetStateAction<boolean>>
}

const SubtasksSection = ({ toggle}: Props) => {
const description = ` List smaller, actionable items that need to be completed to achieve the main task.`
const subHeading =
'* This helps in making progress on larger tasks more manageable and trackable.'
const [isExpanded, setIsExpanded] = useState(true)

return (
<section className="mt-8">
<SectionHeading
title="Subtasks"
description={description}
subHeading={subHeading}
isExpanded={isExpanded}
handleToggle={() => setIsExpanded(!isExpanded)}
handleToggle={toggle}
/>
{isExpanded && (
<div className={`min-h-full w-full`}>
<SubtasksList />
</div>
)}
<div className={`min-h-full w-full`}>
<SubtasksList />
</div>
</section>
)
}
Expand Down
1 change: 0 additions & 1 deletion client/components/overview/TipsSection/TipsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const TipsSection = () => {
subHeading={
'* Simple strategies to combat distractions, get more done, and feel accomplished.'
}
isExpanded={isExpanded}
handleToggle={() => setIsExpanded(!isExpanded)}
/>
{isExpanded && (
Expand Down
28 changes: 9 additions & 19 deletions client/components/overview/common/SectionHeading.component.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,29 @@
import ButtonIcon from '@/components/forms/buttons/ButtonIcon'
import React from 'react'
import { HiOutlineChevronDown, HiOutlineChevronRight } from 'react-icons/hi'

interface Props {
title: string
description: string
subHeading?: string
isExpanded: boolean
handleToggle: () => void
handleToggle: any
}

const SectionHeading = ({
title,
description,
subHeading,
isExpanded,
handleToggle,
}: Props) => {
return (
<div className="w-full">
<h2
className="text-3xl font-bold mt-3 mb-3 flex items-center gap-2 cursor-pointer"
onClick={() => handleToggle()}
>
{title}{' '}
{isExpanded ? <HiOutlineChevronRight /> : <HiOutlineChevronDown />}
<h2 className="text-3xl font-bold mt-3 mb-3 flex items-start gap-1 cursor-pointer">
{title} <ButtonIcon variant="close" action={() => handleToggle()}/>
</h2>
{isExpanded && (
<>
<p className="my-5 mx-auto text-xl">{description}</p>
{subHeading && (
<p className="text-xs text-gray-500 -mt-4 mb-4 dark:text-gray-400">
{subHeading}
</p>
)}
</>
<p className="my-5 mx-auto text-xl">{description}</p>
{subHeading && (
<p className="text-xs text-gray-500 -mt-4 mb-4 dark:text-gray-400">
{subHeading}
</p>
)}
</div>
)
Expand Down
15 changes: 15 additions & 0 deletions client/jotai/atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ const KEYS = {
snippets: 'snippets',
subTasks: 'subtasks',
notes: 'notes',
userSettings: 'userSettings'
}

type USER_SETTINGS = {
showSubtasks: boolean,
showNotes: boolean,
showSnippets: boolean,
showTimer: boolean
}

export const atom_filename = atomWithStorage(KEYS.filename, 'task.md')
Expand All @@ -22,4 +30,11 @@ export const atom_description = atomWithStorage(
KEYS.description,
DEFAULT_TEMPLATES.blank.description,
)
export const atom_settings = atomWithStorage<USER_SETTINGS>(KEYS.userSettings, {
showSubtasks: true,
showNotes: true,
showSnippets: false,
showTimer: true,
})

export const atom_subTasks = atomWithStorage<Array<Task>>(KEYS.subTasks, [])

0 comments on commit a92f611

Please sign in to comment.