From edb79e7e93b36441107380e16a340234d121539b Mon Sep 17 00:00:00 2001 From: Michael Salim Date: Thu, 21 Nov 2024 20:56:44 +0000 Subject: [PATCH] Feat: Target date on create & edit, sort by target, update how name & target is shown --- README.md | 2 +- apps/homepage/package.json | 1 + .../DatePicker/datePickerReactSelect.tsx | 55 +++++++++++++ .../src/containers/CreateProjectModal.tsx | 42 +++++++--- .../src/containers/EditProjectModal.tsx | 32 +++++++- .../Dashboard/DashboardIndex.graphql | 2 +- apps/homepage/src/pages/_app.tsx | 1 + apps/homepage/src/pages/o/[slug]/index.tsx | 23 +++++- yarn.lock | 80 ++++++++++++++++++- 9 files changed, 218 insertions(+), 20 deletions(-) create mode 100644 apps/homepage/src/components/DatePicker/datePickerReactSelect.tsx diff --git a/README.md b/README.md index 0627e8e..36c84fe 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ We maintain a separate wiki page at https://docs.theopenpresenter.com. Please re ✅ Present in any device that can run a browser ✅ Collaborate & control presentation from anywhere ✅ Play video from various sources (Youtube, local, etc) +✅ Organize your past and future presentation sessions 🟨 Import & display lyrics from various sources with ease (currently only MyWorshipList) 🟨 Display slides from many different sources (currently only Google Slides) 🟨 Record audio and save it for future playback -⬜ Organize your past and future presentation sessions ⬜ Offline support Last but not least, the code for TheOpenPresenter will always be Open Source. We also promise to keep a hosted version of TheOpenPresenter free for small churches for as long as possible, the ones that will benefit from this project the most. diff --git a/apps/homepage/package.json b/apps/homepage/package.json index cdef9b7..f7a4bbf 100644 --- a/apps/homepage/package.json +++ b/apps/homepage/package.json @@ -31,6 +31,7 @@ "postcss-import": "^16.1.0", "random-word-slugs": "^0.1.7", "react": "rc", + "react-calendar": "^5.1.0", "react-dom": "rc", "react-icons": "^5.3.0", "react-qr-code": "^2.0.15", diff --git a/apps/homepage/src/components/DatePicker/datePickerReactSelect.tsx b/apps/homepage/src/components/DatePicker/datePickerReactSelect.tsx new file mode 100644 index 0000000..422541b --- /dev/null +++ b/apps/homepage/src/components/DatePicker/datePickerReactSelect.tsx @@ -0,0 +1,55 @@ +import React, { useCallback } from "react"; +import ReactCalendar from "react-calendar"; +import { + GroupBase, + MenuListProps, + Options, + Props, + SelectComponentsConfig, + StylesConfig, +} from "react-select"; + +const MenuList = (props: MenuListProps) => { + const onChange = useCallback( + (val: Date) => { + if (props.selectProps.onChange) { + props.selectProps?.onChange(val, { + // This doesn't do anything but the function wants it + action: "select-option", + option: { value: val, label: "" }, + name: "", + }); + if (props.selectProps.onMenuClose) { + props.selectProps.onMenuClose(); + } + } + }, + [props.selectProps], + ); + + return ( + onChange(val as Date)} + /> + ); +}; + +export const ReactSelectDateComponents: SelectComponentsConfig< + Options, + true, + any +> = { MenuList }; + +export const ReactSelectDateStyle: Partial< + StylesConfig> +> = { + container: (provided) => ({ ...provided, width: "100%" }), + menu: (provided) => ({ ...provided, width: 350, right: 0 }), +}; + +export const ReactSelectDateProps: Props = { + styles: ReactSelectDateStyle, + components: ReactSelectDateComponents, + menuPosition: "fixed", +}; diff --git a/apps/homepage/src/containers/CreateProjectModal.tsx b/apps/homepage/src/containers/CreateProjectModal.tsx index 375a4c3..f35cec7 100644 --- a/apps/homepage/src/containers/CreateProjectModal.tsx +++ b/apps/homepage/src/containers/CreateProjectModal.tsx @@ -1,3 +1,4 @@ +import { ReactSelectDateProps } from "@/components/DatePicker/datePickerReactSelect"; import { TagsSelector } from "@/components/Tag/TagsSelector"; import { useOrganizationSlug } from "@/lib/permissionHooks/organization"; import { @@ -21,12 +22,13 @@ import { useCreateTagMutation, } from "@repo/graphql"; import { globalState } from "@repo/lib"; -import { OverlayToggleComponentProps } from "@repo/ui"; +import { OverlayToggleComponentProps, formatHumanReadableDate } from "@repo/ui"; import { format } from "date-fns"; import { Form, Formik } from "formik"; import { InputControl, SelectControl, SubmitButton } from "formik-chakra-ui"; import { generateSlug } from "random-word-slugs"; import { useCallback, useMemo, useState } from "react"; +import Select from "react-select"; export type CreateProjectModalPropTypes = Omit< ModalProps, @@ -40,6 +42,7 @@ export type CreateProjectModalPropTypes = Omit< type FormInputs = { name: string; categoryId: string | undefined; + targetDate: Date | undefined; }; const CreateProjectModal = ({ @@ -74,9 +77,10 @@ const CreateProjectModal = ({ variables: { organizationId, slug: generateSlug(), - name: data.name === "" ? namePlaceholder : data.name, + name: data.name, categoryId: data.categoryId, tags: selectedTagIds, + targetDate: data.targetDate ? data.targetDate.toDateString() : null, }, }).then((x) => { const projectSlug = x.data?.createFullProject?.project?.slug; @@ -87,15 +91,7 @@ const CreateProjectModal = ({ onToggle?.(); resetData?.(); }, - [ - createProject, - namePlaceholder, - onToggle, - organizationId, - resetData, - selectedTagIds, - slug, - ], + [createProject, onToggle, organizationId, resetData, selectedTagIds, slug], ); return ( @@ -110,10 +106,11 @@ const CreateProjectModal = ({ initialValues={{ name: "", categoryId: undefined, + targetDate: undefined, }} onSubmit={handleSubmit} > - {({ handleSubmit }) => ( + {({ handleSubmit, values, setFieldValue }) => (
New Project @@ -125,6 +122,27 @@ const CreateProjectModal = ({ name="name" inputProps={{ placeholder: namePlaceholder }} /> + + + Service Time + { + setFieldValue("targetDate", val); + }} + isClearable + isSearchable={false} + /> + +