Skip to content

Commit

Permalink
feat(web): Implement the basic panel structure (#1138)
Browse files Browse the repository at this point in the history
Co-authored-by: airslice <[email protected]>
  • Loading branch information
mkumbobeaty and airslice authored Sep 10, 2024
1 parent 58a108a commit 2f8bc87
Show file tree
Hide file tree
Showing 37 changed files with 400 additions and 180 deletions.
1 change: 0 additions & 1 deletion web/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import GlobalModal from "@reearth/beta/features/GlobalModal";
import NotificationBanner from "@reearth/beta/features/Notification";
import { Provider as I18nProvider } from "@reearth/services/i18n";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { filterVisibleItems } from "@reearth/beta/ui/fields/utils";
import { useInfoboxFetcher } from "@reearth/services/api";
import { Item, convert } from "@reearth/services/api/propertyApi/utils";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { CodeInput } from "@reearth/beta/lib/reearth-ui";
import { SetStateAction } from "jotai";
import { Dispatch, FC } from "react";

import NoStyleMessage from "./NoStyleMessage";

type CodeTabProps = {
hasLayerStyleSelected: boolean;
styleCode: string | undefined;
setStyleCode: Dispatch<SetStateAction<string | undefined>>;
};

const CodeTab: FC<CodeTabProps> = ({
hasLayerStyleSelected,
styleCode,
setStyleCode
}) => {
const handleStyleCodeChange = (newStyleCode?: string) => {
setStyleCode(newStyleCode);
};

return hasLayerStyleSelected ? (
<CodeInput
value={styleCode}
onChange={handleStyleCodeChange}
language="json"
/>
) : (
<NoStyleMessage />
);
};

export default CodeTab;
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Button, TabItem, Tabs } from "@reearth/beta/lib/reearth-ui";
import { LayerStyle } from "@reearth/services/api/layerStyleApi/utils";
import { useT } from "@reearth/services/i18n";
import { styled, useTheme } from "@reearth/services/theme";
import { SetStateAction } from "jotai";
import { Dispatch, FC } from "react";

import NoStyleMessage from "./NoStyleMessage";

type InterfaceTabProps = {
layerStyle: LayerStyle | undefined;
setLayerStyle: Dispatch<SetStateAction<LayerStyle | undefined>>;
};

const InterfaceTab: FC<InterfaceTabProps> = ({
layerStyle,
setLayerStyle: _todo // avoid unused variable warning
}) => {
const theme = useTheme();
const t = useT();

//Null will be replaced by corresponding component on next step
const tabsItem: TabItem[] = [
{
id: "marker",
icon: "points",
children: null
},
{
id: "polyline",
icon: "polyline",
children: null
},
{
id: "polygon",
icon: "polygon",
children: null
},
{
id: "threedtiles",
icon: "buildings",
children: null
},
{
id: "model",
icon: "cube",
children: null
}
];

return layerStyle ? (
<Wrapper>
<TabsWrapper>
<Tabs
tabs={tabsItem}
position="top"
alignment="center"
background={theme.bg[1]}
/>
</TabsWrapper>
{layerStyle && (
<Button
title={t("New node")}
extendWidth
size="small"
icon="plus"
appearance="primary"
/>
)}
</Wrapper>
) : (
<NoStyleMessage />
);
};

export default InterfaceTab;

const Wrapper = styled("div")(() => ({
width: "100%"
}));

const TabsWrapper = styled("div")(() => ({
display: "flex",
flexDirection: "column"
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Typography } from "@reearth/beta/lib/reearth-ui";
import { useT } from "@reearth/services/i18n";
import { styled, useTheme } from "@reearth/services/theme";
import { FC } from "react";

const NoStyleMessage: FC = () => {
const theme = useTheme();
const t = useT();

return (
<TextWrapper>
<Typography size="body" color={theme.content.weak}>
{t("No style selected")}
</Typography>
</TextWrapper>
);
};

export default NoStyleMessage;

const TextWrapper = styled("div")(() => ({
height: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center"
}));
112 changes: 112 additions & 0 deletions web/src/beta/features/Editor/Map/LayerStylePanel/Editor/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Button, TabItem, Tabs } from "@reearth/beta/lib/reearth-ui";
import { LayerStyle } from "@reearth/services/api/layerStyleApi/utils";
import { useT } from "@reearth/services/i18n";
import { useNotification } from "@reearth/services/state";
import { styled } from "@reearth/services/theme";
import { FC, useCallback, useEffect, useState } from "react";

import { LayerStyleValueUpdateProps } from "../../../hooks/useLayerStyles";

import CodeTab from "./CodeTab";
import InterfaceTab from "./InterfaceTab";

type LayerStyleEditorProps = {
selectedLayerStyle?: LayerStyle;
onLayerStyleValueUpdate?: (inp: LayerStyleValueUpdateProps) => void;
};

const LayerStyleEditor: FC<LayerStyleEditorProps> = ({
selectedLayerStyle,
onLayerStyleValueUpdate
}) => {
const t = useT();
const [, setNotification] = useNotification();

const [layerStyle, setLayerStyle] = useState(selectedLayerStyle);
useEffect(() => {
setLayerStyle(selectedLayerStyle);
}, [selectedLayerStyle]);

const [styleCode, setStyleCode] = useState<string | undefined>("");
useEffect(() => {
setStyleCode(JSON.stringify(layerStyle?.value, null, 2));
}, [layerStyle]);

const handleSubmit = useCallback(() => {
if (!layerStyle?.id) return;
try {
const parsedStyle = JSON.parse(styleCode || "");
setLayerStyle((prev) => {
if (!prev?.id) return prev;
return {
...prev,
value: parsedStyle
};
});
onLayerStyleValueUpdate?.({
styleId: layerStyle.id,
value: parsedStyle
});
} catch (_e) {
setNotification({ type: "error", text: t("Invalid style") });
}
}, [styleCode, onLayerStyleValueUpdate, layerStyle, setNotification, t]);

const tabItems: TabItem[] = [
//Making code default tab temporary
{
id: "code",
name: t("Code"),
children: (
<CodeTab
styleCode={styleCode}
setStyleCode={setStyleCode}
hasLayerStyleSelected={!!layerStyle?.id}
/>
)
},
{
id: "interface",
name: t("Interface"),
children: (
<InterfaceTab layerStyle={layerStyle} setLayerStyle={setLayerStyle} />
)
}
];

return (
<EditorContainer>
<Tabs tabs={tabItems} position="top" alignment="end" />
{layerStyle?.id && (
<ButtonWrapper>
<Button
title={t("Save")}
extendWidth
size="small"
icon="floppyDisk"
onClick={handleSubmit}
/>
</ButtonWrapper>
)}
</EditorContainer>
);
};

const EditorContainer = styled("div")(({ theme }) => ({
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "space-between",
gap: theme.spacing.small,
background: theme.bg[1]
}));

const ButtonWrapper = styled("div")(({ theme }) => ({
borderTop: `1px solid ${theme.outline.weaker}`,
padding: theme.spacing.small,
width: "100%"
}));

export default LayerStyleEditor;

This file was deleted.

Loading

0 comments on commit 2f8bc87

Please sign in to comment.