feature/random-nik-things

This commit is contained in:
Nikolaj Frey 2024-07-16 17:11:03 +08:00
parent e77fe17675
commit 990cd108bd
10 changed files with 403 additions and 120 deletions

2
.gitignore vendored
View File

@ -3,6 +3,8 @@
.env .env
app/node_modules app/node_modules
remix/node_modules
next/node_modules
app-next/node_modules app-next/node_modules
api/node_modules api/node_modules
node_modules node_modules

View File

@ -93,7 +93,6 @@
"title": "Commander", "title": "Commander",
"description": "Open Thingtime Commander", "description": "Open Thingtime Commander",
"mode": "view", "mode": "view",
"fallbackText": "test2",
"keywords": [ "keywords": [
"commander", "commander",
"thingtime", "thingtime",
@ -107,7 +106,38 @@
"key": "name", "key": "name",
"title": "Name of Command to run", "title": "Name of Command to run",
"description": "The name of the command/function to run", "description": "The name of the command/function to run",
"defaultValue": "Menu" "defaultValue": "MagicInput"
}
]
},
{
"name": "commanderMagicInput",
"title": "Magic Input",
"description": "Evaluates a Magic Input",
"mode": "no-view",
"keywords": [
"commander",
"thingtime",
"ai"
],
"arguments": [
{
"placeholder": "Path",
"name": "path",
"type": "text",
"description": "The path to open the new finder window at",
"required": false
}
],
"preferences": [
{
"name": "name",
"required": false,
"type": "textfield",
"key": "name",
"title": "Name of Command to run",
"description": "The name of the command/function to run",
"defaultValue": "openNewFinderWindow"
} }
] ]
}, },
@ -116,7 +146,6 @@
"title": "Open New Finder Window", "title": "Open New Finder Window",
"description": "Open new finder window", "description": "Open new finder window",
"mode": "no-view", "mode": "no-view",
"fallbackText": "test2",
"keywords": [ "keywords": [
"commander", "commander",
"thingtime", "thingtime",
@ -148,7 +177,6 @@
"title": "Trim image", "title": "Trim image",
"description": "Will trim all whitespace from an image", "description": "Will trim all whitespace from an image",
"mode": "no-view", "mode": "no-view",
"fallbackText": "test2",
"keywords": [ "keywords": [
"commander", "commander",
"thingtime", "thingtime",
@ -171,7 +199,6 @@
"title": "mp4 to mp3", "title": "mp4 to mp3",
"description": "Converts an mp4 into an mp3 using ffmpeg at 320Kbps", "description": "Converts an mp4 into an mp3 using ffmpeg at 320Kbps",
"mode": "no-view", "mode": "no-view",
"fallbackText": "test2",
"keywords": [ "keywords": [
"commander", "commander",
"thingtime", "thingtime",

View File

@ -0,0 +1,11 @@
import { Box, Heading } from '@chakra-ui/react';
import { Logo } from './Logo';
export const Branding = () => {
return (
<Box w="100%" px={'18px'} maxW={'container'} textAlign={'left'}>
<Heading>Branding</Heading>
<Logo />
</Box>
);
};

View File

@ -0,0 +1,87 @@
import { Box, Center, Flex, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from '@chakra-ui/react';
import React, { useMemo, useState } from 'react';
export const Logo = () => {
// a completely dynamic and interactive logo
// uses borders, border radius, and colour themes to create a simple timeless beautiful logo
// const defaultThemeRaw = ['white', '#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
const defaultThemeRaw = ['#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
const [reverseColours, setReverseColours] = useState(false);
const defaultTheme = reverseColours ? defaultThemeRaw?.reverse() : defaultThemeRaw;
const [theme, setTheme] = useState('blue');
const [squares, setSquares] = useState(9);
const [width, setWidth] = useState(250);
const [height, setHeight] = useState(250);
// logo is a T/plus shape made of two intersecting squares
// you can toggle border sides on both squares to create different shapes
const [borderWidth, setBorderWidth] = useState(18);
const [borderRadius, setBorderRadius] = useState(12);
const squaresArray = Array.from({ length: squares }, (_, index) => index);
const [spacing, setSpacing] = useState(borderWidth);
// log squaresArray
console.debug('tt.squaresArray', squaresArray);
// basically the 5 squares that make up a plus but with the centre one missing
const [divisions, setDivisions] = useState(3);
const [divisionHeight, setDivisionHeight] = useState(100 / divisions);
const [divisionWidth, setDivisionWidth] = useState(100 / divisions);
const uuid = useMemo(() => {
return Math.random().toString(36).substring(2) + Date.now().toString(36);
}, []);
return (
<>
{/* these are the controls */}
{/* border radius use chakra slider */}
<Center py={12}>
<Slider aria-label="slider-ex-1" defaultValue={borderRadius} onChange={setBorderRadius}>
<SliderTrack>
<SliderFilledTrack />
</SliderTrack>
<SliderThumb>🟡</SliderThumb>
</Slider>
</Center>
<Box className="tt.logo" overflow="hidden" w={width + 'px'} h={height + 'px'} position="relative">
{squaresArray.map((_, idx) => {
// technically not even in programming terms cause it starts at 0 😂
const humanIdx = idx + 1;
const even = humanIdx % 2 === 0;
const colourIndex = Math.round(idx / 2);
// log the colourIndex
console.debug('tt.colourIndex', colourIndex);
return (
<Box
display="inline-block"
key={`logo-${uuid}-${idx}`}
bg={even ? defaultTheme[colourIndex] : 'rgba(0,0,0,0)'}
w={`${divisionHeight}%`}
h={`${divisionWidth}%`}
></Box>
);
})}
</Box>
</>
);
};

View File

@ -0,0 +1,129 @@
import { Box, Center, Flex, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from '@chakra-ui/react';
import React, { useState } from 'react';
export const LogoOld2 = () => {
// a completely dynamic and interactive logo
// uses borders, border radius, and colour themes to create a simple timeless beautiful logo
// const defaultThemeRaw = ['white', '#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
const defaultThemeRaw = ['#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
const [reverseColours, setReverseColours] = useState(false);
const defaultTheme = reverseColours ? defaultThemeRaw?.reverse() : defaultThemeRaw;
const [theme, setTheme] = useState('blue');
const [squares, setSquares] = useState(8);
const [width, setWidth] = useState(50);
const [height, setHeight] = useState(50);
// logo is a T/plus shape made of two intersecting squares
// you can toggle border sides on both squares to create different shapes
const [borderWidth, setBorderWidth] = useState(18);
const [borderRadius, setBorderRadius] = useState(12);
const squaresArray = Array.from({ length: squares }, (_, index) => index);
const [spacing, setSpacing] = useState(borderWidth);
// log squaresArray
console.debug('tt.squaresArray', squaresArray);
return (
<>
{/* these are the controls */}
{/* border radius use chakra slider */}
<Center py={12}>
<Slider aria-label="slider-ex-1" defaultValue={borderRadius} onChange={setBorderRadius}>
<SliderTrack>
<SliderFilledTrack />
</SliderTrack>
<SliderThumb>🟡</SliderThumb>
</Slider>
</Center>
<Center overflow="hidden" w={width} h={height} position="relative">
{/* border top left squares */}
{squaresArray.map((_, index) => {
const top = index * spacing;
const left = index * spacing;
const colour = defaultTheme[index];
const square = (
<Box
zIndex={2}
backgroundColor={colour}
borderRadius={`${borderRadius}px`}
className="logo-square"
position={'absolute'}
width={width}
top={12}
left={12}
height={height}
transform={`translateY(${top}px) translateX(${left}px)`}
>
{/* another box which acts as a mask */}
{/* <Box
backgroundColor={theme}
borderRadius={`${borderRadius}px`}
className="logo-square"
position={'absolute'}
width={width}
top={12}
left={12}
height={height}
top={`${top}px`}
left={`${left}px`}
/> */}
</Box>
);
return square;
})}
{/* make squares for bottom right */}
{squaresArray.map((_, index) => {
const bottom = index * spacing + height * 2;
const right = index * spacing + width * 2;
const colour = defaultTheme[index];
const square = (
<Box
zIndex={1}
backgroundColor={colour}
borderRadius={`${borderRadius}px`}
className="logo-square"
position={'absolute'}
width={width}
top={14}
left={14}
height={height}
transform={`translateY(${-bottom}px) translateX(${-right}px)`}
>
{/* another box which acts as a mask */}
{/* <Box
backgroundColor={theme}
borderRadius={`${borderRadius}px`}
className="logo-square"
position={'absolute'}
width={width}
height={height}
top={`${top}px`}
left={`${left}px`}
/> */}
</Box>
);
return square;
})}
</Center>
</>
);
};

View File

@ -8,8 +8,8 @@ export const Editor = (props) => {
return ( return (
<> <>
<Box minH="60vh" w="100%" maxW={'container'} pos={'relative'}> <Box minH="60vh" w="100%" maxW={'container'} pos={'relative'}>
{/* only on client side render editor */}
<Flex position="absolute" w={width} h={height} top={0} left={0} right={0} bottom={0}> <Flex position="absolute" w={width} h={height} top={0} left={0} right={0} bottom={0}>
{/* only on client side render editor */}
<Suspense fallback={<div>Loading...</div>}> <Suspense fallback={<div>Loading...</div>}>
<MonacoEditor defaultLanguage={defaultLanguage} defaultValue={defaultValue} /> <MonacoEditor defaultLanguage={defaultLanguage} defaultValue={defaultValue} />
</Suspense> </Suspense>

View File

@ -136,11 +136,11 @@ export const Nav = (props) => {
</Center> </Center>
)} )}
{/* TODO - Add conditional only show if loggedIn */} {/* TODO - Add conditional only show if loggedIn */}
<Center transform={['', 'scaleX(-100%)']} cursor="pointer"> {/* <Center transform={['', 'scaleX(-100%)']} cursor="pointer">
<Link to="/logout"> <Link to="/logout">
<Icon size="12px" name="🗝️"></Icon> <Icon size="12px" name="🗝️"></Icon>
</Link> </Link>
</Center> </Center> */}
<Center transform={['', 'scaleX(-100%)']} cursor="pointer"> <Center transform={['', 'scaleX(-100%)']} cursor="pointer">
<Link to="/login"> <Link to="/login">
<Icon size="12px" name="🌈"></Icon> <Icon size="12px" name="🌈"></Icon>

View File

@ -1,146 +1,143 @@
import React, { useState } from "react" import React, { useState } from 'react';
import ClickAwayListener from "react-click-away-listener" import ClickAwayListener from 'react-click-away-listener';
import { Center, Flex, Text } from "@chakra-ui/react" import { Center, Flex, Text } from '@chakra-ui/react';
import { Icon } from "../Icon/Icon" import { Icon } from '../Icon/Icon';
import { useThingtime } from "./useThingtime" import { useThingtime } from './useThingtime';
export const SettingsMenu = (props) => { export const SettingsMenu = (props) => {
const [show, setShow] = useState(false) const [show, setShow] = useState(false);
const hideRef = React.useRef(null) const hideRef = React.useRef(null);
const [opacity, setOpacity] = React.useState(props?.opacity === 0 ? 0 : 1) const [opacity, setOpacity] = React.useState(props?.opacity === 0 ? 0 : 1);
const [pinStatus, setPinStatus] = React.useState(false) const [pinStatus, setPinStatus] = React.useState(false);
const stateRef = React.useRef({ const stateRef = React.useRef({
pinStatus, pinStatus
}) });
React.useEffect(() => { React.useEffect(() => {
stateRef.current.pinStatus = pinStatus stateRef.current.pinStatus = pinStatus;
}, [pinStatus]) }, [pinStatus]);
const { thingtime, events } = useThingtime() const { thingtime, events } = useThingtime();
const opacityRef = React.useRef(null) const opacityRef = React.useRef(null);
const waitTime = 1555 const waitTime = 1555;
const [uuid, setUuid] = React.useState(null) const [uuid, setUuid] = React.useState(null);
React.useEffect(() => { React.useEffect(() => {
setUuid(Math.random().toString(36).substring(7)) setUuid(Math.random().toString(36).substring(7));
}, []) }, []);
React.useEffect(() => { React.useEffect(() => {
const subscription = events.subscribe((event) => { const subscription = events.subscribe((event) => {
if (event?.type === "settings-menu-hide" && event?.uuid !== uuid) { if (event?.type === 'settings-menu-hide' && event?.uuid !== uuid) {
if (!stateRef?.current?.pinStatus || event?.force) { if (!stateRef?.current?.pinStatus || event?.force) {
setShow(false) setShow(false);
setOpacity(0) setOpacity(0);
} }
} }
}) });
return () => { return () => {
subscription?.unsubscribe?.() subscription?.unsubscribe?.();
} };
}, [events, uuid]) }, [events, uuid]);
React.useEffect(() => { React.useEffect(() => {
clearInterval(opacityRef?.current) clearInterval(opacityRef?.current);
if (props?.opacity) { if (props?.opacity) {
setOpacity(props?.opacity) setOpacity(props?.opacity);
} else { } else {
opacityRef.current = setInterval(() => { opacityRef.current = setInterval(() => {
if (!stateRef?.current?.pinStatus) { if (!stateRef?.current?.pinStatus) {
setOpacity(props?.opacity) setOpacity(props?.opacity);
setShow(false) setShow(false);
} }
}, waitTime) }, waitTime);
} }
}, [props?.opacity]) }, [props?.opacity]);
React.useEffect(() => { React.useEffect(() => {
if (show || props?.opacity) { if (show || props?.opacity) {
clearInterval(hideRef?.current) clearInterval(hideRef?.current);
events.next({ events.next({
type: "settings-menu-hide", type: 'settings-menu-hide',
uuid, uuid
}) });
} else if (!show) { } else if (!show) {
setPinStatus(false) setPinStatus(false);
} }
}, [show, props?.opacity, events, uuid]) }, [show, props?.opacity, events, uuid]);
const maybeHide = React.useCallback(() => { const maybeHide = React.useCallback(() => {
clearInterval(hideRef?.current) clearInterval(hideRef?.current);
hideRef.current = setTimeout(() => { hideRef.current = setTimeout(() => {
if (!stateRef?.current?.pinStatus) { if (!stateRef?.current?.pinStatus) {
setShow(false) setShow(false);
setOpacity(0) setOpacity(0);
} }
}, waitTime) }, waitTime);
}, []) }, []);
const showMenu = React.useCallback(() => { const showMenu = React.useCallback(() => {
clearInterval(hideRef?.current) clearInterval(hideRef?.current);
setShow(true) setShow(true);
}, []) }, []);
const hideMenu = React.useCallback(() => { const hideMenu = React.useCallback(() => {
setShow(false) setShow(false);
}, []) }, []);
const basePadding = React.useMemo(() => { const basePadding = React.useMemo(() => {
return 4 return 4;
}, []) }, []);
const types = React.useMemo(() => { const types = React.useMemo(() => {
const baseTypes = thingtime?.settings?.types?.javascript || {} const baseTypes = thingtime?.settings?.types?.javascript || {};
const baseTypeKeys = Object.keys(baseTypes) const baseTypeKeys = Object.keys(baseTypes);
const customTypes = thingtime?.settings?.types?.custom || {} const customTypes = thingtime?.settings?.types?.custom || {};
const customTypeKeysRaw = Object.keys(customTypes) const customTypeKeysRaw = Object.keys(customTypes);
const customTypeKeys = customTypeKeysRaw?.filter((key) => { const customTypeKeys = customTypeKeysRaw?.filter((key) => {
return !baseTypeKeys?.includes?.(key) return !baseTypeKeys?.includes?.(key);
}) });
const types = [ const types = [
...(baseTypeKeys?.map?.((key) => { ...(baseTypeKeys?.map?.((key) => {
return { return {
...baseTypes?.[key], ...baseTypes?.[key],
key, key
} };
}) || []), }) || []),
...(customTypeKeys?.map?.((key) => { ...(customTypeKeys?.map?.((key) => {
return { return {
...customTypes?.[key], ...customTypes?.[key],
key, key
} };
}) || []), }) || [])
] ];
return types return types;
}, [ }, [thingtime?.settings?.types?.javascript, thingtime?.settings?.types?.custom]);
thingtime?.settings?.types?.javascript,
thingtime?.settings?.types?.custom,
])
const onType = React.useCallback( const onType = React.useCallback(
(args) => { (args) => {
props?.onType?.(args) props?.onType?.(args);
}, },
[props?.onType] [props?.onType]
) );
const onDelete = React.useCallback( const onDelete = React.useCallback(
(type) => { (type) => {
props?.onDelete?.() props?.onDelete?.();
}, },
[props?.onDelete] [props?.onDelete]
) );
const childIconSize = 10 const childIconSize = 10;
const iconSize = props?.iconSize || 7 const iconSize = props?.iconSize || 7;
return ( return (
<ClickAwayListener onClickAway={hideMenu}> <ClickAwayListener onClickAway={hideMenu}>
@ -149,7 +146,7 @@ export const SettingsMenu = (props) => {
// width="100%" // width="100%"
paddingRight={36} paddingRight={36}
opacity={opacity} opacity={opacity}
transition={props?.transition || "all 0.2s ease-in-out"} transition={props?.transition || 'all 0.2s ease-in-out'}
onMouseEnter={showMenu} onMouseEnter={showMenu}
onMouseLeave={maybeHide} onMouseLeave={maybeHide}
> >
@ -159,6 +156,8 @@ export const SettingsMenu = (props) => {
cursor="pointer" cursor="pointer"
// onClick={deleteValue} // onClick={deleteValue}
transition="all 0.2s ease-in-out" transition="all 0.2s ease-in-out"
// add title for hover context
title={`Options`}
> >
<Icon name="wizard" size={iconSize}></Icon> <Icon name="wizard" size={iconSize}></Icon>
</Flex> </Flex>
@ -169,7 +168,7 @@ export const SettingsMenu = (props) => {
left={0} left={0}
flexDirection="column" flexDirection="column"
opacity={show ? 1 : 0} opacity={show ? 1 : 0}
pointerEvents={show ? "all" : "none"} pointerEvents={show ? 'all' : 'none'}
> >
<Flex <Flex
position="absolute" position="absolute"
@ -178,19 +177,44 @@ export const SettingsMenu = (props) => {
padding="5px" padding="5px"
cursor="pointer" cursor="pointer"
onClick={() => setPinStatus((prev) => !prev)} onClick={() => setPinStatus((prev) => !prev)}
title={`Pin Options`}
> >
<Icon {show === true && <Icon opacity={pinStatus ? 1 : 0.5} name={pinStatus ? 'pinned' : 'pin'} size="8px"></Icon>}
opacity={pinStatus ? 1 : 0.5}
name={pinStatus ? "pinned" : "pin"}
size="8px"
></Icon>
</Flex> </Flex>
{/* edit mode menu item */}
<Flex <Flex
flexDirection="column" flexDirection="column"
// rowGap={basePadding / 3} // rowGap={basePadding / 3}
background="greys.lightt" background="greys.lightt"
borderRadius={4} borderRadius={4}
boxShadow={props?.boxShadow || "0px 2px 7px 0px rgba(0,0,0,0.2)"} boxShadow={props?.boxShadow || '0px 2px 7px 0px rgba(0,0,0,0.2)'}
paddingY={basePadding}
>
<Flex
alignItems="center"
flexDirection="row"
// paddingRight={basePadding}
paddingLeft={basePadding}
_hover={{
background: 'greys.light'
}}
cursor="pointer"
// paddingX={basePadding * 1}
paddingY={basePadding / 2}
>
<Icon marginBottom="-2px" name="🎨" size={childIconSize}></Icon>
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
Toggle Edit Mode
</Text>
</Flex>
</Flex>
<Flex
flexDirection="column"
// rowGap={basePadding / 3}
background="greys.lightt"
borderRadius={4}
boxShadow={props?.boxShadow || '0px 2px 7px 0px rgba(0,0,0,0.2)'}
paddingY={basePadding} paddingY={basePadding}
> >
{!props?.readonly && ( {!props?.readonly && (
@ -200,17 +224,13 @@ export const SettingsMenu = (props) => {
// paddingRight={basePadding} // paddingRight={basePadding}
paddingLeft={basePadding} paddingLeft={basePadding}
_hover={{ _hover={{
background: "greys.light", background: 'greys.light'
}} }}
cursor="pointer" cursor="pointer"
// paddingX={basePadding * 1} // paddingX={basePadding * 1}
paddingY={basePadding / 2} paddingY={basePadding / 2}
> >
<Icon <Icon marginBottom="-2px" name="cyclone" size={childIconSize}></Icon>
marginBottom="-2px"
name="cyclone"
size={childIconSize}
></Icon>
<Text marginTop="-2px" paddingLeft={2} fontSize="xs"> <Text marginTop="-2px" paddingLeft={2} fontSize="xs">
Types Types
</Text> </Text>
@ -228,12 +248,12 @@ export const SettingsMenu = (props) => {
types.map((type, idx) => { types.map((type, idx) => {
const ret = ( const ret = (
<Flex <Flex
key={props?.uuid + props?.fullPath + "-type-menu-" + idx} key={props?.uuid + props?.fullPath + '-type-menu-' + idx}
width="100%" width="100%"
_hover={{ _hover={{
"&>div": { '&>div': {
background: "greys.light", background: 'greys.light'
}, }
}} }}
cursor="pointer" cursor="pointer"
onClick={() => onType({ type })} onClick={() => onType({ type })}
@ -247,11 +267,7 @@ export const SettingsMenu = (props) => {
paddingLeft={basePadding * 2} paddingLeft={basePadding * 2}
paddingY={basePadding / 2} paddingY={basePadding / 2}
> >
<Icon <Icon marginBottom="-2px" name={type?.icon || type?.key || type?.label || type} size={childIconSize}></Icon>
marginBottom="-2px"
name={type?.icon || type?.key || type?.label || type}
size={childIconSize}
></Icon>
<Text marginTop="-2px" paddingLeft={2} fontSize="xs"> <Text marginTop="-2px" paddingLeft={2} fontSize="xs">
{type?.label || type?.key || type} {type?.label || type?.key || type}
</Text> </Text>
@ -259,18 +275,18 @@ export const SettingsMenu = (props) => {
<Flex <Flex
marginLeft="auto" marginLeft="auto"
_hover={{ _hover={{
transform: "scale(1.3)", transform: 'scale(1.3)'
}} }}
transition="all 0.2s ease-out" transition="all 0.2s ease-out"
onClick={(e) => { onClick={(e) => {
e?.preventDefault?.() e?.preventDefault?.();
e?.stopPropagation?.() e?.stopPropagation?.();
// cancel bubble // cancel bubble
e?.nativeEvent?.stopImmediatePropagation?.() e?.nativeEvent?.stopImmediatePropagation?.();
onType({ onType({
type, type,
wrap: true, wrap: true
}) });
}} }}
> >
<Icon name="wrap" size={childIconSize}></Icon> <Icon name="wrap" size={childIconSize}></Icon>
@ -278,8 +294,8 @@ export const SettingsMenu = (props) => {
)} )}
</Flex> </Flex>
</Flex> </Flex>
) );
return ret return ret;
})} })}
</Flex> </Flex>
{!props?.readonly && props?.onDelete && ( {!props?.readonly && props?.onDelete && (
@ -287,18 +303,14 @@ export const SettingsMenu = (props) => {
alignItems="center" alignItems="center"
flexDirection="row" flexDirection="row"
_hover={{ _hover={{
background: "greys.light", background: 'greys.light'
}} }}
cursor="pointer" cursor="pointer"
onClick={onDelete} onClick={onDelete}
paddingX={basePadding * 1} paddingX={basePadding * 1}
paddingY={basePadding / 2} paddingY={basePadding / 2}
> >
<Icon <Icon marginBottom="-2px" name="bin" size={childIconSize}></Icon>
marginBottom="-2px"
name="bin"
size={childIconSize}
></Icon>
<Text marginTop="-2px" paddingLeft={2} fontSize="xs"> <Text marginTop="-2px" paddingLeft={2} fontSize="xs">
Recycle Recycle
</Text> </Text>
@ -308,5 +320,5 @@ export const SettingsMenu = (props) => {
</Flex> </Flex>
</Center> </Center>
</ClickAwayListener> </ClickAwayListener>
) );
} };

View File

@ -0,0 +1,15 @@
import { Box } from '@chakra-ui/react';
import { Branding } from '~/components/Branding/Branding';
import { TopSpacing } from '~/components/Layout/TopSpacing';
import { Raw } from '~/components/MongoDB/Raw';
import { RawResults } from '~/components/MongoDB/RawResults';
export default function branding() {
const template = (
<>
<Branding />
</>
);
return template;
}

0
vercel.json Normal file
View File