From 9d3a856e8c63a79eba49d41ad24e52fef3205540 Mon Sep 17 00:00:00 2001 From: Aman Agarwal Date: Tue, 21 Nov 2023 15:57:26 +0530 Subject: [PATCH 1/8] feat(docker): adding docker config --- Dockerfile | 23 +++++++++++++++++++++++ docker-compose.yml | 9 +++++++++ next.config.js | 1 + 3 files changed, 33 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6798eae --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Use the official Node.js 14 image as a base +FROM node:18-alpine + +# Set the working directory inside the container +WORKDIR /usr/src/app + +# Copy package.json and package-lock.json to the working directory +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Copy the rest of the application code to the container +COPY . . + +# Build the Next.js app +RUN npm run build + +# Expose the desired port +EXPOSE 3000 + +# Start the Next.js app +CMD ["node", "server.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e31e694 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3' + +services: + admin-ui: + build: + context: . + dockerfile: Dockerfile + ports: + - "3000:3000" diff --git a/next.config.js b/next.config.js index caecedc..b529825 100644 --- a/next.config.js +++ b/next.config.js @@ -6,6 +6,7 @@ const nextConfig = { reactStrictMode: true, swcMinify: true, + output: 'standalone', // Uncoment to add domain whitelist // images: { From 8f76229b1893288042776e5f0acc44a1b03c9c42 Mon Sep 17 00:00:00 2001 From: faisalEsMagico Date: Tue, 21 Nov 2023 22:11:46 +0530 Subject: [PATCH 2/8] fix(build): fix build error --- next-env.d.ts | 1 - src/app/setup-new-configuration/page.tsx | 4 +- src/components/forms/DatePicker.tsx | 98 -------- src/components/forms/DropzoneInput.tsx | 224 ------------------ src/components/forms/ErrorMessage.tsx | 23 -- src/components/forms/FilePreview.tsx | 133 ----------- src/components/forms/Input.tsx | 88 ------- src/components/forms/PasswordInput.tsx | 95 -------- src/components/forms/SelectInput.tsx | 98 -------- src/components/forms/TextArea.tsx | 72 ------ src/components/uiComponents/AdminSelect.tsx | 4 +- src/components/uiComponents/SavedQuestion.tsx | 97 -------- .../wpcasOverView/LevelAndQuestion.tsx | 57 ----- .../wpcasOverView/SingleQuestion.tsx | 0 src/pages/sandbox/form.tsx | 105 -------- src/types/dropzone.ts | 3 - 16 files changed, 5 insertions(+), 1097 deletions(-) delete mode 100644 src/components/forms/DatePicker.tsx delete mode 100644 src/components/forms/DropzoneInput.tsx delete mode 100644 src/components/forms/ErrorMessage.tsx delete mode 100644 src/components/forms/FilePreview.tsx delete mode 100644 src/components/forms/Input.tsx delete mode 100644 src/components/forms/PasswordInput.tsx delete mode 100644 src/components/forms/SelectInput.tsx delete mode 100644 src/components/forms/TextArea.tsx delete mode 100644 src/components/uiComponents/SavedQuestion.tsx delete mode 100644 src/components/wpcasOverView/LevelAndQuestion.tsx delete mode 100644 src/components/wpcasOverView/SingleQuestion.tsx delete mode 100644 src/pages/sandbox/form.tsx delete mode 100644 src/types/dropzone.ts diff --git a/next-env.d.ts b/next-env.d.ts index fd36f94..4f11a03 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,5 @@ /// /// -/// // NOTE: This file should not be edited // see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/src/app/setup-new-configuration/page.tsx b/src/app/setup-new-configuration/page.tsx index 21d35bc..47cb9c3 100644 --- a/src/app/setup-new-configuration/page.tsx +++ b/src/app/setup-new-configuration/page.tsx @@ -28,8 +28,8 @@ export type SurveyDataType = { onboardingTime: string; }; -const SetupNewSurvey = ({ visible }: { visible: boolean }) => { - const [isOpen, setIsOpen] = useState(visible); +const SetupNewSurvey = () => { + const [isOpen, setIsOpen] = useState(false); const [isSuccessPopUpOpen, setIsSuccessPopUpOpen] = useState(false); const [isNewForm, setIsNewForm] = useState(false); diff --git a/src/components/forms/DatePicker.tsx b/src/components/forms/DatePicker.tsx deleted file mode 100644 index 82d212c..0000000 --- a/src/components/forms/DatePicker.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import clsx from 'clsx'; -import get from 'lodash.get'; -import ReactDatePicker, { ReactDatePickerProps } from 'react-datepicker'; -import { Controller, RegisterOptions, useFormContext } from 'react-hook-form'; -import { HiOutlineCalendar } from 'react-icons/hi'; - -import 'react-datepicker/dist/react-datepicker.css'; - -type DatePickerProps = { - validation?: RegisterOptions; - label: string; - id: string; - placeholder?: string; - defaultYear?: number; - defaultMonth?: number; - defaultValue?: string; - helperText?: string; - readOnly?: boolean; -} & Omit; - -export default function DatePicker({ - validation, - label, - id, - placeholder, - defaultYear, - defaultMonth, - defaultValue, - helperText, - readOnly = false, - ...rest -}: DatePickerProps) { - const { - formState: { errors }, - control, - } = useFormContext(); - const error = get(errors, id); - - // If there is a year default, then change the year to the props - const defaultDate = new Date(); - if (defaultYear) defaultDate.setFullYear(defaultYear); - if (defaultMonth) defaultDate.setMonth(defaultMonth); - - return ( -
- - - ( - <> -
- - -
-
- {helperText !== '' && ( -

{helperText}

- )} - {error && ( - - {error.message?.toString()} - - )} -
- - )} - /> -
- ); -} diff --git a/src/components/forms/DropzoneInput.tsx b/src/components/forms/DropzoneInput.tsx deleted file mode 100644 index 1bde92d..0000000 --- a/src/components/forms/DropzoneInput.tsx +++ /dev/null @@ -1,224 +0,0 @@ -import clsx from 'clsx'; -import get from 'lodash.get'; -import * as React from 'react'; -import { Accept, FileRejection, useDropzone } from 'react-dropzone'; -import { Controller, useFormContext } from 'react-hook-form'; - -import FilePreview from '@/components/forms/FilePreview'; - -import { FileWithPreview } from '@/types/dropzone'; - -type DropzoneInputProps = { - accept?: Accept; - helperText?: string; - id: string; - label: string; - maxFiles?: number; - readOnly?: boolean; - validation?: Record; -}; - -export default function DropzoneInput({ - accept, - helperText = '', - id, - label, - maxFiles = 1, - validation, - readOnly, -}: DropzoneInputProps) { - const { - control, - getValues, - setValue, - setError, - clearErrors, - formState: { errors }, - } = useFormContext(); - const error = get(errors, id); - - //#region //*=========== Error Focus =========== - const dropzoneRef = React.useRef(null); - - React.useEffect(() => { - error && dropzoneRef.current?.focus(); - }, [error]); - //#endregion //*======== Error Focus =========== - - const [files, setFiles] = React.useState( - getValues(id) || [] - ); - - const onDrop = React.useCallback( - (acceptedFiles: T[], rejectedFiles: FileRejection[]) => { - if (rejectedFiles && rejectedFiles.length > 0) { - setValue(id, files ? [...files] : null); - setError(id, { - type: 'manual', - message: rejectedFiles && rejectedFiles[0].errors[0].message, - }); - } else { - const acceptedFilesPreview = acceptedFiles.map((file: T) => - Object.assign(file, { - preview: URL.createObjectURL(file), - }) - ); - - setFiles( - files - ? [...files, ...acceptedFilesPreview].slice(0, maxFiles) - : acceptedFilesPreview - ); - - setValue( - id, - files - ? [...files, ...acceptedFiles].slice(0, maxFiles) - : acceptedFiles, - { - shouldValidate: true, - } - ); - clearErrors(id); - } - }, - [clearErrors, files, id, maxFiles, setError, setValue] - ); - - React.useEffect(() => { - return () => { - () => { - files.forEach((file) => URL.revokeObjectURL(file.preview)); - }; - }; - }, [files]); - - const deleteFile = ( - e: React.MouseEvent, - file: FileWithPreview - ) => { - e.preventDefault(); - const newFiles = [...files]; - - newFiles.splice(newFiles.indexOf(file), 1); - - if (newFiles.length > 0) { - setFiles(newFiles); - setValue(id, newFiles, { - shouldValidate: true, - shouldDirty: true, - shouldTouch: true, - }); - } else { - setFiles([]); - setValue(id, null, { - shouldValidate: true, - shouldDirty: true, - shouldTouch: true, - }); - } - }; - - const { getRootProps, getInputProps } = useDropzone({ - onDrop, - accept, - maxFiles, - maxSize: 1000000, - }); - - return ( -
- - - {readOnly && !(files?.length > 0) ? ( -
- No file uploaded -
- ) : files?.length >= maxFiles ? ( -
    - {files.map((file, index) => ( - - ))} -
- ) : ( - ( - <> -
- -
-
- -

- Drag and drop file here, or click to choose file -

-

{`${ - maxFiles - (files?.length || 0) - } file(s) remaining`}

-
-
-
- -
- {helperText !== '' && ( -

{helperText}

- )} - {error && ( -

- {error.message?.toString()} -

- )} -
- {!readOnly && !!files?.length && ( -
    - {files.map((file, index) => ( - - ))} -
- )} - - )} - /> - )} -
- ); -} diff --git a/src/components/forms/ErrorMessage.tsx b/src/components/forms/ErrorMessage.tsx deleted file mode 100644 index 7b77d20..0000000 --- a/src/components/forms/ErrorMessage.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import * as React from 'react'; -import { get, useFormState } from 'react-hook-form'; - -import clsxm from '@/lib/clsxm'; - -type ErrorMessageProps = { - id: string; -} & React.ComponentPropsWithoutRef<'p'>; - -export default function ErrorMessage({ - id, - className, - ...rest -}: ErrorMessageProps) { - const { errors } = useFormState(); - const error = get(errors, id); - - return ( -

- {error.message?.toString()} -

- ); -} diff --git a/src/components/forms/FilePreview.tsx b/src/components/forms/FilePreview.tsx deleted file mode 100644 index 95e47af..0000000 --- a/src/components/forms/FilePreview.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import * as React from 'react'; -import { - HiOutlineExternalLink, - HiOutlineEye, - HiOutlinePaperClip, - HiOutlinePhotograph, - HiX, -} from 'react-icons/hi'; -import Lightbox from 'react-image-lightbox'; - -import 'react-image-lightbox/style.css'; - -import UnstyledLink from '@/components/links/UnstyledLink'; - -import { FileWithPreview } from '@/types/dropzone'; - -type FilePreviewProps = { - file: FileWithPreview; -} & ( - | { - deleteFile?: ( - e: React.MouseEvent, - file: FileWithPreview - ) => void; - readOnly?: true; - } - | { - deleteFile: ( - e: React.MouseEvent, - file: FileWithPreview - ) => void; - readOnly?: false; - } -); - -export default function FilePreview({ - deleteFile, - file, - readOnly, -}: FilePreviewProps): React.ReactElement { - const [index, setIndex] = React.useState(0); - const [isOpen, setIsOpen] = React.useState(false); - - const images = [file.preview]; - - const handleDelete = (e: React.MouseEvent) => { - e.stopPropagation(); - deleteFile?.(e, file); - }; - - const imagesType = ['image/png', 'image/jpg', 'image/jpeg']; - - return imagesType.includes(file.type) ? ( - <> -
  • -
    -
    -
    - - {!readOnly && ( - - )} -
    -
  • - {isOpen && ( - setIsOpen(false)} - onMovePrevRequest={() => - setIndex( - (prevIndex) => (prevIndex + images.length - 1) % images.length - ) - } - onMoveNextRequest={() => - setIndex((prevIndex) => (prevIndex + 1) % images.length) - } - /> - )} - - ) : ( -
  • -
    -
    -
    - - - - {!readOnly && ( - - )} -
    -
  • - ); -} diff --git a/src/components/forms/Input.tsx b/src/components/forms/Input.tsx deleted file mode 100644 index d5a5991..0000000 --- a/src/components/forms/Input.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import clsx from 'clsx'; -import * as React from 'react'; -import { RegisterOptions, useFormContext } from 'react-hook-form'; -import { HiExclamationCircle } from 'react-icons/hi'; - -export type InputProps = { - /** Input label */ - label: string; - /** - * id to be initialized with React Hook Form, - * must be the same with the pre-defined types. - */ - id: string; - /** Input placeholder */ - placeholder?: string; - /** Small text below input, useful for additional information */ - helperText?: string; - /** - * Input type - * @example text, email, password - */ - type?: React.HTMLInputTypeAttribute; - /** Disables the input and shows defaultValue (can be set from React Hook Form) */ - readOnly?: boolean; - /** Disable error style (not disabling error validation) */ - hideError?: boolean; - /** Manual validation using RHF, it is encouraged to use yup resolver instead */ - validation?: RegisterOptions; -} & React.ComponentPropsWithoutRef<'input'>; - -export default function Input({ - label, - placeholder = '', - helperText, - id, - type = 'text', - readOnly = false, - hideError = false, - validation, - ...rest -}: InputProps) { - const { - register, - formState: { errors }, - } = useFormContext(); - - return ( -
    - -
    - - - {!hideError && errors[id] && ( -
    - -
    - )} -
    -
    - {helperText &&

    {helperText}

    } - {!hideError && errors[id] && ( - - {errors[id]?.message as unknown as string} - - )} -
    -
    - ); -} diff --git a/src/components/forms/PasswordInput.tsx b/src/components/forms/PasswordInput.tsx deleted file mode 100644 index 3823ee2..0000000 --- a/src/components/forms/PasswordInput.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import clsx from 'clsx'; -import { useState } from 'react'; -import { RegisterOptions, useFormContext } from 'react-hook-form'; -import { HiEye, HiEyeOff } from 'react-icons/hi'; - -export type PasswordInputProps = { - /** Input label */ - label: string; - /** - * id to be initialized with React Hook Form, - * must be the same with the pre-defined types. - */ - id: string; - /** Input placeholder */ - placeholder?: string; - /** Small text below input, useful for additional information */ - helperText?: string; - /** - * Input type - * @example text, email, password - */ - type?: React.HTMLInputTypeAttribute; - /** Disables the input and shows defaultValue (can be set from React Hook Form) */ - readOnly?: boolean; - /** Disable error style (not disabling error validation) */ - hideError?: boolean; - /** Manual validation using RHF, it is encouraged to use yup resolver instead */ - validation?: RegisterOptions; -} & React.ComponentPropsWithoutRef<'input'>; - -export default function PasswordInput({ - label, - placeholder = '', - helperText, - id, - readOnly = false, - validation, - ...rest -}: PasswordInputProps) { - const { - register, - formState: { errors }, - } = useFormContext(); - - const [showPassword, setShowPassword] = useState(false); - const togglePassword = () => setShowPassword((prev) => !prev); - - return ( -
    - -
    - - - -
    -
    - {helperText &&

    {helperText}

    } - {errors[id] && ( - - {errors[id]?.message as unknown as string} - - )} -
    -
    - ); -} diff --git a/src/components/forms/SelectInput.tsx b/src/components/forms/SelectInput.tsx deleted file mode 100644 index a5f5463..0000000 --- a/src/components/forms/SelectInput.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import clsx from 'clsx'; -import * as React from 'react'; -import { RegisterOptions, useFormContext } from 'react-hook-form'; -import { HiExclamationCircle } from 'react-icons/hi'; - -export type SelectInputProps = { - label: string; - id: string; - placeholder?: string; - helperText?: string; - type?: string; - readOnly?: boolean; - validation?: RegisterOptions; - children: React.ReactNode; -} & React.ComponentPropsWithoutRef<'select'>; - -export default function SelectInput({ - label, - helperText, - id, - placeholder, - readOnly = false, - children, - validation, - ...rest -}: SelectInputProps) { - const { - register, - formState: { errors }, - watch, - } = useFormContext(); - - const value = watch(id); - - // Add disabled and selected attribute to option, will be used if readonly - const readOnlyChildren = React.Children.map( - children, - (child) => { - if (React.isValidElement(child)) { - return React.cloneElement( - child as React.ReactElement, - { - disabled: child.props.value !== rest?.defaultValue, - } - ); - } - } - ); - - return ( -
    - -
    - - - {errors[id] && ( -
    - -
    - )} -
    -
    - {helperText &&

    {helperText}

    } - {errors[id] && ( - - {errors[id]?.message as unknown as string} - - )} -
    -
    - ); -} diff --git a/src/components/forms/TextArea.tsx b/src/components/forms/TextArea.tsx deleted file mode 100644 index 71ef336..0000000 --- a/src/components/forms/TextArea.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import clsx from 'clsx'; -import get from 'lodash.get'; -import { RegisterOptions, useFormContext } from 'react-hook-form'; -import { HiExclamationCircle } from 'react-icons/hi'; - -export type TextAreaProps = { - label: string; - id: string; - placeholder?: string; - helperText?: string; - readOnly?: boolean; - hideError?: boolean; - validation?: RegisterOptions; -} & React.ComponentPropsWithoutRef<'textarea'>; - -export default function TextArea({ - label, - placeholder = '', - helperText, - id, - readOnly = false, - hideError = false, - validation, - ...rest -}: TextAreaProps) { - const { - register, - formState: { errors }, - } = useFormContext(); - const error = get(errors, id); - - return ( -
    - -
    -