mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-02-04 01:32:54 +08:00
fix ssr
This commit is contained in:
parent
c093575700
commit
1286dbba13
@ -3,10 +3,7 @@ import Link from "next/link";
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { useLocalStorage } from "usehooks-ts";
|
import { useLocalStorage } from "usehooks-ts";
|
||||||
import { FaFileImport } from "react-icons/fa";
|
import { FaFileImport } from "react-icons/fa";
|
||||||
import {
|
import { MdUnfoldMore, MdUnfoldLess } from "react-icons/md";
|
||||||
MdUnfoldMore,
|
|
||||||
MdUnfoldLess,
|
|
||||||
} from "react-icons/md";
|
|
||||||
import {
|
import {
|
||||||
AiFillHome,
|
AiFillHome,
|
||||||
AiOutlineClear,
|
AiOutlineClear,
|
||||||
@ -25,6 +22,7 @@ import {
|
|||||||
import { getNextLayout } from "src/containers/LiveEditor/helpers";
|
import { getNextLayout } from "src/containers/LiveEditor/helpers";
|
||||||
import { StorageConfig } from "src/typings/global";
|
import { StorageConfig } from "src/typings/global";
|
||||||
import { CanvasDirection } from "reaflow";
|
import { CanvasDirection } from "reaflow";
|
||||||
|
import { useLoading } from "src/hooks/useLoading";
|
||||||
|
|
||||||
const StyledSidebar = styled.div`
|
const StyledSidebar = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -110,6 +108,8 @@ function getLayoutIcon(layout: CanvasDirection) {
|
|||||||
export const Sidebar: React.FC<{
|
export const Sidebar: React.FC<{
|
||||||
setJson: React.Dispatch<React.SetStateAction<string>>;
|
setJson: React.Dispatch<React.SetStateAction<string>>;
|
||||||
}> = ({ setJson }) => {
|
}> = ({ setJson }) => {
|
||||||
|
const pageLoaded = useLoading();
|
||||||
|
|
||||||
const [jsonFile, setJsonFile] = React.useState<File | null>(null);
|
const [jsonFile, setJsonFile] = React.useState<File | null>(null);
|
||||||
const [config, setConfig] = useLocalStorage<StorageConfig>("config", {
|
const [config, setConfig] = useLocalStorage<StorageConfig>("config", {
|
||||||
layout: "LEFT",
|
layout: "LEFT",
|
||||||
@ -117,7 +117,6 @@ export const Sidebar: React.FC<{
|
|||||||
controls: true,
|
controls: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
if (e.target.files) setJsonFile(e.target.files?.item(0));
|
if (e.target.files) setJsonFile(e.target.files?.item(0));
|
||||||
};
|
};
|
||||||
@ -140,89 +139,92 @@ export const Sidebar: React.FC<{
|
|||||||
}
|
}
|
||||||
}, [jsonFile, setJson]);
|
}, [jsonFile, setJson]);
|
||||||
|
|
||||||
return (
|
if (pageLoaded)
|
||||||
<StyledSidebar>
|
return (
|
||||||
<StyledTopWrapper>
|
<StyledSidebar>
|
||||||
<Link passHref href="/">
|
<StyledTopWrapper>
|
||||||
<StyledElement as="a">
|
<Link passHref href="/">
|
||||||
<StyledLogo>
|
<StyledElement as="a">
|
||||||
<StyledText>J</StyledText>
|
<StyledLogo>
|
||||||
<StyledText secondary>V</StyledText>
|
<StyledText>J</StyledText>
|
||||||
</StyledLogo>
|
<StyledText secondary>V</StyledText>
|
||||||
|
</StyledLogo>
|
||||||
|
</StyledElement>
|
||||||
|
</Link>
|
||||||
|
<StyledElement title="Home">
|
||||||
|
<Link href="/">
|
||||||
|
<a>
|
||||||
|
<AiFillHome />
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
</StyledElement>
|
||||||
|
<StyledElement
|
||||||
|
as="a"
|
||||||
|
onClick={() => {
|
||||||
|
setJson("[]");
|
||||||
|
localStorage.removeItem("json");
|
||||||
|
}}
|
||||||
|
title="Clear JSON"
|
||||||
|
>
|
||||||
|
<AiOutlineClear />
|
||||||
|
</StyledElement>
|
||||||
|
<StyledElement
|
||||||
|
as="a"
|
||||||
|
onClick={() =>
|
||||||
|
setConfig((c) => ({
|
||||||
|
...c,
|
||||||
|
layout: getNextLayout(c.layout),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
title="Change Layout"
|
||||||
|
>
|
||||||
|
{getLayoutIcon(config.layout)}
|
||||||
|
</StyledElement>
|
||||||
|
<StyledElement
|
||||||
|
title="Toggle Controls"
|
||||||
|
as="a"
|
||||||
|
onClick={() => toggle("controls")}
|
||||||
|
>
|
||||||
|
{config.controls ? <AiFillControl /> : <AiOutlineControl />}
|
||||||
</StyledElement>
|
</StyledElement>
|
||||||
</Link>
|
|
||||||
<StyledElement title="Home">
|
|
||||||
<Link href="/">
|
|
||||||
<a>
|
|
||||||
<AiFillHome />
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
</StyledElement>
|
|
||||||
<StyledElement
|
|
||||||
as="a"
|
|
||||||
onClick={() => {
|
|
||||||
setJson("[]");
|
|
||||||
localStorage.removeItem("json");
|
|
||||||
}}
|
|
||||||
title="Clear JSON"
|
|
||||||
>
|
|
||||||
<AiOutlineClear />
|
|
||||||
</StyledElement>
|
|
||||||
<StyledElement
|
|
||||||
as="a"
|
|
||||||
onClick={() =>
|
|
||||||
setConfig((c) => ({
|
|
||||||
...c,
|
|
||||||
layout: getNextLayout(c.layout),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
title="Change Layout"
|
|
||||||
>
|
|
||||||
{getLayoutIcon(config.layout)}
|
|
||||||
</StyledElement>
|
|
||||||
<StyledElement
|
|
||||||
title="Toggle Controls"
|
|
||||||
as="a"
|
|
||||||
onClick={() => toggle("controls")}
|
|
||||||
>
|
|
||||||
{config.controls ? <AiFillControl /> : <AiOutlineControl />}
|
|
||||||
</StyledElement>
|
|
||||||
|
|
||||||
<StyledElement
|
<StyledElement
|
||||||
as="a"
|
as="a"
|
||||||
title="Toggle Expand/Collapse"
|
title="Toggle Expand/Collapse"
|
||||||
onClick={() => toggle("expand")}
|
onClick={() => toggle("expand")}
|
||||||
>
|
>
|
||||||
{config.expand ? <MdUnfoldMore /> : <MdUnfoldLess />}
|
{config.expand ? <MdUnfoldMore /> : <MdUnfoldLess />}
|
||||||
</StyledElement>
|
</StyledElement>
|
||||||
<StyledElement as="a" title="Import JSON File">
|
<StyledElement as="a" title="Import JSON File">
|
||||||
<StyledImportFile>
|
<StyledImportFile>
|
||||||
<input
|
<input
|
||||||
key={jsonFile?.name}
|
key={jsonFile?.name}
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
type="file"
|
type="file"
|
||||||
accept="application/JSON"
|
accept="application/JSON"
|
||||||
/>
|
/>
|
||||||
<FaFileImport />
|
<FaFileImport />
|
||||||
</StyledImportFile>
|
</StyledImportFile>
|
||||||
</StyledElement>
|
</StyledElement>
|
||||||
</StyledTopWrapper>
|
</StyledTopWrapper>
|
||||||
<StyledBottomWrapper>
|
<StyledBottomWrapper>
|
||||||
<StyledElement>
|
<StyledElement>
|
||||||
<Link href="https://twitter.com/aykutsarach">
|
<Link href="https://twitter.com/aykutsarach">
|
||||||
<a rel="me" target="_blank">
|
<a rel="me" target="_blank">
|
||||||
<AiOutlineTwitter />
|
<AiOutlineTwitter />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</StyledElement>
|
</StyledElement>
|
||||||
<StyledElement>
|
<StyledElement>
|
||||||
<Link href="https://github.com/AykutSarac/jsonvisio.com">
|
<Link href="https://github.com/AykutSarac/jsonvisio.com">
|
||||||
<a rel="me" target="_blank">
|
<a rel="me" target="_blank">
|
||||||
<AiFillGithub />
|
<AiFillGithub />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</StyledElement>
|
</StyledElement>
|
||||||
</StyledBottomWrapper>
|
</StyledBottomWrapper>
|
||||||
</StyledSidebar>
|
</StyledSidebar>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
AiOutlineFullscreen,
|
AiOutlineFullscreen,
|
||||||
AiFillSave,
|
AiFillSave,
|
||||||
} from "react-icons/ai";
|
} from "react-icons/ai";
|
||||||
|
import { useLoading } from "src/hooks/useLoading";
|
||||||
|
|
||||||
const StyledLiveEditor = styled.div`
|
const StyledLiveEditor = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -47,6 +48,8 @@ export const LiveEditor: React.FC<{
|
|||||||
json: string;
|
json: string;
|
||||||
setJson: React.Dispatch<React.SetStateAction<string>>;
|
setJson: React.Dispatch<React.SetStateAction<string>>;
|
||||||
}> = ({ json }) => {
|
}> = ({ json }) => {
|
||||||
|
const pageLoaded = useLoading();
|
||||||
|
|
||||||
const canvasRef = React.useRef<CanvasRef | null>(null);
|
const canvasRef = React.useRef<CanvasRef | null>(null);
|
||||||
const wrapperRef = React.useRef<ReactZoomPanPinchRef | null>(null);
|
const wrapperRef = React.useRef<ReactZoomPanPinchRef | null>(null);
|
||||||
const [config] = useLocalStorage<StorageConfig>("config", {
|
const [config] = useLocalStorage<StorageConfig>("config", {
|
||||||
@ -87,55 +90,58 @@ export const LiveEditor: React.FC<{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
if (pageLoaded)
|
||||||
<StyledLiveEditor>
|
return (
|
||||||
<StyledEditorWrapper>
|
<StyledLiveEditor>
|
||||||
<TransformWrapper
|
<StyledEditorWrapper>
|
||||||
maxScale={2}
|
<TransformWrapper
|
||||||
minScale={0.4}
|
maxScale={2}
|
||||||
initialScale={0.8}
|
minScale={0.4}
|
||||||
ref={wrapperRef}
|
initialScale={0.8}
|
||||||
limitToBounds={false}
|
ref={wrapperRef}
|
||||||
wheel={{
|
limitToBounds={false}
|
||||||
step: 0.4,
|
wheel={{
|
||||||
}}
|
step: 0.4,
|
||||||
>
|
}}
|
||||||
<TransformComponent>
|
>
|
||||||
<Canvas
|
<TransformComponent>
|
||||||
ref={canvasRef}
|
<Canvas
|
||||||
nodes={nodes}
|
ref={canvasRef}
|
||||||
edges={edges}
|
nodes={nodes}
|
||||||
layoutOptions={{
|
edges={edges}
|
||||||
"elk.direction": config.layout,
|
layoutOptions={{
|
||||||
}}
|
"elk.direction": config.layout,
|
||||||
maxWidth={20000}
|
}}
|
||||||
maxHeight={20000}
|
maxWidth={20000}
|
||||||
center={false}
|
maxHeight={20000}
|
||||||
zoomable={false}
|
center={false}
|
||||||
fit
|
zoomable={false}
|
||||||
readonly
|
fit
|
||||||
animated
|
readonly
|
||||||
node={CustomNode}
|
animated
|
||||||
/>
|
node={CustomNode}
|
||||||
</TransformComponent>
|
/>
|
||||||
</TransformWrapper>
|
</TransformComponent>
|
||||||
</StyledEditorWrapper>
|
</TransformWrapper>
|
||||||
{config.controls && (
|
</StyledEditorWrapper>
|
||||||
<StyledControls>
|
{config.controls && (
|
||||||
<Button onClick={() => zoomIn(0.5)}>
|
<StyledControls>
|
||||||
<AiOutlineZoomIn size={24} />
|
<Button onClick={() => zoomIn(0.5)}>
|
||||||
</Button>
|
<AiOutlineZoomIn size={24} />
|
||||||
<Button onClick={() => zoomOut(0.4)}>
|
</Button>
|
||||||
<AiOutlineZoomOut size={24} />
|
<Button onClick={() => zoomOut(0.4)}>
|
||||||
</Button>
|
<AiOutlineZoomOut size={24} />
|
||||||
<Button onClick={() => wrapperRef.current?.resetTransform()}>
|
</Button>
|
||||||
<AiOutlineFullscreen size={24} />
|
<Button onClick={() => wrapperRef.current?.resetTransform()}>
|
||||||
</Button>
|
<AiOutlineFullscreen size={24} />
|
||||||
<Button onClick={() => localStorage.setItem("json", json)}>
|
</Button>
|
||||||
<AiFillSave size={24} />
|
<Button onClick={() => localStorage.setItem("json", json)}>
|
||||||
</Button>
|
<AiFillSave size={24} />
|
||||||
</StyledControls>
|
</Button>
|
||||||
)}
|
</StyledControls>
|
||||||
</StyledLiveEditor>
|
)}
|
||||||
);
|
</StyledLiveEditor>
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,6 @@ import { useLoading } from "src/hooks/useLoading";
|
|||||||
|
|
||||||
function AykutSarac({ Component, pageProps }: AppProps) {
|
function AykutSarac({ Component, pageProps }: AppProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const data = useLoading();
|
|
||||||
|
|
||||||
const [pageLoading, setPageLoading] = React.useState<boolean>(false);
|
const [pageLoading, setPageLoading] = React.useState<boolean>(false);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -38,8 +37,6 @@ function AykutSarac({ Component, pageProps }: AppProps) {
|
|||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!data) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={darkTheme}>
|
<ThemeProvider theme={darkTheme}>
|
||||||
<GlobalStyle />
|
<GlobalStyle />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user