Skip to content

Commit

Permalink
Merge pull request #45 from NabilNYMansour/newLanding
Browse files Browse the repository at this point in the history
New landing
  • Loading branch information
NabilNYMansour authored Aug 31, 2024
2 parents cb2b14f + c1af1b0 commit f8264a6
Show file tree
Hide file tree
Showing 30 changed files with 546 additions and 227 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
username: ${{ secrets.SSH_USERNAME }}
# Will assume basic setup has been done on the server
script: |
pm2 stop all
cd excalihub
git pull
export NVM_DIR=~/.nvm
Expand Down
1 change: 1 addition & 0 deletions src/app/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default function Error({ error, reset }: {
</Text>
<Group justify="center">
<Button variant='white'
style={{ transition: "all 0.2s" }}
size="md"
onClick={
() => reset()
Expand Down
1 change: 0 additions & 1 deletion src/app/landing/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { MAIN_URL } from "@/lib/constants";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Landing",
alternates: {
canonical: `${MAIN_URL}/landing`,
}
Expand Down
41 changes: 37 additions & 4 deletions src/app/landing/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,45 @@
}
}

.drawing footer [class*="App-toolbar"] {
border: 5px solid red;
.drawing div [class*="mobile-misc-tools-container"] {
display: none;
}

.drawing {
pointer-events: none;
animation: fadeIn 0.25s ease-in-out;
}
}

@-webkit-keyframes gradient {
0% {
background-position: 0 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
@keyframes gradient {
0% {
background-position: 0 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}

/* .hero {
background: linear-gradient(
62deg,
var(--mantine-color-main-filled),
var(--mantine-color-main-light),
var(--mantine-color-main-light),
var(--mantine-color-main-filled)
);
animation: gradient 30s ease infinite;
background-size: 400% 400%;
} */
127 changes: 38 additions & 89 deletions src/app/landing/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
"use client";

import { Button, Container, Text, Timeline } from '@mantine/core';
import { FaQuestionCircle } from 'react-icons/fa';
import CoolButton from '@/app/ui/components/buttons/CoolButton';
import { RiLinkM } from 'react-icons/ri';
import { Box, Divider, Flex, Group } from '@mantine/core';
import { useMediaQuery } from '@mantine/hooks';
import { Skeleton, useComputedColorScheme } from "@mantine/core";
import dynamic from "next/dynamic";
import CenterContainer from '@/app/ui/components/other/CenterContainer';
import classes from './page.module.css';
import { WELCOME_EXCALI_DATA } from '@/lib/constants';
import cx from 'clsx';
import { FeaturesCards } from '../ui/components/landing/FeaturesCards';
import LandingHero from '../ui/components/landing/LandingHero';
import Faq from '../ui/components/landing/Faq';

const Excalidraw = dynamic(
async () => (await import("@excalidraw/excalidraw")).Excalidraw,
Expand All @@ -20,98 +18,49 @@ const Excalidraw = dynamic(
},
);

function LandingExcalidraw({ isPhone }: { isPhone: boolean | undefined }) {
function LandingExcalidraw() {
const computedColorScheme = useComputedColorScheme('light', { getInitialValueInEffect: true });
const isSmallScreen = useMediaQuery('(max-width: 1300px)');

return (
<div
className={classes.drawing}
style={{ width: "100%", height: "35vh", borderRadius: "12px", overflow: "hidden", marginTop: "25px" }}>
<Excalidraw theme={computedColorScheme}
UIOptions={{ tools: { image: false } }}
initialData={{
elements: WELCOME_EXCALI_DATA.elements as any,
scrollToContent: true,
appState: { zoom: { value: (isPhone ? .5 : 1) as any } }
}} zenModeEnabled viewModeEnabled />
</div>
<Flex direction="column" justify="center" align="stretch"
w={1000} p={20}>
<div
className={classes.drawing}
style={{ width: "100%", height: isSmallScreen ? 300 : 650, borderRadius: "1.0rem", overflow: "hidden", marginTop: "25px" }}>
<Excalidraw theme={computedColorScheme}
UIOptions={{ tools: { image: false } }}
initialData={{
elements: WELCOME_EXCALI_DATA.elements as any,
scrollToContent: true,
appState: { zoom: { value: (isSmallScreen ? .5 : 1) as any } }
}} zenModeEnabled />
</div>
</Flex>
);
}

const myWebsiteLink = <Button
component='a'
href='https://nabilmansour.com'
target='_blank'
size='xs' p={1}
variant='light'
leftSection={<RiLinkM size={28} />}>
<Text fw={900} span size='1.5rem'>Website</Text>
</Button>
const Page = () => {
return <Flex direction="column" w="100%" align="center">

const LandingPageComponent = () => {
const isPhone = useMediaQuery('(max-width: 650px)');
{/* <Divider my="md" size="xs" w="70%" variant='dashed'
color="var(--mantine-color-main-filled)"
pos="absolute" top="100px" left="0" /> */}

return (
<CenterContainer size="md">
<LandingExcalidraw isPhone={isPhone} />
<CoolButton href='/excalidraw' text='Try the Demo' style={{
backgroundImage: "linear-gradient(180deg, #ffd034, #b6871d)",
fontSize: "1.5rem", fontWeight: "900",
}} />
<Container size="sm">
<Timeline active={100} lineWidth={3} bulletSize={40}>
<Timeline.Item bullet={<FaQuestionCircle size={28} />} title={<h2>What is Excalihub?</h2>}>
<p>Excalihub is a platform for creating and sharing Excalidraw drawings. You can create, save, and share multiple drawings for free.</p>
<p>To start, you just need to:</p>
<CoolButton href='/sign-up' text='Sign up'
style={{ backgroundImage: "linear-gradient(180deg, #6965DB, #908cff)", fontSize: "1.5rem", fontWeight: "900" }} />
<p>Or if you already have an account:</p>
<CoolButton href='/sign-in' text='Sign in'
style={{ backgroundImage: "linear-gradient(180deg, #6965DB, #908cff)", fontSize: "1rem", fontWeight: "900" }} />
</Timeline.Item>
<Timeline.Item bullet={<div style={{ scale: "2.5" }}>🤔</div>} title={<h2>Why?</h2>}>
<p>I find Excalidraw useful but the free version doesn&apos;t let you have multiple saved drawings. So I thought I could make that myself.</p>
</Timeline.Item>
<Timeline.Item bullet={<div style={{ scale: "2.5" }}>😮</div>} title={<h2>Oh so you are part of the Excali team?</h2>}>
<Text size='1.75rem' fw={900} c="#ff0000" span>Nope :D </Text>
<span>But I would like to be...</span>
</Timeline.Item>
<Timeline.Item bullet={<div style={{ scale: "2.5" }}>👨‍💻</div>} title={<h2>So who are you?</h2>}>
<p>Just a guy. You can know more about me on my <span>
{myWebsiteLink}
</span></p>
<p>One thing to note is that I am self-hosting this site. So if you find it useful consider to</p>
<CoolButton
href="https://buymeacoffee.com/nabilmansour"
text="☕️ Buy me coffee ツ"
target='_blank'
style={{
borderRadius: "100px",
backgroundColor: "var(--mantine-color-main-filled)",
textAlign: "center",
fontSize: isPhone ? "1.25rem" : "2.5rem",
fontWeight: 900,
}}
/>
</Timeline.Item>
<Timeline.Item bullet={<div style={{ scale: "2.5" }}>🧐</div>} title={<h2>Are you trying to replace Excalidraw?</h2>}>
<p>Of course not. I am making this for myself but would probably use Excalidraw if I want all the fancy features.
This is just to have multiple drawings saved in one place.
I recommend using the <a target='_blank' href='https://plus.excalidraw.com/'>
original Excalidraw platform if you want the other features</a>.</p>
</Timeline.Item>
<Timeline.Item bullet={<div style={{ scale: "3.5" }}>🥼</div>} title={<h2>Feedback</h2>}>
<p>If you have any feedback or suggestions, feel free to reach out to me on my {myWebsiteLink}
</p>
</Timeline.Item>
</Timeline>
</Container>
</CenterContainer>
);
};
<Flex wrap="wrap" w="100%" mih={900} justify="center" align="center">
<LandingHero />
<LandingExcalidraw />
</Flex>

const Page = () => {
return <LandingPageComponent />;
<Flex bg="var(--mantine-color-main-light)"
wrap="wrap" w="100%" justify="center" align="center">
<FeaturesCards />
</Flex>

<Flex wrap="wrap" w="100%" justify="center" align="center" id='faq'>
<Faq />
</Flex>
</Flex>
};

export default Page;
18 changes: 17 additions & 1 deletion src/app/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@
}
}

@keyframes shake {
0% {
transform: translate(2px, 0);
}
10% {
transform: translate(-2px, 0);
}
15% {
transform: translate(0, 0);
}
}

.slideUp {
animation: slideUp 0.25s ease-in-out;
}
}

.buymecoffee {
animation: slideUp 0.25s ease-in-out, shake 1500ms infinite linear;
}
15 changes: 11 additions & 4 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import DrawingCard from "./ui/components/cards/DrawingCard";
import PaginationControls from "./ui/components/other/PaginationControls";
import UserBeingProcessed from "./ui/components/other/UserBeingProcessed";
import classes from "./page.module.css";
import ActionButtons from "./ui/components/buttons/ActionButtons";

async function HomePageComponent({ searchParams, name, clerkId }: { searchParams: SearchParams, name: string | null, clerkId: string | null }) {
if (!name || !clerkId) throw new Error("User not found");
if (!name || !clerkId) return <UserBeingProcessed />;

const userIdQuery = await getUserIdByClerkId(clerkId);
if (userIdQuery.length > 0) {
Expand All @@ -27,10 +28,16 @@ async function HomePageComponent({ searchParams, name, clerkId }: { searchParams

return (
<CenterContainer size="xl">
<Flex direction="column" align="center" h="100%" w="100%" >
<Text p={25}>Hi {name}! 👋</Text>
<Flex direction="column" align="center" h="100%" w="100%" className={classes.slideUp}>

<Card className={classes.slideUp} shadow="xs" padding="md" radius="md" w="100%" maw={1108}>
<Flex w="100%" maw={1108} py={15} px={16} align="center" justify="space-between">
<Text>Hi {name}! 👋</Text>
<ActionButtons/>
</Flex>

<Card
shadow="xs" radius="md" w="100%" maw={1108}
bg="light-dark(#fff, #313036)">
<Flex direction="column" gap={10} w="100%">

{/*=============Search and new drawing=============*/}
Expand Down
2 changes: 1 addition & 1 deletion src/app/terms/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const Page = () => {
<p>Excalihub is a public platform. As such, all the drawings and content you share as &quot;Public&quot; becomes visible to everybody. In particular,</p>
<ul>
<li>
Content shared as <b>&quot;Public&quot;</b> is visible to anyone and will contain the title, description and username of its creator. It is also indexed by search engines.
Content shared as <b>&quot;Public&quot;</b> is visible to anyone and will contain the title, description and username of its creator.
</li>
<li>
Content kept as <b>&quot;Private&quot;</b> is not shared with anybody, as described below in the Privacy Policy.
Expand Down
38 changes: 38 additions & 0 deletions src/app/ui/components/buttons/ActionButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client";

import { ActionIcon, Button, Group } from "@mantine/core";
import { useMediaQuery } from "@mantine/hooks";
import { FaGithub } from "react-icons/fa6";
import { SiBuymeacoffee } from "react-icons/si";

export default function ActionButtons() {
const isSmallScreen = useMediaQuery('(max-width: 750px)');

if (isSmallScreen) {
return <Group gap={10} justify="flex-end">
<ActionIcon size="lg" radius="md" color="gray"
component="a" href="https://github.com/NabilNYMansour/excalihub" target="_blank">
<FaGithub size={20} />
</ActionIcon>
<ActionIcon size="lg" radius="md" color="green"
component="a" href="https://buymeacoffee.com/nabilmansour" target="_blank">
<SiBuymeacoffee size={20} />
</ActionIcon>
</Group>
} else {
return <Group gap={10}>
<Button style={{ transition: "all 0.2s" }}
radius="md" color="gray"
component="a" href="https://github.com/NabilNYMansour/excalihub" target="_blank"
rightSection={<FaGithub size={20} />}>
Contribute on GitHub
</Button>
<Button style={{ transition: "all 0.2s" }}
radius="md" color="green"
component="a" href="https://buymeacoffee.com/nabilmansour" target="_blank"
rightSection={<SiBuymeacoffee size={20} />}>
Support the project
</Button>
</Group>
}
}
18 changes: 9 additions & 9 deletions src/app/ui/components/buttons/CoolButton.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

.butn:link,
.butn:visited {
display: inline-flex;
Expand All @@ -10,11 +9,11 @@
margin-right: 13px;
border-radius: 4px;
border: none;
color: #fff;
position: relative;
overflow: hidden;
transition: all 0.3s ease-in-out;
border: 1px solid transparent;
transition: all 0.75s ease-in-out;
background-color: black;
color: #fff;
}
.butn::after {
background: #fff;
Expand All @@ -39,19 +38,20 @@
transform: translateY(-3px);
color: #fff;
/* box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.3); */
border: 1px solid white;
box-shadow: 0 0 10px white;
box-shadow: 0px 0px 20px 0px var(--mantine-color-main-filled);
background-color: var(--mantine-color-main-filled);
transition: all 0.3s ease-in-out;
}

.butn__new:hover::before {
left: 120%;
opacity: 0.5s;
opacity: 0.7;
}

.butn__new:hover::after {
left: 200%;
opacity: 0.6;
opacity: 1;
}
.butn span {
z-index: 20;
}
}
7 changes: 4 additions & 3 deletions src/app/ui/components/buttons/CoolButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { CSSProperties } from "react";
import classes from "./CoolButton.module.css";
import cx from "clsx";

const CoolButton = ({ href, text, style, target }: { href: string, text: string, style?: CSSProperties, target?: string }) => {
const CoolButton = ({ href, children, style, target }: { href: string, children?: React.ReactNode, style?: CSSProperties, target?: string }) => {
return (
<div>
<a style={style} href={href} target={target} className={cx(classes.butn, classes.butn__new)}>
<span>{text}</span>
<a style={style} href={href} target={target}
className={cx(classes.butn, classes.butn__new)}>
<span>{children}</span>
</a>
</div>
);
Expand Down
Loading

0 comments on commit f8264a6

Please sign in to comment.