diff --git a/web/e2e/utils/config.ts b/web/e2e/utils/config.ts index 89f37289bd..8e457f5251 100644 --- a/web/e2e/utils/config.ts +++ b/web/e2e/utils/config.ts @@ -8,6 +8,7 @@ export const config = { authClientId: process.env["REEARTH_WEB_AUTH0_CLIENT_ID"], authUrl: process.env["REEARTH_WEB_AUTH0_DOMAIN"], signUpSecret: process.env["REEARTH_WEB_E2E_SIGNUP_SECRET"], + developerMode: process.env["REEARTH_WEB_DEVELOPER_MODE"], }; export type Config = typeof config; diff --git a/web/src/classic/components/atoms/Icon/Icons/defaultBetaProjectImage.png b/web/src/classic/components/atoms/Icon/Icons/defaultBetaProjectImage.png new file mode 100644 index 0000000000..0e1b94e9f2 Binary files /dev/null and b/web/src/classic/components/atoms/Icon/Icons/defaultBetaProjectImage.png differ diff --git a/web/src/classic/components/molecules/Dashboard/defaultProjectImage.jpg b/web/src/classic/components/atoms/Icon/Icons/defaultProjectImage.jpg similarity index 100% rename from web/src/classic/components/molecules/Dashboard/defaultProjectImage.jpg rename to web/src/classic/components/atoms/Icon/Icons/defaultProjectImage.jpg diff --git a/web/src/classic/components/molecules/Common/Header/types.ts b/web/src/classic/components/molecules/Common/Header/types.ts index b3e297b715..d167256bdd 100644 --- a/web/src/classic/components/molecules/Common/Header/types.ts +++ b/web/src/classic/components/molecules/Common/Header/types.ts @@ -1,3 +1,5 @@ +import { ProjectType } from "@reearth/types"; + export type User = { name: string; }; @@ -15,4 +17,5 @@ export type Workspace = { export type Project = { id?: string; name?: string; + projectType?: ProjectType; }; diff --git a/web/src/classic/components/molecules/Common/ProjectCreationModal/index.tsx b/web/src/classic/components/molecules/Common/ProjectCreationModal/index.tsx index 55df016bf0..c5ce975229 100644 --- a/web/src/classic/components/molecules/Common/ProjectCreationModal/index.tsx +++ b/web/src/classic/components/molecules/Common/ProjectCreationModal/index.tsx @@ -3,22 +3,26 @@ import React, { useCallback, useEffect } from "react"; import Button from "@reearth/classic/components/atoms/Button"; import Divider from "@reearth/classic/components/atoms/Divider"; +import defaultBetaProjectImage from "@reearth/classic/components/atoms/Icon/Icons/defaultBetaProjectImage.png"; +import defaultProjectImage from "@reearth/classic/components/atoms/Icon/Icons/defaultProjectImage.jpg"; import Loading from "@reearth/classic/components/atoms/Loading"; import Modal from "@reearth/classic/components/atoms/Modal"; import Text from "@reearth/classic/components/atoms/Text"; -import defaultProjectImage from "@reearth/classic/components/molecules/Dashboard/defaultProjectImage.jpg"; import { useT } from "@reearth/services/i18n"; import { styled, useTheme } from "@reearth/services/theme"; import fonts from "@reearth/services/theme/fonts"; +import { ProjectType } from "@reearth/types"; export interface FormValues { name: string; description: string; imageUrl: string; + projectType: ProjectType; } export interface Props { open?: boolean; + projectType?: ProjectType; onClose?: (refetch?: boolean) => void; onSubmit?: (values: FormValues) => Promise | void; selectedAsset?: string; @@ -30,10 +34,12 @@ const initialValues: FormValues = { name: "", description: "", imageUrl: "", + projectType: "classic", }; const ProjectCreationModal: React.FC = ({ open, + projectType, onClose, onSubmit, selectedAsset, @@ -62,7 +68,10 @@ const ProjectCreationModal: React.FC = ({ if (selectedAsset) { formik.setFieldValue("imageUrl", selectedAsset); } - }, [selectedAsset]); // eslint-disable-line react-hooks/exhaustive-deps + if (projectType) { + formik.setFieldValue("projectType", projectType); + } + }, [selectedAsset, projectType]); // eslint-disable-line react-hooks/exhaustive-deps const handleCreate = useCallback(async () => { await formik.submitForm(); @@ -117,7 +126,11 @@ const ProjectCreationModal: React.FC = ({ {t("Select thumbnail image")} - + {assetModal} @@ -156,8 +169,13 @@ const StyledTextArea = styled.textarea` padding: 5px; `; -const Thumbnail = styled.div<{ url: string }>` - background-image: ${props => (props.url ? `url(${props.url})` : `url(${defaultProjectImage})`)}; +const Thumbnail = styled.div<{ url: string; projectType?: ProjectType }>` + background-image: ${props => + props.url + ? `url(${props.url})` + : props.projectType === "beta" + ? `url(${defaultBetaProjectImage})` + : `url(${defaultProjectImage})`}; background-size: cover; background-position: center; height: 242px; diff --git a/web/src/classic/components/molecules/Common/ProjectTypeSelectionModal/index.stories.tsx b/web/src/classic/components/molecules/Common/ProjectTypeSelectionModal/index.stories.tsx new file mode 100644 index 0000000000..e119aa9b44 --- /dev/null +++ b/web/src/classic/components/molecules/Common/ProjectTypeSelectionModal/index.stories.tsx @@ -0,0 +1,18 @@ +import { action } from "@storybook/addon-actions"; +import { Meta, Story } from "@storybook/react"; + +import ProjectTypeSelectionModal, { Props } from "."; + +export default { + title: "molecules/common/ProjectTypeSelectionModal", + component: ProjectTypeSelectionModal, +} as Meta; + +export const Default: Story = args => ( + +); diff --git a/web/src/classic/components/molecules/Common/ProjectTypeSelectionModal/index.tsx b/web/src/classic/components/molecules/Common/ProjectTypeSelectionModal/index.tsx new file mode 100644 index 0000000000..78498804c4 --- /dev/null +++ b/web/src/classic/components/molecules/Common/ProjectTypeSelectionModal/index.tsx @@ -0,0 +1,104 @@ +import React, { useCallback } from "react"; + +import Icon from "@reearth/classic/components/atoms/Icon"; +import Modal from "@reearth/classic/components/atoms/Modal"; +import Text from "@reearth/classic/components/atoms/Text"; +import { useT } from "@reearth/services/i18n"; +import { styled, useTheme } from "@reearth/services/theme"; +import { ProjectType } from "@reearth/types"; + +export interface Props { + open?: boolean; + onClose?: () => void; + onSubmit?: (projectType: ProjectType) => void; +} + +const ProjectTypeSelectionModal: React.FC = ({ open, onClose, onSubmit }) => { + const t = useT(); + const theme = useTheme(); + const handleTypeSelect = useCallback( + (projectType: ProjectType) => { + onSubmit?.(projectType); + onClose?.(); + }, + [onSubmit, onClose], + ); + + const handleCloseModal = useCallback(() => { + onClose?.(); + }, [onClose]); + + return ( + + + {t("Choose Project Type")} + + + handleTypeSelect("classic")}> + + + {t("classic")} + + + {t("Create project with classic UI")} + + + handleTypeSelect("beta")}> + + + {t("Beta")} + + + {t( + "Create project with the latest features and UI system (projects might break without prior notice)", + )} + + + + + ); +}; + +const ModalWrapper = styled(Modal)` + padding: 20px 32px 36px; + gap: 12px; + width: 756px; + height: 528px; +`; + +const TitleText = styled(Text)` + margin-top: 56px; + text-align: center; +`; +const ProjectTypeContainer = styled.div` + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 32px 56px 32px 36px; + gap: 102px; + height: 373px; +`; + +const ProjectTypeItem = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 20px; + gap: 12px; + width: 194px; + height: 194px; + border: 1px dashed #4a4a4a; + cursor: pointer; +`; + +const HintText = styled(Text)` + margin-top: 12px; + width: 154px; + height: 42px; + line-height: 14px; + text-align: center; +`; + +export default ProjectTypeSelectionModal; diff --git a/web/src/classic/components/molecules/Dashboard/Project.tsx b/web/src/classic/components/molecules/Dashboard/Project.tsx index dcf63fd0dd..1dc90e35df 100644 --- a/web/src/classic/components/molecules/Dashboard/Project.tsx +++ b/web/src/classic/components/molecules/Dashboard/Project.tsx @@ -6,17 +6,18 @@ import { useMedia } from "react-use"; import Button from "@reearth/classic/components/atoms/Button"; import Flex from "@reearth/classic/components/atoms/Flex"; +import defaultBetaProjectImage from "@reearth/classic/components/atoms/Icon/Icons/defaultBetaProjectImage.png"; +import defaultProjectImage from "@reearth/classic/components/atoms/Icon/Icons/defaultProjectImage.jpg"; import PublicationStatus from "@reearth/classic/components/atoms/PublicationStatus"; import Text from "@reearth/classic/components/atoms/Text"; -import { Project as ProjectType } from "@reearth/classic/components/molecules/Dashboard/types"; +import { Project as ProjectObjType } from "@reearth/classic/components/molecules/Dashboard/types"; import { useT } from "@reearth/services/i18n"; import { styled, useTheme } from "@reearth/services/theme"; - -import defaultProjectImage from "./defaultProjectImage.jpg"; +import { ProjectType } from "@reearth/types"; export type Props = { className?: string; - project: ProjectType; + project: ProjectObjType; }; const Project: React.FC = ({ className, project }) => { @@ -39,6 +40,7 @@ const Project: React.FC = ({ className, project }) => { setHover(true)} onMouseLeave={() => setHover(false)}> @@ -47,7 +49,10 @@ const Project: React.FC = ({ className, project }) => { - +