-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29 from pierobassa/feat-new-homepage
feat(homepage): add landing page, refactor connected profile card
- Loading branch information
Showing
17 changed files
with
265 additions
and
150 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
"use client"; | ||
|
||
import { useAccountStore } from "@/store"; | ||
import Image from "next/image"; | ||
import { ConnectedAccountProfileCard, Loader } from "@/components"; | ||
import { useCallback } from "react"; | ||
import { FormattingUtils } from "@/utils"; | ||
import { DEFUALT_USER_IMG_PLACEHOLDER } from "@/constants"; | ||
import { useActiveProfile } from "@lens-protocol/react-web"; | ||
import { WithLensContext } from "@/providers"; | ||
//eslint-disable-next-line | ||
const RubyRingHero = require("@/assets/ruby_ring_hero.png"); | ||
|
||
export default function HomepageComponent() { | ||
const { socialAccountLoading, smartAccountAddress } = useAccountStore(); | ||
|
||
return ( | ||
<section className="bg-[#170c10] text-white"> | ||
<div className="mx-auto max-w-screen-xl px-4 py-4 lg:flex lg:h-screen"> | ||
<div className="mx-auto max-w-3xl text-center mt-32"> | ||
{!socialAccountLoading && !smartAccountAddress && ( | ||
<> | ||
<Image | ||
className="h-72 w-auto mx-auto" | ||
src={RubyRingHero} | ||
alt="Your Company" | ||
/> | ||
<h1 className="bg-gradient-to-r from-red-300 via-rose-700-500 to-pink-600 bg-clip-text text-3xl font-extrabold text-transparent sm:text-5xl"> | ||
Pave the Path to | ||
<span className="sm:block"> Exclusive Interactions! </span> | ||
</h1> | ||
<p className="mx-auto mt-4 max-w-xl sm:text-xl/relaxed"> | ||
Dive into unique social circles of your beloved personas. With | ||
RubyRing, every interaction is a gem of an experience. | ||
</p> | ||
</> | ||
)} | ||
|
||
{socialAccountLoading && !smartAccountAddress && ( | ||
<div | ||
style={{ | ||
display: "flex", | ||
alignItems: "center", | ||
justifyContent: "center", | ||
height: "80vh" | ||
}} | ||
> | ||
<Loader /> | ||
</div> | ||
)} | ||
{smartAccountAddress && ( | ||
<WithLensContext | ||
Component={ | ||
<ConnectedProfile smartAccountAddress={smartAccountAddress} /> | ||
} | ||
/> | ||
)} | ||
</div> | ||
</div> | ||
</section> | ||
); | ||
} | ||
|
||
type ConnectedProfileProps = { | ||
smartAccountAddress: string; | ||
}; | ||
const ConnectedProfile: React.FC<ConnectedProfileProps> = ({ | ||
smartAccountAddress | ||
}) => { | ||
const { data: activeProfile } = useActiveProfile(); | ||
const getProfilePicture = useCallback(() => { | ||
if (!activeProfile) return DEFUALT_USER_IMG_PLACEHOLDER; | ||
if (activeProfile.picture?.__typename === "MediaSet") { | ||
const ipfsUrl = FormattingUtils.ipfsUriToHttps( | ||
activeProfile.picture.original.url | ||
); | ||
return ipfsUrl ?? activeProfile.picture.original.url; | ||
} else { | ||
return DEFUALT_USER_IMG_PLACEHOLDER; | ||
} | ||
}, [activeProfile]); | ||
|
||
return ( | ||
<div> | ||
<div className="font-bold text-xl py-3">Your account</div> | ||
<ConnectedAccountProfileCard | ||
profileImage={getProfilePicture()} | ||
profileHandle={activeProfile?.handle ?? ""} | ||
smartAccountAddress={smartAccountAddress} | ||
/> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./Homepage"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
src/components/Lens/ConnectedAccountProfileCard/ConnectedAccountProfileCard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { FormattingUtils } from "@/utils"; | ||
import { FaGem } from "react-icons/fa"; | ||
|
||
type Props = { | ||
profileImage: string; | ||
profileHandle: string; | ||
smartAccountAddress: string; | ||
}; | ||
|
||
export const ConnectedAccountProfileCard = ({ | ||
profileImage, | ||
profileHandle, | ||
smartAccountAddress | ||
}: Props) => { | ||
return ( | ||
<section className="w-64 mx-auto bg-stone-800 rounded-2xl px-8 py-6 shadow-lg shadow-stone-950"> | ||
<div className="flex items-center justify-between"> | ||
<span className="text-gray-400 text-sm">Ruby Ring member</span> | ||
<span className="text-[#ff89a9]"> | ||
<FaGem /> | ||
</span> | ||
</div> | ||
<div className="mt-6 w-fit mx-auto"> | ||
<img | ||
src={profileImage} | ||
className="rounded-full w-28 " | ||
alt="profile picture" | ||
/> | ||
</div> | ||
|
||
<div className="mt-8 "> | ||
<h2 className="text-white font-bold text-xl tracking-wide"> | ||
{profileHandle} | ||
</h2> | ||
</div> | ||
<p className="text-[#ff89a9] font-semibold mt-2.5"> | ||
{FormattingUtils.humanAddress(smartAccountAddress, 4, 6)} | ||
</p> | ||
</section> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./ConnectedAccountProfileCard"; |
2 changes: 1 addition & 1 deletion
2
src/components/Lens/CreateLensProfileForm/helpers/CreateLensProfileHelpers.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { SuccessAnimationLottie } from "@/components"; | ||
import { WithLensContext } from "@/providers"; | ||
import { useActiveProfile } from "@lens-protocol/react-web"; | ||
import dynamic from "next/dynamic"; | ||
import Link from "next/link"; | ||
import { useMemo, useState } from "react"; | ||
import { IconContext } from "react-icons"; | ||
import { FaGem } from "react-icons/fa"; | ||
|
||
const Breadcrumbs = dynamic( | ||
() => | ||
import("@/components/Breadcrumbs/Breadcrumbs").then((res) => res.default), | ||
{ | ||
ssr: false | ||
} | ||
); | ||
|
||
const CreateLensProfileForm = dynamic( | ||
() => | ||
import( | ||
"@/components/Lens/CreateLensProfileForm/CreateLensProfileForm" | ||
).then((res) => res.default), | ||
{ | ||
ssr: false | ||
} | ||
); | ||
|
||
const AddProfilePictureForm = dynamic( | ||
() => | ||
import( | ||
"@/components/Lens/AddProfilePictureForm/AddProfilePictureForm" | ||
).then((res) => res.default), | ||
{ | ||
ssr: false | ||
} | ||
); | ||
|
||
const Onboarding = () => ( | ||
<WithLensContext Component={<OnboardingComponent />} /> | ||
); | ||
export default Onboarding; | ||
|
||
const ONBOARDING_STEPS = ["Account Handle", "Account image", "Account ready"]; | ||
|
||
function OnboardingComponent() { | ||
const [activeStepIndex, setActiveStepIndex] = useState<number>(0); | ||
|
||
const { data: activeProfile } = useActiveProfile(); | ||
|
||
const renderOnboardingStep = useMemo(() => { | ||
switch (activeStepIndex) { | ||
case 0: | ||
return <CreateLensProfileForm setStep={setActiveStepIndex} />; | ||
case 1: | ||
return <AddProfilePictureForm setStep={setActiveStepIndex} />; | ||
case 2: | ||
case 3: | ||
return ( | ||
<div className="flex flex-col items-center justify-center w-full h-[30vh]"> | ||
<SuccessAnimationLottie /> | ||
<Link href={`/profile/${activeProfile?.handle}`}> | ||
<button | ||
className={ | ||
"bg-[#FF89A9] flex justify-center items-center rounded-md text-[#2b2b2b] w-full mt-8 hover:brightness-90" | ||
} | ||
> | ||
<p className="py-2 px-2 font-medium uppercase text-base"> | ||
Start posting | ||
</p> | ||
<FaGem /> | ||
</button> | ||
</Link> | ||
</div> | ||
); | ||
} | ||
}, [activeStepIndex, activeProfile?.handle]); | ||
|
||
return ( | ||
<div className="px-4"> | ||
<div className="bg-[#2b2b2b] rounded-md mx-auto max-w-2xl mt-8 py-4"> | ||
<div className="py-4 flex flex-col items-center"> | ||
<div className="flex justify-center"> | ||
<IconContext.Provider value={{ size: "32", color: "#FF89A9" }}> | ||
<FaGem /> | ||
</IconContext.Provider> | ||
</div> | ||
<div className="justify-center flex font-medium text-xl py-4"> | ||
Complete your Ruby Ring Account | ||
</div> | ||
<div className="py-4"> | ||
<Breadcrumbs | ||
steps={ONBOARDING_STEPS} | ||
currentStep={activeStepIndex} | ||
/> | ||
</div> | ||
<div className="w-full px-4 md:w-3/4 mt-4"> | ||
{renderOnboardingStep} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./Onboarding"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,24 @@ | ||
// Use inter from next/font | ||
"use client"; | ||
// Use inter from next/font | ||
import { Inter } from "next/font/google"; | ||
import { Suspense } from "react"; | ||
import { useAccountStore } from "@/store"; | ||
import { BeatLoader } from "react-spinners"; | ||
import { WithLensContext } from "@/providers"; | ||
import dynamic from "next/dynamic"; | ||
|
||
//eslint-disable-next-line | ||
|
||
const inter = Inter({ subsets: ["latin"] }); | ||
|
||
const LensProfileCard = dynamic( | ||
() => | ||
import("@/components/Lens/LensProfileCard/LensProfileCard").then( | ||
(res) => res.LensProfileCard | ||
), | ||
{ | ||
ssr: false | ||
} | ||
const HomepageComponent = dynamic( | ||
() => import("@/components/Homepage/Homepage"), | ||
{ ssr: false } | ||
); | ||
|
||
export default function Home() { | ||
const { socialAccountLoading, smartAccountAddress } = useAccountStore(); | ||
return ( | ||
<main className={inter.className}> | ||
<Suspense fallback={<div>Loading...</div>}> | ||
<div className="flex flex-col h-[80vh] w-full justify-center items-center gap-4"> | ||
{!socialAccountLoading && !smartAccountAddress && ( | ||
<h1>Login to start using the app</h1> | ||
)} | ||
{socialAccountLoading && !smartAccountAddress && ( | ||
<BeatLoader | ||
color={"white"} | ||
loading={true} | ||
size={12} | ||
aria-label="Loading Spinner" | ||
data-testid="loader" | ||
/> | ||
)} | ||
<div className="w-1/2 self-center flex flex-col gap-2"> | ||
{smartAccountAddress && ( | ||
<h1 className="font-bold text-xl self-start">Your profile</h1> | ||
)} | ||
|
||
<WithLensContext Component={<LoggedAccountProfileCard />} /> | ||
</div> | ||
</div> | ||
<HomepageComponent /> | ||
</Suspense> | ||
</main> | ||
); | ||
} | ||
|
||
const LoggedAccountProfileCard = () => { | ||
const { lensAccount } = useAccountStore(); | ||
|
||
if (!lensAccount) return null; | ||
return ( | ||
<LensProfileCard | ||
cardClassName="bg-[#2b2b2b] rounded-md p-4" | ||
activeProfile={lensAccount} | ||
profile={lensAccount} | ||
renderFollowButton={false} | ||
/> | ||
); | ||
}; |
Oops, something went wrong.