@chakra-ui/react#useColorModeValue JavaScript Examples
The following examples show how to use
@chakra-ui/react#useColorModeValue.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Container.js From benjamincarlson.io with MIT License | 6 votes |
Container = ({ children }) => {
const router = useRouter()
return (
<>
<Link isExternal href="https://github.com/sponsors/bjcarlson42">
<Box bgGradient='linear(to-l, #7928CA, #FF0080)'>
<Flex justify="center" align="center" py={1} color="white">
<GitHubIcon />
<Text ml={2}>Sponsor Me On GitHub!</Text>
</Flex>
</Box>
</Link>
<Box h={8} bgColor={useColorModeValue("rgb(248, 250, 252)", "gray.900")} />
<Navigation />
<Box h={8} bgColor={useColorModeValue("rgb(248, 250, 252)", "gray.900")} />
<Flex
as="main"
justifyContent="center"
flexDirection="column"
bg={useColorModeValue("#ffffff", "#15161a")}
color={useColorModeValue("#000000", "#ffffff")}
>
{/* hero outside main Flex to avoid px */}
{router.pathname == '/' && <Hero />}
<Flex px={4} flexDir="column" minH="90vh">
{children}
</Flex>
<Footer />
</Flex>
</>
)
}
Example #2
Source File: Faq.js From MeowForm with MIT License | 6 votes |
function Faq() {
const textColor = useColorModeValue("gray.700", "gray.100");
const [check] = useMediaQuery("(min-width: 1025px)");
return (
<div className="faq-div">
<div className="faq-main">
<div className="heading">
<Text
align='center'
color={textColor}
fontSize={check ? "5xl" : "3xl"}
fontWeight='extrabold'
mt={check ? "0%" : "4%"}>
Frequently Asked Questions (FAQ)
</Text>
</div>
<div className="faq-data">
{
FAQ_Data.map((data) => (
<div className="singleFaq" key={data.id}>
<div className="faq-question">
<p><span>Q . </span>{data.question}</p>
</div>
<div className="faq-answer">
<p><span>A . </span>{data.answer}</p>
</div>
</div>
))
}
</div>
</div>
</div>
);
}
Example #3
Source File: ColorModeSwitcher.jsx From realtime-chat-supabase-react with Apache License 2.0 | 6 votes |
ColorModeSwitcher = (props) => {
const { toggleColorMode } = useColorMode();
const text = useColorModeValue("dark", "light");
const SwitchIcon = useColorModeValue(FaMoon, FaSun);
return (
<IconButton
size="md"
fontSize="lg"
aria-label={`Switch to ${text} mode`}
variant="ghost"
color="current"
marginLeft="2"
onClick={toggleColorMode}
icon={<SwitchIcon />}
{...props}
/>
);
}
Example #4
Source File: ColorModeSwitcher.js From react-sample-projects with MIT License | 6 votes |
ColorModeSwitcher = props => {
const { toggleColorMode } = useColorMode();
const text = useColorModeValue('dark', 'light');
const SwitchIcon = useColorModeValue(FaMoon, FaSun);
return (
<IconButton
size="md"
fontSize="lg"
aria-label={`Switch to ${text} mode`}
variant="ghost"
color="current"
marginLeft="2"
onClick={toggleColorMode}
icon={<SwitchIcon />}
{...props}
/>
);
}
Example #5
Source File: Highlight.js From blobs.app with MIT License | 6 votes |
export default function Highlight({ code, lang }) {
const theme = useColorModeValue(coy, nord);
return (
<SyntaxHighlighter
language={lang}
style={{
...theme,
'code[class*="language-"]': {
...theme['code[class*="language-"]'],
fontSize: '15px',
},
}}
customStyle={{
marginBottom: 0,
marginTop: 0,
backgroundColor: 'transparent',
padding: 0,
}}
wrapLines
>
{code}
</SyntaxHighlighter>
);
}
Example #6
Source File: PatternSetter.js From blobs.app with MIT License | 6 votes |
PatternBox = ({ meta, clickHandler, isSelected }) => {
const patternBg = useColorModeValue('A0AEC0', '4A5568');
return (
<Box
as="button"
w="60px"
h="60px"
mr="3"
rounded="lg"
borderColor={isSelected ? 'primary' : 'gray.400'}
borderWidth="2px"
_focus={{ outline: 0 }}
backgroundSize="50%"
backgroundColor="gray.100"
backgroundPosition="center"
_dark={{
backgroundColor: 'gray.500',
borderColor: isSelected ? 'primary' : 'gray.600',
}}
backgroundImage={`url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='${
meta.width
}' height='${meta.height}' viewBox='0 0 ${meta.width} ${
meta.height
}'%3E%3Cg fill='%23${
isSelected ? 'd7819b' : patternBg
}' fill-opacity='1'%3E%3Cpath fill-rule='evenodd' d='${
meta.path
}'/%3E%3C/g%3E%3C/svg%3E")`}
onClick={() => clickHandler(meta.name)}
/>
);
}
Example #7
Source File: Layout.js From blobs.app with MIT License | 6 votes |
Layout = ({ children }) => {
const theme = useColorModeValue('light', 'dark');
const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
}
}
}
`);
return (
<Provider store={store}>
<Box className={theme}>
<Container
maxW="container.xl"
flex="1"
display="flex"
flexDir="column"
minH="100vh"
>
<Box as="main" flex="1" display="flex" flexDir="column">
{children}
</Box>
<Footer siteTitle={data.site.siteMetadata?.title || 'Title'} />
</Container>
</Box>
</Provider>
);
}
Example #8
Source File: ThemeSwitch.js From blobs.app with MIT License | 6 votes |
export default function ThemeSwitch() {
const { toggleColorMode: toggleMode } = useColorMode();
const ToggleIcon = useColorModeValue(SunIcon, MoonIcon);
return (
<Button
leftIcon={<ToggleIcon fontSize="18px" />}
variant="silent"
aria-label="Toggle Theme"
onClick={toggleMode}
>
Switch theme
</Button>
);
}
Example #9
Source File: useCustomColorModes.js From scaffold-directory with MIT License | 6 votes |
useCustomColorModes = () => {
const primaryFontColor = useColorModeValue("gray.700", "gray.200");
const codeFontColor = primaryFontColor;
const secondaryFontColor = useColorModeValue("gray.600", "gray.400");
const dividerColor = useColorModeValue("gray.200", "gray.700");
const borderColor = dividerColor;
const codeBgColor = useColorModeValue("gray.100", "gray.900");
const iconBgColor = codeBgColor;
return {
primaryFontColor,
secondaryFontColor,
dividerColor,
borderColor,
codeFontColor,
codeBgColor,
iconBgColor,
};
}
Example #10
Source File: ColorModeSwitcher.jsx From scaffold-directory with MIT License | 6 votes |
ColorModeSwitcher = () => {
const { toggleColorMode } = useColorMode();
const Icon = useColorModeValue(<SunIcon color="gray.400" h={4} w={4} />, <MoonIcon h={4} w={4} />);
return (
<Flex pos="fixed" bottom={0} right={0} p={6}>
<Switch onChange={toggleColorMode} mr={4} align="center" />
{Icon}
</Flex>
);
}
Example #11
Source File: SavedBlobs.js From blobs.app with MIT License | 5 votes |
SavedBlobs = ({ savedBlobs = [], deleteBlob, loadBlobs }) => {
const cardHoverBg = useColorModeValue('gray.100', 'gray.700');
useEffect(() => {
if (!savedBlobs) loadBlobs();
}, [savedBlobs]);
return (
<Box>
{savedBlobs?.length === 0 && (
<Box textAlign="center">
<Text my="20" fontSize="2xl">
No saved blobs found!
</Text>
</Box>
)}
<SimpleGrid
columns={{ sm: 2, md: 4 }}
spacing="40px"
mb="20"
justifyContent="center"
>
{savedBlobs?.map((blob) => (
<LinkBox
// h="200"
rounded="2xl"
p="5"
borderWidth="1px"
_hover={{ boxShadow: '2xl', background: cardHoverBg }}
role="group"
>
<Text
fontSize="sm"
display="flex"
alignItems="center"
justifyContent="space-between"
>
<LinkOverlay
style={{ textTransform: 'uppercase', fontWeight: 600 }}
href={blob.url}
>
{blob.name}
</LinkOverlay>
<Button
variant="unstyled"
visibility="hidden"
h="auto"
_groupHover={{ visibility: 'visible' }}
onClick={() => {
deleteBlob(blob.id);
}}
>
<TrashIcon color="tomato" />
</Button>
</Text>
<Divider mt="4" />
<Blob {...blob} />
</LinkBox>
))}
</SimpleGrid>
</Box>
);
}
Example #12
Source File: Home.js From MeowForm with MIT License | 4 votes |
function Home(props) {
const textColor = useColorModeValue("gray.700", "gray.100");
const [check] = useMediaQuery("(min-width: 1025px)");
return (
<>
<div>
<Box ml='5%'>
<Bounce top>
<Text
align='center'
color={textColor}
fontSize={check ? "5xl" : "3xl"}
fontWeight='extrabold'
mt={check ? "0%" : "4%"}>
Functional Forms Solution for
</Text>
<Text
align='center'
bgGradient='linear(to-l, #ec9f05 ,#ff4e00)'
bgClip='text'
fontSize={check ? "7xl" : "4xl"}
fontWeight='extrabold'
mt={check ? "0%" : "4%"}>
<Typewriter
options={{
strings: [
"React ",
"Flutter ",
"Html ",
"React Native",
"Vue",
"Angular",
],
autoStart: true,
loop: true,
}}
/>
</Text>
</Bounce>
<Flip top>
<Box
bgColor='#333'
ml={check ? "20%" : "5%"}
mt={check ? "8%" : "12%"}
width={check ? "60%" : "90%"}
borderRadius='25'>
<Text color='#fff' padding='5%'>
<Typewriter
options={{
strings: [
`<form action="https://server.meowform.xyz/YourEmail&FormName method="post"`,
],
autoStart: true,
loop: true,
}}
/>
</Text>
</Box>
<Flex flexDirection='row' ml={check ? "40%" : "23%"}>
<Box margin='1%'>
<a
rel='noreferrer'
href='https://docs.meowform.xyz/docs/intro'
target='_blank'>
<Button margin='1%'> View docs</Button>
</a>
</Box>
<Box margin='1%'>
<Link to='/dashboard'>
<Button colorScheme='orange'>
{" "}
Try it
</Button>
</Link>
</Box>
</Flex>
</Flip>
<Image
lazyLoad={true}
position={check ? "absolute" : "static"}
src='https://res.cloudinary.com/dd0mtkqbr/image/upload/v1629015408/kitekat_ezvxgy.png'
width={check ? "24%" : "40%"}
height={check ? "8%" : "80%"}
mt={check ? "-20%" : "5%"}
ml={check ? "-15%" : "28%"}
transform={check ? "rotate(60deg)" : ""}
opacity={check ? "0.9" : "1"}></Image>
</Box>
<Box></Box>
<Box mt='10%'>.</Box>
</div>
<div ml='25%' mt='10%'>
.
</div>
<Box ml='10%' mt='5%'>
<Flex flexDirection={check ? "row" : "column-reverse"}>
<Image
src='https://res.cloudinary.com/dd0mtkqbr/image/upload/v1629017773/kitekat-19_1_nsknib.png'
width='40%'
height='30%'
ml={check ? "0%" : "25%"}
/>
<Fade right>
<Text
align='center'
color={textColor}
fontSize={check ? "5xl" : "3xl"}
fontWeight='extrabold'
mt={check ? "7%" : "4%"}
ml={check ? "" : "-5%"}>
Make backend-less forms with MeowForm and get
<Text
bgGradient='linear(to-l, #ec9f05 ,#ff4e00)'
bgClip='text'>
Unlimited Responses{" "}
</Text>{" "}
in your inbox .
</Text>
</Fade>
</Flex>
<Flex flexDirection={check ? "row" : "column"} mt='5%'>
<Fade left>
<Text
align='center'
color={textColor}
fontSize={check ? "5xl" : "3xl"}
fontWeight='extrabold'
mt={check ? "7%" : "4%"}
ml={check ? "" : "-5%"}>
Choose your fontend , Use our API to handle things
for
<Text
bgGradient='linear(to-l, #ec9f05 ,#ff4e00)'
bgClip='text'>
{" "}
Free{" "}
</Text>
</Text>
</Fade>
<Image
src='https://res.cloudinary.com/dd0mtkqbr/image/upload/v1629029065/kitekat-8_ein5pc.png'
width='40%'
height='30%'
ml={check ? "0%" : "25%"}
/>
</Flex>
<Flex flexDirection={check ? "row-reverse" : "column"} mt='5%'>
<Fade right>
<Text
align='center'
color={textColor}
fontSize={check ? "5xl" : "3xl"}
fontWeight='extrabold'
mt={check ? "7%" : "4%"}
ml={check ? "" : "-5%"}>
Missed a response ? don't worry view all responses
in out dashboard
<Text
bgGradient='linear(to-l, #ec9f05 ,#ff4e00)'
bgClip='text'>
{" "}
</Text>
</Text>
</Fade>
<Image
src='https://res.cloudinary.com/dd0mtkqbr/image/upload/v1630156150/kitekat-2_kzxgrr.png'
width='40%'
height='30%'
ml={check ? "0%" : "25%"}
/>
</Flex>
</Box>
<Box margin='10%'></Box>
<Box
margin={check ? "5%" : "1%"}
padding={check ? "5%" : "1%"}
alignContent='center'
align='center'>
<Flip top>
<iframe
title='demo video'
width={check ? "640" : "300"}
height={check ? "360" : "200"}
align='center'
src='https://www.loom.com/embed/c8cdc167f9b0405ca37e0b8a6f7ffe13'
frameborder='0'
webkitallowfullscreen
mozallowfullscreen
allowfullscreen='true'></iframe>
</Flip>
<h1 margin='15%'> Meow Form in action</h1>
</Box>
<div className="Reviews">
{/* <Reviews /> */}
</div>
<div className="faq">
<Faq />
</div>
</>
);
}
Example #13
Source File: FormCard.js From MeowForm with MIT License | 4 votes |
function FormCard({formName , responses ,formData ,redirectUrl ,email }) {
const formBackground = useColorModeValue("gray.100","gray.700");
const [check] = useMediaQuery("(min-width: 1025px)")
const { isOpen, onOpen, onClose } = useDisclosure()
const [size, setSize] = React.useState("md")
const [url, setUrl] = React.useState();
const [edit , setEdit] = React.useState(false);
let apiKey = process.env.REACT_APP_APIKEY ;
let apiUrl = process.env.REACT_APP_HOSTURL ;
function isValidURL(string) {
var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
return (res !== null)
};
const sendResponse = async(serverUrl)=> {
let meow = await axios({
method: 'post',
url: serverUrl,
data: {
url: url,
formName: formName
}
});
}
const checkUrl = () => {
if(url === "" || url === undefined){
toast.error(' Url not saved');
setEdit(!edit)
}else if(isValidURL(url)){
let serverUrl = apiUrl + 'url/' + email + '&' + apiKey;
sendResponse(serverUrl);
toast.success('Url is saved, it will some time to reflect');
setEdit(!edit)
}else{
toast.error('The url is not valid :( ');
}
}
return (
<Box id={formName}mt="1%" borderRadius={25} padding="2%" display="flex" flexDirection={check ? "row" : "column"} backgroundColor ="#fff" background={formBackground} >
<Box width="100%" ml="5%" >
<Flex justifyContent="space-between" >
<Text> {formName}</Text>
<Text> {responses} Responses</Text>
<Button colorScheme="orange" onClick={onOpen}> View</Button>
</Flex>
{/* {console.log(formData)} */}
</Box>
<Drawer onClose={onClose} isOpen={isOpen} size={check ? "xl" :"xs"}>
<DrawerOverlay />
<DrawerContent>
<DrawerHeader align="center">
<Text
margin="1%"
fontWeight="extraBold"
fontSize="3xl"
bgGradient="linear(to-l, #ec9f05 ,#ff4e00)"
bgClip="text"
>
{formName}
</Text>
<Text
>
{responses} Responses
</Text>
</DrawerHeader>
<DrawerBody>
<Box>
{formData.length > 0 &&
<>
<FormHeading obj={formData[0]}></FormHeading>
{
formData.map(x=>
<FormData obj={x}></FormData>
)
}
</>
}
{/* <Flex>
<Text margin="5%">Redirect Url </Text>
<Text margin="5%"> { redirectUrl } </Text>
</Flex> */}
{/* { edit && */}
{/* <Flex>
<Input placeholder={redirectUrl} isDisabled={!edit} value={url} onChange={ (e)=>(setUrl(e.target.value))}
/>
{edit === false ?
<Button onClick={()=>{setEdit(!edit)}}>
edit
</Button>
:
<Button onClick={()=>(checkUrl())}> Save</Button>
}
</Flex> */}
{/* } */}
{/* <Text> * you one need Redirect url if you are just using html css , check docs here </Text> */}
</Box>
<Box>
</Box>
</DrawerBody>
</DrawerContent>
</Drawer>
</Box>
);
}
Example #14
Source File: SubmissionReviewView.jsx From scaffold-directory with MIT License | 4 votes |
export default function SubmissionReviewView({ userProvider }) {
const address = useUserAddress(userProvider);
const [challenges, setChallenges] = React.useState([]);
const [isLoadingChallenges, setIsLoadingChallenges] = React.useState(true);
const [draftBuilds, setDraftBuilds] = React.useState([]);
const [isLoadingDraftBuilds, setIsLoadingDraftBuilds] = React.useState(true);
const toast = useToast({ position: "top", isClosable: true });
const toastVariant = useColorModeValue("subtle", "solid");
const { secondaryFontColor } = useCustomColorModes();
const fetchSubmittedChallenges = useCallback(async () => {
setIsLoadingChallenges(true);
let fetchedChallenges;
try {
fetchedChallenges = await getSubmittedChallenges(address);
} catch (error) {
toast({
description: "There was an error getting the submitted challenges. Please try again",
status: "error",
variant: toastVariant,
});
setIsLoadingChallenges(false);
return;
}
setChallenges(fetchedChallenges.sort(bySubmittedTimestamp));
setIsLoadingChallenges(false);
}, [address, toastVariant, toast]);
const fetchSubmittedBuilds = useCallback(async () => {
setIsLoadingDraftBuilds(true);
let fetchedDraftBuilds;
try {
fetchedDraftBuilds = await getDraftBuilds(address);
} catch (error) {
toast({
description: "There was an error getting the draft builds. Please try again",
status: "error",
variant: toastVariant,
});
setIsLoadingDraftBuilds(false);
return;
}
setDraftBuilds(fetchedDraftBuilds.sort(bySubmittedTimestamp));
setIsLoadingDraftBuilds(false);
}, [address, toastVariant, toast]);
useEffect(() => {
if (!address) {
return;
}
fetchSubmittedChallenges();
// eslint-disable-next-line
}, [address]);
useEffect(() => {
if (!address) {
return;
}
fetchSubmittedBuilds();
// eslint-disable-next-line
}, [address]);
const handleSendChallengeReview = reviewType => async (userAddress, challengeId, comment) => {
let signMessage;
try {
signMessage = await getChallengeReviewSignMessage(address, userAddress, challengeId, reviewType);
} catch (error) {
toast({
description: " Sorry, the server is overloaded. ???",
status: "error",
variant: toastVariant,
});
return;
}
let signature;
try {
signature = await userProvider.send("personal_sign", [signMessage, address]);
} catch (error) {
toast({
description: "Couldn't get a signature from the Wallet",
status: "error",
variant: toastVariant,
});
console.error(error);
return;
}
try {
await patchChallengeReview(address, signature, { userAddress, challengeId, newStatus: reviewType, comment });
} catch (error) {
if (error.status === 401) {
toast({
status: "error",
description: "Submission Error. You don't have the required role.",
variant: toastVariant,
});
return;
}
toast({
status: "error",
description: "Submission Error. Please try again.",
variant: toastVariant,
});
return;
}
toast({
description: "Review submitted successfully",
status: "success",
variant: toastVariant,
});
fetchSubmittedChallenges();
};
const handleSendBuildReview = reviewType => async (userAddress, buildId) => {
let signMessage;
try {
signMessage = await getBuildReviewSignMessage(address, buildId, reviewType);
} catch (error) {
toast({
description: " Sorry, the server is overloaded. ???",
status: "error",
variant: toastVariant,
});
return;
}
let signature;
try {
signature = await userProvider.send("personal_sign", [signMessage, address]);
} catch (error) {
toast({
description: "Couldn't get a signature from the Wallet",
status: "error",
variant: toastVariant,
});
return;
}
try {
await patchBuildReview(address, signature, { userAddress, buildId, newStatus: reviewType });
} catch (error) {
if (error.status === 401) {
toast({
status: "error",
description: "Submission Error. You don't have the required role.",
variant: toastVariant,
});
return;
}
toast({
status: "error",
description: "Submission Error. Please try again.",
variant: toastVariant,
});
return;
}
toast({
description: "Review submitted successfully",
status: "success",
variant: toastVariant,
});
fetchSubmittedBuilds();
};
return (
<Container maxW="container.lg">
<Container maxW="container.md" centerContent>
<Heading as="h1">Review Submissions</Heading>
<Text color={secondaryFontColor}>Pending submissions to validate.</Text>
<Text color={secondaryFontColor} mb="6">
Check our{" "}
<Link href={RUBRIC_URL} color="teal.500" isExternal>
Grading Rubric
</Link>
.
</Text>
</Container>
<Heading as="h2" size="lg" mt={6} mb={4}>
Challenges
</Heading>
<Box overflowX="auto">
{isLoadingChallenges ? (
<ChallengesTableSkeleton />
) : (
<Table>
<Thead>
<Tr>
<Th>Builder</Th>
<Th>Challenge</Th>
<Th>Submitted time</Th>
<Th>Actions</Th>
</Tr>
</Thead>
<Tbody>
{!challenges || challenges.length === 0 ? (
<Tr>
<Td colSpan={6}>
<Text color={secondaryFontColor} textAlign="center" mb={4}>
<Icon as={HeroIconInbox} w={6} h={6} color={secondaryFontColor} mt={6} mb={4} />
<br />
All challenges have been reviewed
</Text>
</Td>
</Tr>
) : (
challenges.map(challenge => (
<ChallengeReviewRow
key={`${challenge.userAddress}_${challenge.id}`}
challenge={challenge}
isLoading={isLoadingChallenges}
approveClick={handleSendChallengeReview("ACCEPTED")}
rejectClick={handleSendChallengeReview("REJECTED")}
userProvider={userProvider}
/>
))
)}
</Tbody>
</Table>
)}
</Box>
<Heading as="h2" size="lg" mt={6} mb={4}>
Builds
</Heading>
<Box overflowX="auto">
{isLoadingDraftBuilds ? (
<BuildsTableSkeleton />
) : (
<Table mb={4}>
<Thead>
<Tr>
<Th>Builder</Th>
<Th>Build Name</Th>
<Th>Description</Th>
<Th>Branch URL</Th>
<Th>Submitted time</Th>
<Th>Actions</Th>
</Tr>
</Thead>
<Tbody>
{!draftBuilds || draftBuilds.length === 0 ? (
<Tr>
<Td colSpan={5}>
<Text color={secondaryFontColor} textAlign="center" mb={4}>
<Icon as={HeroIconInbox} w={6} h={6} color={secondaryFontColor} mt={6} mb={4} />
<br />
All builds have been reviewed
</Text>
</Td>
</Tr>
) : (
draftBuilds.map(build => (
<BuildReviewRow
key={`${build.userAddress}_${build.id}`}
build={build}
isLoading={isLoadingDraftBuilds}
approveClick={handleSendBuildReview("ACCEPTED")}
rejectClick={handleSendBuildReview("REJECTED")}
/>
))
)}
</Tbody>
</Table>
)}
</Box>
</Container>
);
}
Example #15
Source File: BuilderProfileView.jsx From scaffold-directory with MIT License | 4 votes |
export default function BuilderProfileView({ serverUrl, mainnetProvider, address, userProvider, userRole }) {
const { builderAddress } = useParams();
const { primaryFontColor, secondaryFontColor, borderColor, iconBgColor } = useCustomColorModes();
const [builder, setBuilder] = useState();
const [challengeEvents, setChallengeEvents] = useState([]);
const [isLoadingBuilder, setIsLoadingBuilder] = useState(false);
const [isBuilderOnBg, setIsBuilderOnBg] = useState(false);
const [isLoadingTimestamps, setIsLoadingTimestamps] = useState(false);
const toast = useToast({ position: "top", isClosable: true });
const toastVariant = useColorModeValue("subtle", "solid");
const challenges = builder?.challenges ? Object.entries(builder.challenges) : undefined;
const acceptedChallenges = getAcceptedChallenges(builder?.challenges);
const isMyProfile = builderAddress === address;
const fetchBuilder = async () => {
setIsLoadingBuilder(true);
const fetchedBuilder = await axios.get(serverUrl + `/builders/${builderAddress}`);
setBuilder(fetchedBuilder.data);
try {
await axios.get(bgBackendUrl + `/builders/${builderAddress}`);
} catch (e) {
// Builder Not found in BG
setIsLoadingBuilder(false);
return;
}
setIsBuilderOnBg(true);
setIsLoadingBuilder(false);
};
useEffect(() => {
fetchBuilder();
// eslint-disable-next-line
}, [builderAddress]);
useEffect(() => {
if (!builderAddress) {
return;
}
async function fetchChallengeEvents() {
setIsLoadingTimestamps(true);
try {
const fetchedChallengeEvents = await getChallengeEventsForUser(builderAddress);
setChallengeEvents(fetchedChallengeEvents.sort(byTimestamp).reverse());
setIsLoadingTimestamps(false);
} catch (error) {
toast({
description: "Can't get challenges metadata. Please try again",
status: "error",
variant: toastVariant,
});
}
}
fetchChallengeEvents();
// eslint-disable-next-line
}, [builderAddress]);
return (
<Container maxW="container.xl">
<SimpleGrid gap={14} columns={{ base: 1, xl: 4 }}>
<GridItem colSpan={1}>
<BuilderProfileCard
builder={builder}
mainnetProvider={mainnetProvider}
isMyProfile={isMyProfile}
userProvider={userProvider}
fetchBuilder={fetchBuilder}
userRole={userRole}
/>
</GridItem>
{isBuilderOnBg ? (
<GridItem colSpan={{ base: 1, xl: 3 }}>
<Box borderColor={borderColor} borderWidth={1} p={5}>
<Flex direction="column" align="center" justify="center">
<Image src="/assets/bg.png" mb={3} />
<Text mb={3} fontSize="lg" fontWeight="bold">
This builder has upgraded to BuidlGuidl.
</Text>
<Button as={Link} href={`${BG_FRONTEND_URL}/builders/${builderAddress}`} isExternal colorScheme="blue">
View their profile on Buidlguidl
</Button>
</Flex>
</Box>
</GridItem>
) : (
<GridItem colSpan={{ base: 1, xl: 3 }}>
<HStack spacing={4} mb={8}>
<Flex borderRadius="lg" borderColor={borderColor} borderWidth={1} p={4} w="full" justify="space-between">
<Flex bg={iconBgColor} borderRadius="lg" w={12} h={12} justify="center" align="center">
<InfoOutlineIcon w={5} h={5} />
</Flex>
<div>
<Text fontSize="xl" fontWeight="medium" textAlign="right">
{acceptedChallenges.length}
</Text>
<Text fontSize="sm" color={secondaryFontColor} textAlign="right">
challenges completed
</Text>
</div>
</Flex>
<Flex borderRadius="lg" borderColor={borderColor} borderWidth={1} p={4} w="full" justify="space-between">
<Flex bg={iconBgColor} borderRadius="lg" w={12} h={12} justify="center" align="center">
<InfoOutlineIcon w={5} h={5} />
</Flex>
<div>
<Text fontSize="xl" fontWeight="medium" textAlign="right">
{builder?.function ? (
<Tag colorScheme={userFunctionDescription[builder?.function].colorScheme} variant="solid">
{userFunctionDescription[builder?.function].label}
</Tag>
) : (
"-"
)}
</Text>
<Text fontSize="sm" color={secondaryFontColor} textAlign="right">
Role
</Text>
</div>
</Flex>
</HStack>
<Flex mb={4}>
<Text fontSize="2xl" fontWeight="bold">
Challenges
</Text>
<Spacer />
</Flex>
{isLoadingBuilder && <BuilderProfileChallengesTableSkeleton />}
{!isLoadingBuilder &&
(challenges ? (
<Box overflowX="auto">
<Table>
{isMyProfile && (
<TableCaption>
<Button as={RouteLink} colorScheme="blue" to="/">
Start a challenge
</Button>
</TableCaption>
)}
<Thead>
<Tr>
<Th>Name</Th>
<Th>Contract</Th>
<Th>Live Demo</Th>
<Th>Updated</Th>
<Th>Status</Th>
</Tr>
</Thead>
<Tbody>
{challenges.map(([challengeId, lastSubmission]) => {
if (!challengeInfo[challengeId]) {
return null;
}
const lastEventForChallenge = challengeEvents.filter(
event => event.payload.challengeId === challengeId,
)[0];
return (
<Tr key={challengeId}>
<Td>
<Link as={RouteLink} to={`/challenge/${challengeId}`} fontWeight="700" color="teal.500">
{challengeInfo[challengeId].label}
</Link>
</Td>
<Td>
<Link
// Legacy branchUrl
href={lastSubmission.contractUrl || lastSubmission.branchUrl}
color="teal.500"
target="_blank"
rel="noopener noreferrer"
>
Code
</Link>
</Td>
<Td>
<Link
href={lastSubmission.deployedUrl}
color="teal.500"
target="_blank"
rel="noopener noreferrer"
>
Demo
</Link>
</Td>
<Td>
{isLoadingTimestamps ? (
<SkeletonText noOfLines={1} />
) : (
<DateWithTooltip timestamp={lastEventForChallenge?.timestamp} />
)}
</Td>
<Td>
<ChallengeStatusTag
status={lastSubmission.status}
comment={lastSubmission.reviewComment}
autograding={lastSubmission.autograding}
/>
</Td>
</Tr>
);
})}
</Tbody>
</Table>
</Box>
) : (
<Flex
justify="center"
align="center"
borderRadius="lg"
borderColor={borderColor}
borderWidth={1}
py={36}
w="full"
>
{isMyProfile ? (
<Box maxW="xs" textAlign="center">
<Text fontWeight="medium" color={primaryFontColor} mb={2}>
Start a new challenge
</Text>
<Text color={secondaryFontColor} mb={4}>
Show off your skills. Learn everything you need to build on Ethereum!
</Text>
<Button as={RouteLink} colorScheme="blue" to="/">
Start a challenge
</Button>
</Box>
) : (
<Box maxW="xs" textAlign="center">
<Text color={secondaryFontColor} mb={4}>
This builder hasn't completed any challenges.
</Text>
</Box>
)}
</Flex>
))}
</GridItem>
)}
</SimpleGrid>
</Container>
);
}
Example #16
Source File: Header.jsx From scaffold-directory with MIT License | 4 votes |
export default function Header({
injectedProvider,
userRole,
address,
mainnetProvider,
userProvider,
loadWeb3Modal,
logoutOfWeb3Modal,
setUserRole,
}) {
const { secondaryFontColor, borderColor } = useCustomColorModes();
const primaryColorString = useColorModeValue("var(--chakra-colors-gray-700)", "var(--chakra-colors-gray-200)");
const isSignerProviderConnected =
injectedProvider && injectedProvider.getSigner && injectedProvider.getSigner()._isSigner;
const userIsRegistered = userRole && USER_ROLES.anonymous !== userRole;
return (
<Box
borderBottom="1px"
borderColor={borderColor}
mb={10}
px={{ base: 4, lg: 8 }}
h={{ base: userIsRegistered ? "120px" : "80px", lg: "80px" }}
>
{ENVIRONMENT !== "production" && (
<Box pos="fixed" p="2px" fontSize={14} w="100%" bgColor="yellow.200" left={0} textAlign="center">
Working on a {ENVIRONMENT} environment.
</Box>
)}
<Flex
align={{ base: userIsRegistered ? "start" : "center", lg: "center" }}
h="full"
fontWeight="semibold"
pos="relative"
>
<Flex shrink={0} mr={9} mt={{ base: userIsRegistered ? 5 : 0, lg: 0 }}>
<NavLink to="/" exact>
<span role="img" aria-label="castle icon">
?♀️
</span>{" "}
<chakra.strong display={{ base: "none", md: "inline-block" }}>SpeedRunEthereum.com</chakra.strong>
<chakra.strong display={{ base: "inline-block", md: "none" }}>
{isSignerProviderConnected ? "SRE" : "SpeedRunEthereum.com"}
</chakra.strong>
</NavLink>
</Flex>
<HStack
as="ul"
mr={{ base: 0, lg: 6 }}
style={{ listStyle: "none" }}
spacing={{ base: 6, lg: 9 }}
pos={{ base: "absolute", lg: "static" }}
justifyContent={{ base: "center", lg: "left" }}
top="80px"
left={0}
>
{userRole && USER_ROLES.anonymous !== userRole && (
<chakra.li key="/portfolio" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
<NavLink
to="/portfolio"
isActive={(match, location) => location.pathname.includes("/builders/")}
activeStyle={{
color: primaryColorString,
}}
>
Portfolio
</NavLink>
</chakra.li>
)}
{/* ToDo. At least Builder */}
{(USER_ROLES.builder === userRole || USER_ROLES.admin === userRole) && (
<>
<chakra.li key="/builders" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
<NavLink
to="/builders"
exact
activeStyle={{
color: primaryColorString,
}}
>
Builders
</NavLink>
</chakra.li>
</>
)}
{USER_ROLES.admin === userRole && (
<>
<chakra.li key="/submission-review" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
<NavLink
to="/submission-review"
exact
activeStyle={{
color: primaryColorString,
}}
>
Review Submissions
</NavLink>
</chakra.li>
<chakra.li key="/activity" color={secondaryFontColor} _hover={{ color: primaryColorString }}>
<NavLink
to="/activity"
exact
activeStyle={{
color: primaryColorString,
}}
>
Activity
</NavLink>
</chakra.li>
</>
)}
</HStack>
<Spacer />
<Box mt={{ base: userIsRegistered ? 3 : 0, lg: 0 }}>
<Account
address={address}
connectText="Connect Wallet"
ensProvider={mainnetProvider}
isWalletConnected={isSignerProviderConnected}
loadWeb3Modal={loadWeb3Modal}
logoutOfWeb3Modal={() => {
logoutOfWeb3Modal();
setUserRole(null);
}}
setUserRole={setUserRole}
userProvider={userProvider}
userRole={userRole}
/>
</Box>
</Flex>
</Box>
);
}
Example #17
Source File: BuilderProfileCard.jsx From scaffold-directory with MIT License | 4 votes |
BuilderProfileCard = ({ builder, mainnetProvider, isMyProfile, userProvider, fetchBuilder, userRole }) => {
const address = useUserAddress(userProvider);
const ens = useDisplayAddress(mainnetProvider, builder?.id);
const [updatedSocials, setUpdatedSocials] = useState({});
const [isUpdatingReachedOutFlag, setIsUpdatingReachedOutFlag] = useState(false);
const [isUpdatingSocials, setIsUpdatingSocials] = useState(false);
const { isOpen, onOpen, onClose } = useDisclosure();
const { hasCopied, onCopy } = useClipboard(builder?.id);
const { borderColor, secondaryFontColor } = useCustomColorModes();
const shortAddress = ellipsizedAddress(builder?.id);
const hasEns = ens !== shortAddress;
const toast = useToast({ position: "top", isClosable: true });
const toastVariant = useColorModeValue("subtle", "solid");
const joinedDate = new Date(builder?.creationTimestamp);
const joinedDateDisplay = joinedDate.toLocaleString("default", { month: "long" }) + " " + joinedDate.getFullYear();
// INFO: conditional chaining and coalescing didn't work when also checking the length
const hasProfileLinks = builder?.socialLinks ? Object.keys(builder.socialLinks).length !== 0 : false;
const isAdmin = userRole === USER_ROLES.admin;
useEffect(() => {
if (builder) {
setUpdatedSocials(builder.socialLinks ?? {});
}
}, [builder]);
const handleUpdateSocials = async () => {
setIsUpdatingSocials(true);
// Avoid sending socials with empty strings.
const socialLinkCleaned = Object.fromEntries(Object.entries(updatedSocials).filter(([_, value]) => !!value));
const invalidSocials = validateSocials(socialLinkCleaned);
if (invalidSocials.length !== 0) {
toast({
description: `The usernames for the following socials are not correct: ${invalidSocials
.map(([social]) => social)
.join(", ")}`,
status: "error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
let signMessage;
try {
signMessage = await getUpdateSocialsSignMessage(address);
} catch (error) {
toast({
description: " Sorry, the server is overloaded. ???",
status: "error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
let signature;
try {
signature = await userProvider.send("personal_sign", [signMessage, address]);
} catch (error) {
toast({
description: "Couldn't get a signature from the Wallet",
status: "error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
try {
await postUpdateSocials(address, signature, socialLinkCleaned);
} catch (error) {
if (error.status === 401) {
toast({
status: "error",
description: "Access error",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
toast({
status: "error",
description: "Can't update your socials. Please try again.",
variant: toastVariant,
});
setIsUpdatingSocials(false);
return;
}
toast({
description: "Your social links have been updated",
status: "success",
variant: toastVariant,
});
fetchBuilder();
setIsUpdatingSocials(false);
onClose();
};
const handleUpdateReachedOutFlag = async reachedOut => {
setIsUpdatingReachedOutFlag(true);
let signMessage;
try {
signMessage = await getUpdateReachedOutFlagSignMessage(builder.id, reachedOut);
} catch (error) {
toast({
description: " Sorry, the server is overloaded. ???",
status: "error",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
let signature;
try {
signature = await userProvider.send("personal_sign", [signMessage, address]);
} catch (error) {
toast({
description: "Couldn't get a signature from the Wallet",
status: "error",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
try {
await postUpdateReachedOutFlag(address, builder.id, reachedOut, signature);
} catch (error) {
if (error.status === 401) {
toast({
status: "error",
description: "Access error",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
toast({
status: "error",
description: "Can't update the reached out flag. Please try again.",
variant: toastVariant,
});
setIsUpdatingReachedOutFlag(false);
return;
}
toast({
description: 'Updated "reached out" flag successfully',
status: "success",
variant: toastVariant,
});
fetchBuilder();
setIsUpdatingReachedOutFlag(false);
};
return (
<>
<BuilderProfileCardSkeleton isLoaded={!!builder}>
{() => (
/* delay execution */
<Flex
borderRadius="lg"
borderColor={borderColor}
borderWidth={1}
justify={{ base: "space-around", xl: "center" }}
direction={{ base: "row", xl: "column" }}
p={4}
pb={6}
maxW={{ base: "full", lg: "50%", xl: 60 }}
margin="auto"
>
<Link as={RouteLink} to={`/builders/${builder.id}`}>
<QRPunkBlockie
withQr={false}
address={builder.id?.toLowerCase()}
w={52}
borderRadius="lg"
margin="auto"
/>
</Link>
<Flex alignContent="center" direction="column" mt={4}>
{hasEns ? (
<>
<Text fontSize="2xl" fontWeight="bold" textAlign="center">
{ens}
</Text>
<Text textAlign="center" mb={4} color={secondaryFontColor}>
{shortAddress}{" "}
<Tooltip label={hasCopied ? "Copied!" : "Copy"} closeOnClick={false}>
<CopyIcon cursor="pointer" onClick={onCopy} />
</Tooltip>
</Text>
</>
) : (
<Text fontSize="2xl" fontWeight="bold" textAlign="center" mb={8}>
{shortAddress}{" "}
<Tooltip label={hasCopied ? "Copied!" : "Copy"} closeOnClick={false}>
<CopyIcon cursor="pointer" onClick={onCopy} />
</Tooltip>
</Text>
)}
{isAdmin && (
<Center mb={4}>
{builder.reachedOut ? (
<Badge variant="outline" colorScheme="green" alignSelf="center">
Reached Out
</Badge>
) : (
<Button
colorScheme="green"
size="xs"
onClick={() => handleUpdateReachedOutFlag(true)}
isLoading={isUpdatingReachedOutFlag}
alignSelf="center"
>
Mark as reached out
</Button>
)}
</Center>
)}
<Divider mb={6} />
{hasProfileLinks ? (
<Flex mb={4} justifyContent="space-evenly" alignItems="center">
{Object.entries(builder.socialLinks)
.sort(bySocialWeight)
.map(([socialId, socialValue]) => (
<SocialLink id={socialId} value={socialValue} />
))}
</Flex>
) : (
isMyProfile && (
<Alert mb={3} status="warning">
<Text style={{ fontSize: 11 }}>
You haven't set your socials{" "}
<Tooltip label="It's our way of reaching out to you. We could sponsor you an ENS, offer to be part of a build or set up an ETH stream for you.">
<QuestionOutlineIcon />
</Tooltip>
</Text>
</Alert>
)
)}
{isMyProfile && (
<Button mb={3} size="xs" variant="outline" onClick={onOpen}>
Update socials
</Button>
)}
<Text textAlign="center" color={secondaryFontColor}>
Joined {joinedDateDisplay}
</Text>
</Flex>
</Flex>
)}
</BuilderProfileCardSkeleton>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Update your socials</ModalHeader>
<ModalCloseButton />
<ModalBody p={6}>
{Object.entries(socials).map(([socialId, socialData]) => (
<FormControl id="socialId" key={socialId} mb={3}>
<FormLabel htmlFor={socialId} mb={0}>
<strong>{socialData.label}:</strong>
</FormLabel>
<Input
type="text"
name={socialId}
value={updatedSocials[socialId] ?? ""}
placeholder={socialData.placeholder}
onChange={e => {
const value = e.target.value;
setUpdatedSocials(prevSocials => ({
...prevSocials,
[socialId]: value,
}));
}}
/>
</FormControl>
))}
<Button colorScheme="blue" onClick={handleUpdateSocials} isLoading={isUpdatingSocials} isFullWidth mt={4}>
Update
</Button>
</ModalBody>
</ModalContent>
</Modal>
</>
);
}
Example #18
Source File: Blob.js From blobs.app with MIT License | 4 votes |
Blob = ({
size,
isOutline,
type,
svgPath,
color,
colors,
image,
pattern,
}) => {
const ref = useRef(null);
const [imgLoaded, setImgLoaded] = useState(false);
const pattenBgColor = useColorModeValue('#d1d8e0', '#6c7c93');
const props = {
fill: color,
};
if (type === 'gradient') {
props.fill = 'url(#gradient)';
}
if (isOutline) {
props.strokeWidth = '7px';
props.fill = 'none';
props.stroke = color;
}
if (type === 'gradient' && isOutline) {
props.stroke = 'url(#gradient)';
}
if (!svgPath) {
return (
<Flex justify="center" alignItems="center" h="100%">
<Spinner />
</Flex>
);
}
return (
<svg
viewBox={`0 0 ${size} ${size}`}
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
width="100%"
id="blobSvg"
ref={ref}
>
{type === 'solid' && <path id="blob" d={svgPath} {...props} />}
{type === 'gradient' && (
<>
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style={{ stopColor: colors[0] }} />
<stop offset="100%" style={{ stopColor: colors[1] }} />
</linearGradient>
</defs>
<path id="blob" d={svgPath} {...props} />
</>
)}
{type === 'pattern' && (
<>
<defs>
<pattern
id="pattern"
x="0"
y="0"
width={Patterns[pattern].width}
height={Patterns[pattern].height}
patternUnits="userSpaceOnUse"
fill={pattenBgColor}
>
<path d={Patterns[pattern].path} />
</pattern>
</defs>
<path id="blob" d={svgPath} {...props} fill="url(#pattern)" />
</>
)}
{type === 'image' && (
<>
<defs>
<clipPath id="shape">
<path id="blob" d={svgPath} {...props} />
</clipPath>
</defs>
{!imgLoaded && (
<image
x="0"
y="0"
width="100%"
height="100%"
clipPath="url(#shape)"
xlinkHref={LoadingImg}
preserveAspectRatio="none"
/>
)}
<image
x="0"
y="0"
width="100%"
height="100%"
clipPath="url(#shape)"
xlinkHref={image}
preserveAspectRatio="none"
onLoad={() => {
setImgLoaded(true);
}}
/>
</>
)}
</svg>
);
}
Example #19
Source File: index.js From benjamincarlson.io with MIT License | 4 votes |
export default function Index() {
const { colorMode } = useColorMode()
const colorSecondary = {
light: 'gray.600',
dark: 'gray.400'
}
const iconColor = {
light: 'gray.600',
dark: 'gray.300'
}
const linkColor = {
light: 'blue.400',
dark: 'blue.600'
}
return (
<>
<NextSeo
title={title}
description={description}
canonical={url}
openGraph={{
url,
title,
description
}}
/>
<Container>
<Flex
flexDirection="column"
maxWidth="1000px"
alignSelf={[null, "center"]}
>
{/* hero is defined inside of components/Container.js which allows it to have a different bg color without applying p to a bunch of tags */}
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: .7, delay: 2 }}
>
<Box as="section" mt={10} mb={20}>
<Heading letterSpacing="tight" mt={8} size="lg" fontWeight={700} as="h2" mb={4}>About Me</Heading>
<Text color={colorSecondary[colorMode]}>Hi everyone ?, I'm Benjamin Carlson. I go to <Link color="blue.500" href="https://www2.ccsu.edu/" isExternal>Central Connecticut State University</Link> where I study computer science and mathematics. My personal website is where I showcase my projects, writing, statistics, experience, and more. It also serves as a sandbox to play around with new technologies, as seen by the <Link href="https://github.com/bjcarlson42/benjamincarlson.io#overview" color={linkColor[colorMode]} isExternal>evolution</Link> of this website! Feel free to reach out via email or any social media.</Text>
</Box>
<Box as="section" mt={10} mb={20}>
<Heading letterSpacing="tight" mt={8} size="lg" fontWeight={700} as="h2" mb={4}>Featured Projects ??</Heading>
<SimpleGrid minChildWidth="300px" spacing="40px">
<ProjectCard
title="coffeeclass.io"
description="coffeeclass.io is a tutorial website I started to teach programming and computer science skills in a fun and easy to learn manner."
repoHref="https://github.com/carlson-technologies/coffeeclass.io"
demoHref="https://www.coffeeclass.io?utm_source=website&utm_campaign=benjamincarlson.io"
languageColor="#2b7489"
language="TypeScript"
/>
<ProjectCard
title="benjamincarlson.io"
description="This website is a personal website I built to showcase my projects and experience."
repoHref="https://github.com/bjcarlson42/benjamincarlson.io"
demoHref="https://benjamincarlson.io"
languageColor="#f1e05a"
language="JavaScript"
/>
<ProjectCard
title="Word Of The Day App"
description="A word of the day app built using Google's Flutter - a cross platform mobile app framework. View current and past words and save your favorites!"
repoHref="https://github.com/bjcarlson42/wotd"
youtubeId="https://youtu.be/17wMTF_bnnc"
languageColor="#00B4AB"
language="Dart"
/>
</SimpleGrid>
</Box>
<Box as="section" mt={10} mb={20}>
<Heading letterSpacing="tight" mt={8} mb={4} size="lg" fontWeight={700} as="h2">Publications ?</Heading>
<Text color={colorSecondary[colorMode]}>I began writing about programming back in 2019 on my first blog that is no longer alive. Since then I have expanded to different media outlets and covered a variety of topics from programming, to productivity, to business.</Text>
{/* <Flex align="center" mt={4}> */}
<SimpleGrid minChildWidth="200px" spacing="20px" my={10}>
<Flex flexDir="column">
<Icon as={YoutubeIcon} color="red.500" fontSize="2xl" mb={2} />
<Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
<Link href='https://youtube.com/benjamincarlson' color={linkColor[colorMode]} isExternal>YouTube</Link>
</Heading>
<Text>I started uploading YouTube videos in 2020 when the pandemic started. I mostly upload programming tutorial videos but I also upload developer vlogs and informational videos. I have uploaded (almost) weekly since then and have grown my channel to an audience of over 4k subscribers and 450k views!</Text>
</Flex>
<Flex flexDir="column">
<Icon as={SiMedium} fontSize="2xl" mb={2} />
<Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
<Link href='https://benjamincarlson.medium.com' color={linkColor[colorMode]} isExternal>Medium</Link>
</Heading>
<Text>Medium was the first publication I started. I wrote my <Link color="blue.500" href="https://levelup.gitconnected.com/using-javascript-to-scramble-a-rubiks-cube-306f52908f18" isExternal>first article</Link> in March 2020, and since then I have written about a dozen more articles. Nowadays I write less for Medium and more for coffeeclass.io.</Text>
</Flex>
<Flex flexDir="column">
<Icon as={FiCoffee} color="yellow.500" fontSize="2xl" mb={2} />
<Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
<Link href='https://www.coffeeclass.io' color={linkColor[colorMode]} isExternal>coffeeclass.io</Link>
</Heading>
<Text>Because I enjoyed uploading YouTube videos about programming and writing about programming on Medium, I decided to start my own programming tutorial website, coffeeclass.io. If you are interested in writing about code, see our <Link color="blue.500" href="https://www.coffeeclass.io/contribute/getting-started" isExternal>getting started</Link> page.</Text>
</Flex>
<Flex flexDir="column">
<Icon as={BsGear} color="gray.500" fontSize="2xl" mb={2} />
<Heading as="h3" size="md" fontWeight={400} mb={2} letterSpacing="tight">
<Link href='https://www.engineering.coffeeclass.io' color={linkColor[colorMode]} isExternal>engineering.coffeeclass.io</Link>
</Heading>
<Text>The behind the scenes look at coffeeclass.io. On this site I write about the development of coffeeclass.io. Everything from the current tech stack, future plans, growing pains, and more.</Text>
</Flex>
</SimpleGrid>
{/* </Flex> */}
<Flex
mb={4}
bgColor={useColorModeValue("gray.100", "gray.900")}
p={[5, 20, 50]}
borderRadius={3}
as="blockquote"
borderLeft="10px solid"
borderLeftColor={useColorModeValue("blue.400", "blue.700")}
>
<Icon as={GrBlockQuote} fontSize={40} color={colorSecondary[colorMode]} mr={4} />
<Flex flexDir="column">
<Text fontSize="xl" fontStyle="italic" color={colorSecondary[colorMode]}>If You Can Think and Speak and Write, You Are Absolutely Deadly.</Text>
<Text fontSize="xl" fontWeight="bold" mt={2}>Jordan B. Peterson</Text>
</Flex>
</Flex>
</Box>
<Todo />
<TechStack />
<Box as="section">
<Text mt={10}>Looks like you've made it to the end of this page... feel free to <Link href="https://youtube.com/benjamincarlson" isExternal color={linkColor[colorMode]}>check out my YouTube channel</Link> or
visit <Link href="https://www.coffeeclass.io/?utm_source=website&utm_campaign=benjamincarlson.io" isExternal color={linkColor[colorMode]}>coffeeclass.io</Link> where
you can find even more programming content.
</Text>
</Box>
</motion.div>
</Flex>
</Container>
</>
)
}
Example #20
Source File: Todo.js From benjamincarlson.io with MIT License | 4 votes |
Todo = () => {
const toast = useToast()
const { colorMode } = useColorMode()
const { isOpen, onOpen, onClose } = useDisclosure()
const colorSecondary = {
light: 'gray.600',
dark: 'gray.400',
}
const borderColor = {
light: 'gray.200',
dark: 'gray.600',
}
const colorSmall = {
light: 'gray.400',
dark: 'gray.600',
}
const myTodos = [
{
completed: false,
title: 'Improve Final Cut Pro skills ?',
},
{
completed: false,
title: 'Finish my degree ?',
},
{
completed: false,
title: 'Grow my YouTube channel ?',
},
{
completed: false,
title: 'Grow coffeeclass.io ☕',
},
]
const [todos, setTodos] = useState(myTodos)
const [input, setInput] = useState('')
const removeTodo = todo => {
setTodos(todos.filter(t => t !== todo))
}
const toggleCompleted = todo => {
todo.completed = !todo.completed
setTodos([...todos])
}
const addTodo = () => {
setTodos(todos.concat({
completed: false,
title: input,
}))
setInput('')
}
return (
<>
<Box as="section" w="100%" mt={10} mb={20}>
<Stack spacing={4} w="100%">
<Heading letterSpacing="tight" size="lg" fontWeight={700} as="h2">Todo List ?</Heading>
<Text color={colorSecondary[colorMode]}>Here is a list of things I plan to accomplish over the next year. Try it out yourself!</Text>
<InputGroup size="md" mt={4} borderColor="gray.500" borderColor={borderColor[colorMode]}>
<InputLeftElement
pointerEvents="none"
children={<Search2Icon color={useColorModeValue("gray.500", "gray.600")} />}
/>
<Input
aria-label="Enter a Todo!"
placeholder="Improve Python skills ?"
value={input}
onChange={e => setInput(e.target.value)}
/>
<InputRightElement width="6.75rem">
<Button
aria-label="Add a TODO!"
fontWeight="bold"
h="1.75rem"
size="md"
colorScheme="gray"
mr={2}
variant="outline"
px={10}
onClick={() => {
if (input == '')
toast({
title: 'Whoops! There\'s an error!',
description: "Input can't be empty!",
status: "error",
duration: 2000,
isClosable: true,
})
else {
addTodo(input)
}
}}
>
Add Todo!
</Button>
</InputRightElement>
</InputGroup>
<Flex flexDir="column">
{todos.map((todo, index) => (
<Flex
key={index}
justify="space-between"
align="center"
my={1}
>
<Flex align="center">
<Icon fontSize="xl" mr={2} as={ChevronRightIcon} color={colorSecondary[colorMode]} />
<Tooltip label={`Click "${todo.title}" to mark as completed.`} placement="top" hasArrow>
<Text color={colorSecondary[colorMode]} textDecor={todo.completed && "line-through"} _hover={{ cursor: 'pointer' }} onClick={() => toggleCompleted(todo)}>{todo.title}</Text>
</Tooltip>
</Flex>
<Tooltip label={`Delete "${todo.title}"`} placement="top" hasArrow>
<IconButton aria-label={`Delete "${todo.title}" from Todo list.`} icon={<DeleteIcon color="red.400" />} onClick={() => removeTodo(todo)} />
</Tooltip>
</Flex>
))}
</Flex>
<Flex align="center">
<Text onClick={() => setTodos(myTodos)} _hover={{ cursor: 'pointer' }} color={colorSmall[colorMode]}>Reset</Text>
<Divider orientation="vertical" mx={2} h={4} />
<Text onClick={onOpen} _hover={{ cursor: 'pointer' }} color={colorSmall[colorMode]}>Help</Text>
</Flex>
</Stack>
</Box>
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Todo List Help</ModalHeader>
<ModalCloseButton />
<ModalBody>
<OrderedList>
<ListItem>
<Text fontWeight="bold">Add a Todo</Text>
<Text>Input your Todo and click the "Add Todo!" button to add a new Todo.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">Reset</Text>
<Text>Click the "Reset" button to reset the list.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">Delete</Text>
<Text>Click the "Delete" button to delete a Todo.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">Completed</Text>
<Text>Click a Todo to mark it as completed.</Text>
</ListItem>
<ListItem>
<Text fontWeight="bold">View Code</Text>
<Text>Click the "View Code" button to view the code on GitHub for this simple TODO list.</Text>
</ListItem>
</OrderedList>
<Divider my={6} />
<Text><strong>Current state of Todo List:</strong> [{todos.map(t => { return `{"${t.title}",${t.completed}},` })}]</Text>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
<Link
href="https://github.com/bjcarlson42/benjamincarlson.io/blob/master/components/Todo.js"
_hover={{ textDecor: 'none' }}
isExternal
>
<Button variant="ghost">View Code</Button>
</Link>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}
Example #21
Source File: Navigation.js From benjamincarlson.io with MIT License | 4 votes |
Navigation = () => {
const router = useRouter()
return (
<Flex
justify="center"
flexDirection="row"
minWidth="356px"
width="100%"
bgColor={useColorModeValue("rgb(248, 250, 252)", "gray.900")}
as="nav"
px={4}
py={2}
pos="sticky"
zIndex={10}
top={0}
>
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: .7 }}
>
<Box maxWidth="1200px">
<DarkModeSwitch />
<NextLink href="/statistics" passHref>
<Button
as="a"
variant="ghost"
p={[1, 2, 4]}
_hover={{ backgroundColor: useColorModeValue("gray.100", "gray.700") }}
fontWeight={router.pathname === '/statistics' ? "bold" : "normal"}
color={router.pathname === '/statistics' ? useColorModeValue("blue.500", "blue.700") : useColorModeValue("#000000", "#ffffff")}
aria-label="Statistics"
>
Statistics
</Button>
</NextLink>
<NextLink href="/blog" passHref>
<Button
as="a"
variant="ghost"
p={[1, 2, 4]}
fontWeight={router.pathname.includes('/blog') ? "bold" : "normal"}
color={router.pathname.includes('/blog') ? useColorModeValue("blue.500", "blue.700") : useColorModeValue("#000000", "#ffffff")}
aria-label="Blog"
>
Blog
</Button>
</NextLink>
<NextLink href="/projects" passHref>
<Button
as="a"
variant="ghost"
p={[1, 2, 4]}
fontWeight={router.pathname === '/projects' ? "bold" : "normal"}
color={router.pathname === '/projects' ? useColorModeValue("blue.500", "blue.700") : useColorModeValue("#000000", "#ffffff")}
aria-label="Projects"
>
Projects
</Button>
</NextLink>
<NextLink href="/gear" passHref>
<Button
as="a"
variant="ghost"
p={[1, 2, 4]}
fontWeight={router.pathname === '/gear' ? "bold" : "normal"}
color={router.pathname === '/gear' ? useColorModeValue("blue.500", "blue.700") : useColorModeValue("#000000", "#ffffff")}
aria-label="Gear"
>
Gear
</Button>
</NextLink>
<NextLink href="/" passHref>
<Button
as="a"
variant="ghost"
p={[1, 2, 4]}
fontWeight={router.pathname === '/' ? "bold" : "normal"}
color={router.pathname === '/' ? useColorModeValue("blue.500", "blue.700") : useColorModeValue("#000000", "#ffffff")}
aria-label="Home"
>
Home
</Button>
</NextLink>
</Box>
</motion.div>
</Flex>
)
}
Example #22
Source File: Hero.js From benjamincarlson.io with MIT License | 4 votes |
export default function Hero() {
return (
<Box bgColor={useColorModeValue("rgb(248, 250, 252)", "gray.900")}>
<Flex
w="100%"
flexDir={["column", "column", "row"]}
align="center"
px={4}
mt={[8, 8, 16]}
mb={8}
maxW="1200px"
mx="auto"
>
<Flex flexDir="column" w={["100%", "100%", "50%"]} mr={[0, 0, 4]}>
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: .7, delay: .4 }}
>
<Heading
letterSpacing="tight"
mb={4}
as="h1"
size="xl"
fontWeight={700}
>
Hello! I'm Benjamin Carlson -
</Heading>
</motion.div>
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: .7, delay: .8 }}
>
<Text
fontSize="xl"
color={useColorModeValue("gray.600", "gray.500")}
mb={6}
>
A <strong>software engineer ??</strong>, <strong>creator ?</strong>, and <strong>student ??</strong> living and working in CT. You've stumbled onto my online portfolio, resume, blog, and all things in between.
</Text>
</motion.div>
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: .7, delay: 1.2 }}
>
<Flex flexDir={["column", "row", "row"]}>
<Link href="https://youtube.com/benjamincarlson" _hover={{ textDecor: 'none' }} w={["100%", "100%", null]} mr={[0, 2, 2]} mb={[2, 0, 0]} isExternal>
<Button
w={["100%", "100%", null]}
colorScheme="red"
size="md"
rightIcon={<YoutubeIcon fontSize="xl" />}
boxShadow={useColorModeValue("0px 8px 26px rgba(0, 0, 0, 0.2)", "0px 8px 26px rgba(0, 0, 0, 0.7)")}
_hover={{ transform: "translateY(-2px)", opacity: .85, bgColor: useColorModeValue("red.400", "red.500") }}
>
Visit my YouTube
</Button>
</Link>
<Link href="https://github.com/sponsors/bjcarlson42" _hover={{ textDecor: 'none' }} w={["100%", "100%", null]} isExternal>
<Button
w={["100%", "100%", null]}
colorScheme="gray"
variant="outline"
size="md"
rightIcon={<GitHubIcon fontSize="xl" />}
boxShadow={useColorModeValue("0px 8px 26px rgba(0, 0, 0, 0.2)", "0px 8px 26px rgba(0, 0, 0, 0.7)")}
_hover={{ transform: "translateY(-2px)", bgColor: useColorModeValue("gray.100", "gray.800") }}
>
Sponsor me on GitHub
</Button>
</Link>
</Flex>
</motion.div>
</Flex>
<Box mt={[10, 10, 0]} w={["100%", "100%", "50%"]}>
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: .7, delay: 1.6 }}
>
<AspectRatio ratio={16 / 9}>
<iframe src="https://www.youtube.com/embed/uNKBWrkMO_Q" alt="Featured YouTube video" allowFullScreen={true} style={{ borderRadius: 10 }} />
</AspectRatio>
</motion.div>
</Box>
</Flex>
</Box>
)
}
Example #23
Source File: Footer.js From benjamincarlson.io with MIT License | 4 votes |
Footer = () => {
const { colorMode } = useColorMode()
const borderIcon = {
light: 'gray.400',
dark: 'gray.500'
}
const footerHoverBg = {
light: 'gray.100',
dark: 'gray.700',
}
return (
<Box bgColor={useColorModeValue("rgb(248, 250, 252)", "gray.900")} mt={4}>
<Flex
align="center"
my={4}
direction="column"
>
<div>
<Link href="https://twitter.com/bjmncrlsn" title="Twitter" isExternal>
<IconButton
aria-label="Twitter"
icon={<FiTwitter />}
size="lg"
color={borderIcon[colorMode]}
variant="ghost"
_hover={{ backgroundColor: footerHoverBg[colorMode] }}
/>
</Link>
<Link href="https://github.com/bjcarlson42" title="GitHub" isExternal>
<IconButton
aria-label="GitHub"
icon={<FiGithub />}
size="lg"
color={borderIcon[colorMode]}
variant="ghost"
_hover={{ backgroundColor: footerHoverBg[colorMode] }}
/>
</Link>
<Link
href="https://www.linkedin.com/in/bjcarlson42"
title="LinkedIn"
isExternal
>
<IconButton
aria-label="LinkedIn"
icon={<FiLinkedin />}
size="lg"
color={borderIcon[colorMode]}
variant="ghost"
_hover={{ backgroundColor: footerHoverBg[colorMode] }}
/>
</Link>
<Link
href="https://www.youtube.com/benjamincarlson"
title="YouTube"
isExternal
>
<IconButton
aria-label="YouTube"
icon={<FiYoutube />}
size="lg"
color={borderIcon[colorMode]}
variant="ghost"
_hover={{ backgroundColor: footerHoverBg[colorMode] }}
/>
</Link>
<Link href="mailto:[email protected]" title="Email" isExternal>
<IconButton
aria-label="Email"
icon={<FiMail />}
size="lg"
color={borderIcon[colorMode]}
variant="ghost"
_hover={{ backgroundColor: footerHoverBg[colorMode] }}
/>
</Link>
</div>
</Flex>
</Box>
)
}