mirror of
https://github.com/AykutSarac/jsoncrack.com.git
synced 2025-01-27 15:22:56 +08:00
refactor codebase
This commit is contained in:
parent
b4e2fcabf6
commit
900e6897b9
@ -1,5 +1,4 @@
|
||||
NEXT_PUBLIC_BASE_URL=http://localhost:3000
|
||||
NEXT_PUBLIC_PAYMENT_URL=https://herowand.lemonsqueezy.com/checkout/buy/ce30521f-c7cc-44f3-9435-995d3260ba22
|
||||
NEXT_PUBLIC_GA_ID=G-JKZEHMJBMH
|
||||
NEXT_PUBLIC_PAYMENT_URL=https://herowand.lemonsqueezy.com/checkout/buy/ce30521f-c7cc-44f3-9435-995d3260ba22
|
||||
NEXT_PUBLIC_SUPABASE_URL=https://bxkgqurwqjmvrqekcbws.supabase.co
|
||||
NEXT_PUBLIC_SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ4a2dxdXJ3cWptdnJxZWtjYndzIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTA2NDU0MjUsImV4cCI6MjAwNjIyMTQyNX0.3nZ0yhuFjnI3yHbAL8S9UtK-Ny-6F5AylNHgo1tymTU
|
@ -1,5 +0,0 @@
|
||||
NEXT_PUBLIC_BASE_URL=https://jsoncrack.com
|
||||
NEXT_PUBLIC_PAYMENT_URL=https://herowand.lemonsqueezy.com/checkout/buy/ce30521f-c7cc-44f3-9435-995d3260ba22
|
||||
NEXT_PUBLIC_GA_ID=G-JKZEHMJBMH
|
||||
NEXT_PUBLIC_SUPABASE_URL=https://bxkgqurwqjmvrqekcbws.supabase.co
|
||||
NEXT_PUBLIC_SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ4a2dxdXJ3cWptdnJxZWtjYndzIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTA2NDU0MjUsImV4cCI6MjAwNjIyMTQyNX0.3nZ0yhuFjnI3yHbAL8S9UtK-Ny-6F5AylNHgo1tymTU
|
@ -1,80 +0,0 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
const StyledInputWrapper = styled.div`
|
||||
background: ${({ theme }) => theme.BACKGROUND_TERTIARY};
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
`;
|
||||
|
||||
const StyledForm = styled.div`
|
||||
display: flex;
|
||||
|
||||
flex: 1;
|
||||
`;
|
||||
|
||||
const StyledInput = styled.input`
|
||||
background: ${({ theme }) => theme.BACKGROUND_TERTIARY};
|
||||
color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
|
||||
outline: none;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
line-height: 32px;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
`;
|
||||
|
||||
const StyledButton = styled.button`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: none;
|
||||
color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
|
||||
padding: 0 10px;
|
||||
min-height: unset;
|
||||
text-transform: uppercase;
|
||||
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: ${({ theme }) => theme.PRIMARY};
|
||||
color: white;
|
||||
outline: 3px solid ${({ theme }) => theme.BACKGROUND_TERTIARY};
|
||||
border-radius: 10px;
|
||||
}
|
||||
`;
|
||||
|
||||
export interface InputProps {
|
||||
value: string | number | string[];
|
||||
extensions: string[];
|
||||
activeExtension: number;
|
||||
onChange?: React.ChangeEventHandler<HTMLInputElement>;
|
||||
setExtension: (value: number) => void;
|
||||
}
|
||||
export const FileInput: React.FC<InputProps> = ({
|
||||
setExtension,
|
||||
activeExtension,
|
||||
onChange,
|
||||
extensions,
|
||||
value,
|
||||
}) => {
|
||||
return (
|
||||
<StyledInputWrapper>
|
||||
<StyledForm>
|
||||
<StyledInput type="text" onChange={onChange} value={value} placeholder="File Name" />
|
||||
{extensions.map((ext, key) => (
|
||||
<StyledButton
|
||||
className={`${activeExtension === key && "active"}`}
|
||||
key={key}
|
||||
aria-label="search"
|
||||
onClick={() => setExtension(key)}
|
||||
>
|
||||
{ext}
|
||||
</StyledButton>
|
||||
))}
|
||||
</StyledForm>
|
||||
</StyledInputWrapper>
|
||||
);
|
||||
};
|
@ -1,5 +1,3 @@
|
||||
export const baseURL = process.env.NEXT_PUBLIC_BASE_URL as string;
|
||||
|
||||
// Example taken from https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json
|
||||
const sampleJson = Object.freeze({
|
||||
squadName: "Super hero squad",
|
||||
|
@ -208,11 +208,7 @@ export const BottomBar = () => {
|
||||
</Text>
|
||||
</Flex>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown
|
||||
style={{
|
||||
pointerEvents: "none",
|
||||
}}
|
||||
>
|
||||
<Popover.Dropdown style={{ pointerEvents: "none" }}>
|
||||
<Text size="xs">{error}</Text>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
|
@ -1,20 +0,0 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { MonacoEditor } from "src/components/MonacoEditor";
|
||||
|
||||
const StyledEditorWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
export const JsonEditor: React.FC = () => {
|
||||
return (
|
||||
<StyledEditorWrapper>
|
||||
<MonacoEditor />
|
||||
</StyledEditorWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default JsonEditor;
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import type { CustomNodeProps } from "src/containers/Views/GraphView/CustomNode";
|
||||
import type { CustomNodeProps } from "src/containers/Editor/LiveEditor/GraphView/CustomNode";
|
||||
import { TextRenderer } from "./TextRenderer";
|
||||
import * as Styled from "./styles";
|
||||
|
||||
@ -25,7 +25,7 @@ const Row = ({ val, x, y, index }: RowProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Node: React.FC<CustomNodeProps> = ({ node, x, y }) => (
|
||||
const Node = ({ node, x, y }: CustomNodeProps) => (
|
||||
<Styled.StyledForeignObject width={node.width} height={node.height} x={0} y={0} $isObject>
|
||||
{(node.text as Value[]).map((val, idx) => (
|
||||
<Row val={val} index={idx} x={x} y={y} key={idx} />
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { MdLink, MdLinkOff } from "react-icons/md";
|
||||
import type { CustomNodeProps } from "src/containers/Views/GraphView/CustomNode";
|
||||
import type { CustomNodeProps } from "src/containers/Editor/LiveEditor/GraphView/CustomNode";
|
||||
import useToggleHide from "src/hooks/useToggleHide";
|
||||
import { isContentImage } from "src/lib/utils/graph/calculateNodeSize";
|
||||
import useConfig from "src/store/useConfig";
|
||||
@ -43,7 +43,7 @@ const StyledImage = styled.img`
|
||||
background: ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
|
||||
`;
|
||||
|
||||
const Node: React.FC<CustomNodeProps> = ({ node, x, y, hasCollapse = false }) => {
|
||||
const Node = ({ node, x, y, hasCollapse = false }: CustomNodeProps) => {
|
||||
const {
|
||||
id,
|
||||
text,
|
@ -11,20 +11,14 @@ const StyledRow = styled.span`
|
||||
vertical-align: middle;
|
||||
`;
|
||||
|
||||
function isColorFormat(colorString: string) {
|
||||
const hexCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
|
||||
const rgbRegex = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/;
|
||||
const rgbaRegex = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(0|1|0\.\d+)\s*\)$/;
|
||||
|
||||
return (
|
||||
hexCodeRegex.test(colorString) || rgbRegex.test(colorString) || rgbaRegex.test(colorString)
|
||||
);
|
||||
}
|
||||
|
||||
const isURL =
|
||||
/(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi;
|
||||
|
||||
export const TextRenderer: React.FC<{ children: string }> = ({ children }) => {
|
||||
interface TextRendererProps {
|
||||
children: string;
|
||||
}
|
||||
|
||||
export const TextRenderer = ({ children }: TextRendererProps) => {
|
||||
if (isURL.test(children?.replaceAll('"', ""))) {
|
||||
return <Styled.StyledLinkItUrl>{children}</Styled.StyledLinkItUrl>;
|
||||
}
|
||||
@ -39,3 +33,13 @@ export const TextRenderer: React.FC<{ children: string }> = ({ children }) => {
|
||||
}
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
function isColorFormat(colorString: string) {
|
||||
const hexCodeRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
|
||||
const rgbRegex = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/;
|
||||
const rgbaRegex = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(0|1|0\.\d+)\s*\)$/;
|
||||
|
||||
return (
|
||||
hexCodeRegex.test(colorString) || rgbRegex.test(colorString) || rgbaRegex.test(colorString)
|
||||
);
|
||||
}
|
@ -6,17 +6,13 @@ import { Space } from "react-zoomable-ui";
|
||||
import { Canvas } from "reaflow";
|
||||
import type { ElkRoot } from "reaflow/dist/layout/useLayout";
|
||||
import { useLongPress } from "use-long-press";
|
||||
import { CustomNode } from "src/containers/Views/GraphView/CustomNode";
|
||||
import { CustomNode } from "src/containers/Editor/LiveEditor/GraphView/CustomNode";
|
||||
import useToggleHide from "src/hooks/useToggleHide";
|
||||
import useConfig from "src/store/useConfig";
|
||||
import useGraph from "src/store/useGraph";
|
||||
import { CustomEdge } from "./CustomEdge";
|
||||
import { NotSupported } from "./NotSupported";
|
||||
|
||||
interface GraphProps {
|
||||
isWidget?: boolean;
|
||||
}
|
||||
|
||||
const StyledEditorWrapper = styled.div<{ $widget: boolean; $showRulers: boolean }>`
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
@ -77,6 +73,10 @@ const layoutOptions = {
|
||||
"elk.layered.nodePlacement.strategy": "NETWORK_SIMPLEX",
|
||||
};
|
||||
|
||||
interface GraphProps {
|
||||
isWidget?: boolean;
|
||||
}
|
||||
|
||||
const GraphCanvas = ({ isWidget }: GraphProps) => {
|
||||
const { validateHiddenNodes } = useToggleHide();
|
||||
const setLoading = useGraph(state => state.setLoading);
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import type { DefaultTheme } from "styled-components";
|
||||
import { useTheme } from "styled-components";
|
||||
import { TextRenderer } from "src/containers/Views/GraphView/CustomNode/TextRenderer";
|
||||
import { TextRenderer } from "src/containers/Editor/LiveEditor/GraphView/CustomNode/TextRenderer";
|
||||
|
||||
type TextColorFn = {
|
||||
theme: DefaultTheme;
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { Graph } from "src/containers/Views/GraphView";
|
||||
import { TreeView } from "src/containers/Views/TreeView";
|
||||
import { Graph } from "src/containers/Editor/LiveEditor/GraphView";
|
||||
import { TreeView } from "src/containers/Editor/LiveEditor/TreeView";
|
||||
import { ViewMode } from "src/enums/viewMode.enum";
|
||||
import useConfig from "src/store/useConfig";
|
||||
|
||||
@ -29,7 +29,7 @@ const View = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const LiveEditor: React.FC = () => {
|
||||
const LiveEditor = () => {
|
||||
return (
|
||||
<StyledLiveEditor onContextMenuCapture={e => e.preventDefault()}>
|
||||
<View />
|
@ -19,14 +19,7 @@ const editorOptions = {
|
||||
},
|
||||
};
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
display: grid;
|
||||
height: calc(100vh - 67px);
|
||||
grid-template-columns: 100%;
|
||||
grid-template-rows: minmax(0, 1fr);
|
||||
`;
|
||||
|
||||
export const MonacoEditor = () => {
|
||||
const TextEditor = () => {
|
||||
const monaco = useMonaco();
|
||||
const contents = useFile(state => state.contents);
|
||||
const setContents = useFile(state => state.setContents);
|
||||
@ -72,17 +65,35 @@ export const MonacoEditor = () => {
|
||||
}, [getHasChanges]);
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<Editor
|
||||
height="100%"
|
||||
language={fileType}
|
||||
theme={theme}
|
||||
value={contents}
|
||||
options={editorOptions}
|
||||
onValidate={errors => setError(errors[0]?.message)}
|
||||
onChange={contents => setContents({ contents, skipUpdate: true })}
|
||||
loading={<LoadingOverlay visible />}
|
||||
/>
|
||||
</StyledWrapper>
|
||||
<StyledEditorWrapper>
|
||||
<StyledWrapper>
|
||||
<Editor
|
||||
height="100%"
|
||||
language={fileType}
|
||||
theme={theme}
|
||||
value={contents}
|
||||
options={editorOptions}
|
||||
onValidate={errors => setError(errors[0]?.message)}
|
||||
onChange={contents => setContents({ contents, skipUpdate: true })}
|
||||
loading={<LoadingOverlay visible />}
|
||||
/>
|
||||
</StyledWrapper>
|
||||
</StyledEditorWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextEditor;
|
||||
|
||||
const StyledEditorWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
display: grid;
|
||||
height: calc(100vh - 67px);
|
||||
grid-template-columns: 100%;
|
||||
grid-template-rows: minmax(0, 1fr);
|
||||
`;
|
@ -16,7 +16,7 @@ export const StyledEditor = styled(Allotment)`
|
||||
}
|
||||
`;
|
||||
|
||||
const JsonEditor = dynamic(() => import("src/containers/Editor/JsonEditor"), {
|
||||
const TextEditor = dynamic(() => import("src/containers/Editor/TextEditor"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
@ -24,7 +24,7 @@ const LiveEditor = dynamic(() => import("src/containers/Editor/LiveEditor"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const Panes: React.FC = () => {
|
||||
export const Editor = () => {
|
||||
const fullscreen = useGraph(state => state.fullscreen);
|
||||
|
||||
return (
|
||||
@ -35,7 +35,7 @@ const Panes: React.FC = () => {
|
||||
maxSize={800}
|
||||
visible={!fullscreen}
|
||||
>
|
||||
<JsonEditor />
|
||||
<TextEditor />
|
||||
</Allotment.Pane>
|
||||
<Allotment.Pane minSize={0}>
|
||||
<LiveEditor />
|
||||
@ -43,5 +43,3 @@ const Panes: React.FC = () => {
|
||||
</StyledEditor>
|
||||
);
|
||||
};
|
||||
|
||||
export default Panes;
|
@ -6,7 +6,7 @@ import { gaEvent } from "src/lib/utils/gaEvent";
|
||||
import useModal from "src/store/useModal";
|
||||
import useUser from "src/store/useUser";
|
||||
|
||||
export const AccountModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const AccountModal = ({ opened, onClose }: ModalProps) => {
|
||||
const user = useUser(state => state.user);
|
||||
const setVisible = useModal(state => state.setVisible);
|
||||
const logout = useUser(state => state.logout);
|
||||
|
@ -5,7 +5,7 @@ import { Modal, Group, Button, Text, Divider } from "@mantine/core";
|
||||
import { documentSvc } from "src/services/document.service";
|
||||
import useJson from "src/store/useJson";
|
||||
|
||||
export const ClearModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const ClearModal = ({ opened, onClose }: ModalProps) => {
|
||||
const setJson = useJson(state => state.setJson);
|
||||
const { query, replace } = useRouter();
|
||||
|
||||
|
@ -44,11 +44,13 @@ const colorByFormat: Record<FileFormat, DefaultMantineColor> = {
|
||||
csv: "grape",
|
||||
};
|
||||
|
||||
const UpdateNameModal: React.FC<{
|
||||
interface UpdateNameModalProps {
|
||||
file: File | null;
|
||||
onClose: () => void;
|
||||
refetch: () => void;
|
||||
}> = ({ file, onClose, refetch }) => {
|
||||
}
|
||||
|
||||
const UpdateNameModal = ({ file, onClose, refetch }: UpdateNameModalProps) => {
|
||||
const [name, setName] = React.useState("");
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -95,7 +97,7 @@ const UpdateNameModal: React.FC<{
|
||||
|
||||
const TOTAL_QUOTA = 25;
|
||||
|
||||
export const CloudModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const CloudModal = ({ opened, onClose }: ModalProps) => {
|
||||
const setFile = useFile(state => state.setFile);
|
||||
const [currentFile, setCurrentFile] = React.useState<File | null>(null);
|
||||
const [searchValue, setSearchValue] = React.useState("");
|
||||
|
@ -62,7 +62,7 @@ function downloadURI(uri: string, name: string) {
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
export const DownloadModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const DownloadModal = ({ opened, onClose }: ModalProps) => {
|
||||
const [extension, setExtension] = React.useState(Extensions.PNG);
|
||||
const [fileDetails, setFileDetails] = React.useState({
|
||||
filename: "jsoncrack.com",
|
||||
|
@ -8,7 +8,7 @@ import type { FileFormat } from "src/enums/file.enum";
|
||||
import { gaEvent } from "src/lib/utils/gaEvent";
|
||||
import useFile from "src/store/useFile";
|
||||
|
||||
export const ImportModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const ImportModal = ({ opened, onClose }: ModalProps) => {
|
||||
const [url, setURL] = React.useState("");
|
||||
const [file, setFile] = React.useState<File | null>(null);
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { Stack, Modal, Button, Text, Anchor, Group, TextInput, Divider } from "@
|
||||
import { VscLinkExternal } from "react-icons/vsc";
|
||||
import useJsonQuery from "src/hooks/useJsonQuery";
|
||||
|
||||
export const JQModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const JQModal = ({ opened, onClose }: ModalProps) => {
|
||||
const { updateJson } = useJsonQuery();
|
||||
const [query, setQuery] = React.useState("");
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { decode } from "jsonwebtoken";
|
||||
import { gaEvent } from "src/lib/utils/gaEvent";
|
||||
import useFile from "src/store/useFile";
|
||||
|
||||
export const JWTModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const JWTModal = ({ opened, onClose }: ModalProps) => {
|
||||
const setContents = useFile(state => state.setContents);
|
||||
const [token, setToken] = React.useState("");
|
||||
|
||||
|
@ -2,7 +2,7 @@ import React from "react";
|
||||
import type { ModalProps } from "@mantine/core";
|
||||
import { Modal, Stack, Button, Text } from "@mantine/core";
|
||||
|
||||
export const LoginModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const LoginModal = ({ opened, onClose }: ModalProps) => {
|
||||
return (
|
||||
<Modal title="Sign In" opened={opened} onClose={onClose} centered>
|
||||
<Stack py="sm">
|
||||
|
@ -17,7 +17,7 @@ const dataToString = (data: any) => {
|
||||
return JSON.stringify(text, replacer, 2);
|
||||
};
|
||||
|
||||
export const NodeModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const NodeModal = ({ opened, onClose }: ModalProps) => {
|
||||
const setVisible = useModal(state => state.setVisible);
|
||||
const nodeData = useGraph(state => dataToString(state.selectedNode?.text));
|
||||
const path = useGraph(state => state.selectedNode?.path || "");
|
||||
|
@ -4,7 +4,7 @@ import { Button, Modal, Rating, Text, Textarea } from "@mantine/core";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { supabase } from "src/lib/api/supabase";
|
||||
|
||||
export const ReviewModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const ReviewModal = ({ opened, onClose }: ModalProps) => {
|
||||
const [stars, setStars] = React.useState(0);
|
||||
const [review, setReview] = React.useState("");
|
||||
|
||||
|
@ -8,7 +8,7 @@ import { gaEvent } from "src/lib/utils/gaEvent";
|
||||
import useConfig from "src/store/useConfig";
|
||||
import useFile from "src/store/useFile";
|
||||
|
||||
export const SchemaModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const SchemaModal = ({ opened, onClose }: ModalProps) => {
|
||||
const setJsonSchema = useFile(state => state.setJsonSchema);
|
||||
const [schema, setSchema] = React.useState(
|
||||
JSON.stringify(
|
||||
|
@ -15,7 +15,7 @@ import { FiExternalLink } from "react-icons/fi";
|
||||
import { MdCheck, MdCopyAll } from "react-icons/md";
|
||||
import { gaEvent } from "src/lib/utils/gaEvent";
|
||||
|
||||
export const ShareModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const ShareModal = ({ opened, onClose }: ModalProps) => {
|
||||
const { query } = useRouter();
|
||||
const shareURL = `https://jsoncrack.com/editor?json=${query.json}`;
|
||||
|
||||
|
@ -47,7 +47,7 @@ const typeOptions = [
|
||||
},
|
||||
];
|
||||
|
||||
export const TypeModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const TypeModal = ({ opened, onClose }: ModalProps) => {
|
||||
const getJson = useJson(state => state.getJson);
|
||||
const [type, setType] = React.useState("");
|
||||
const [selectedType, setSelectedType] = React.useState<Language>(Language.TypeScript);
|
||||
|
@ -24,7 +24,7 @@ const overlayLinks = {
|
||||
"https://herowand.lemonsqueezy.com/buy/577928ea-fb09-4076-9307-3e5931b35ad0?embed=1&media=0&logo=0&desc=0&discount=0&enabled=82417",
|
||||
};
|
||||
|
||||
export const UpgradeModal: React.FC<ModalProps> = ({ opened, onClose }) => {
|
||||
export const UpgradeModal = ({ opened, onClose }: ModalProps) => {
|
||||
const [plan, setPlan] = React.useState<string>("annual");
|
||||
const user = useUser(state => state.user);
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { getHotkeyHandler } from "@mantine/hooks";
|
||||
import { AiOutlineSearch } from "react-icons/ai";
|
||||
import { useFocusNode } from "src/hooks/useFocusNode";
|
||||
|
||||
export const SearchInput: React.FC = () => {
|
||||
export const SearchInput = () => {
|
||||
const [searchValue, setValue, skip, nodeCount, currentNode] = useFocusNode();
|
||||
|
||||
return (
|
@ -5,7 +5,7 @@ import toast from "react-hot-toast";
|
||||
import { AiOutlineFullscreen } from "react-icons/ai";
|
||||
import { AiFillGift } from "react-icons/ai";
|
||||
import { FiDownload } from "react-icons/fi";
|
||||
import { SearchInput } from "src/components/SearchInput";
|
||||
import { SearchInput } from "src/containers/Toolbar/SearchInput";
|
||||
import { FileFormat } from "src/enums/file.enum";
|
||||
import { JSONCrackLogo } from "src/layout/JsonCrackLogo";
|
||||
import { gaEvent } from "src/lib/utils/gaEvent";
|
||||
@ -30,7 +30,11 @@ function fullscreenBrowser() {
|
||||
}
|
||||
}
|
||||
|
||||
export const Toolbar: React.FC<{ isWidget?: boolean }> = ({ isWidget = false }) => {
|
||||
interface ToolbarProps {
|
||||
isWidget?: boolean;
|
||||
}
|
||||
|
||||
export const Toolbar = ({ isWidget = false }: ToolbarProps) => {
|
||||
const setVisible = useModal(state => state.setVisible);
|
||||
const setFormat = useFile(state => state.setFormat);
|
||||
const format = useFile(state => state.format);
|
||||
|
@ -19,7 +19,7 @@ interface LogoProps extends React.ComponentPropsWithoutRef<"a"> {
|
||||
fontSize?: string;
|
||||
}
|
||||
|
||||
export const JSONCrackLogo: React.FC<LogoProps> = ({ fontSize = "1.2rem", ...props }) => {
|
||||
export const JSONCrackLogo = ({ fontSize = "1.2rem", ...props }: LogoProps) => {
|
||||
const logoText = React.useMemo(() => {
|
||||
if (typeof window === "undefined") return "JSON CRACK";
|
||||
return isIframe() ? "JC" : "JSON CRACK";
|
||||
|
@ -8,7 +8,7 @@ const StyledLayoutWrapper = styled.div`
|
||||
padding-bottom: 48px;
|
||||
`;
|
||||
|
||||
const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const Layout = ({ children }: React.PropsWithChildren) => {
|
||||
return (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<StyledLayoutWrapper>
|
||||
|
@ -8,9 +8,9 @@ import "@mantine/core/styles.css";
|
||||
import "@mantine/code-highlight/styles.css";
|
||||
import { ThemeProvider } from "styled-components";
|
||||
import ReactGA from "react-ga4";
|
||||
import { Loading } from "src/components/Loading";
|
||||
import GlobalStyle from "src/constants/globalStyle";
|
||||
import { lightTheme } from "src/constants/theme";
|
||||
import { Loading } from "src/layout/Loading";
|
||||
import { supabase } from "src/lib/api/supabase";
|
||||
import useUser from "src/store/useUser";
|
||||
|
||||
|
@ -6,8 +6,8 @@ import { useMantineColorScheme } from "@mantine/core";
|
||||
import styled, { ThemeProvider } from "styled-components";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { darkTheme, lightTheme } from "src/constants/theme";
|
||||
import { Editor } from "src/containers/Editor";
|
||||
import { BottomBar } from "src/containers/Editor/BottomBar";
|
||||
import Panes from "src/containers/Editor/Panes";
|
||||
import { Toolbar } from "src/containers/Toolbar";
|
||||
import useConfig from "src/store/useConfig";
|
||||
import useFile from "src/store/useFile";
|
||||
@ -39,7 +39,7 @@ export const StyledEditorWrapper = styled.div`
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const EditorPage: React.FC = () => {
|
||||
const EditorPage = () => {
|
||||
const { query, isReady } = useRouter();
|
||||
const { setColorScheme } = useMantineColorScheme();
|
||||
const checkEditorSession = useFile(state => state.checkEditorSession);
|
||||
@ -67,7 +67,7 @@ const EditorPage: React.FC = () => {
|
||||
<StyledPageWrapper>
|
||||
<Toolbar />
|
||||
<StyledEditorWrapper>
|
||||
<Panes />
|
||||
<Editor />
|
||||
</StyledEditorWrapper>
|
||||
</StyledPageWrapper>
|
||||
<BottomBar />
|
||||
|
@ -20,7 +20,7 @@ interface EmbedMessage {
|
||||
};
|
||||
}
|
||||
|
||||
const Graph = dynamic(() => import("src/containers/Views/GraphView").then(c => c.Graph), {
|
||||
const Graph = dynamic(() => import("src/containers/Editor/LiveEditor/GraphView").then(c => c.Graph), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user