Skip to content

Commit

Permalink
Merge pull request #29 from pierobassa/feat-new-homepage
Browse files Browse the repository at this point in the history
feat(homepage): add landing page, refactor connected profile card
  • Loading branch information
akanoce committed Sep 24, 2023
2 parents 2764c9f + bec053d commit 6741d99
Show file tree
Hide file tree
Showing 17 changed files with 265 additions and 150 deletions.
2 changes: 1 addition & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
transpilePackages: ["@lens-protocol"],
transpilePackages: ["@lens-protocol", "web3.storage"],
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.fallback = {
Expand Down
Binary file added src/assets/ruby_ring_hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/components/Breadcrumbs/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default function Breadcrumbs({ steps, currentStep }: Props) {
></span>
)}
<Breadcrumb
key={index}
title={step}
displayedNumber={index + 1}
done={currentStep > index}
Expand Down
93 changes: 93 additions & 0 deletions src/components/Homepage/Homepage.tsx
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>
);
};
1 change: 1 addition & 0 deletions src/components/Homepage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Homepage";
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export default function AddProfilePictureForm({ setStep }: Props) {

const [loading, setLoading] = useState<boolean>(false);

//TODO: we hsould get rid of this as it should be outdated
const { lensAccount } = useAccountStore();

const {
Expand Down
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>
);
};
1 change: 1 addition & 0 deletions src/components/Lens/ConnectedAccountProfileCard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ConnectedAccountProfileCard";
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CIDString } from "web3.storage";
import { CIDString } from "node_modules/web3.storage";

export const getWeb3StorageLink = (CID: CIDString) => {
return `https://${CID}.ipfs.w3s.link/`;
Expand Down
1 change: 1 addition & 0 deletions src/components/Lens/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./AddProfilePictureForm";
export * from "./CreateLensProfileForm";
export * from "./ConnectedAccountProfileCard";
export * from "./LensProfileCard";
export * from "./SearchLensProfiles";
export * from "./SpotlightSearchLensProfiles";
Expand Down
103 changes: 103 additions & 0 deletions src/components/Onboarding/Onboarding.tsx
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>
);
}
1 change: 1 addition & 0 deletions src/components/Onboarding/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Onboarding";
8 changes: 6 additions & 2 deletions src/components/SocialLoginWrapper/LoggedInAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AccountBox } from "@/components";
import { useAccountStore } from "@/store";
import { Menu, Transition } from "@headlessui/react";
import { useWalletLogout } from "@lens-protocol/react-web";
import Link from "next/link";
Expand All @@ -14,9 +15,12 @@ type Props = {
};
export const LoggedInAccount: React.FC<Props> = ({ address, onLogout }) => {
const { execute: lensLogout } = useWalletLogout();
const handleLogout = () => {
lensLogout();
const { clear } = useAccountStore();
const handleLogout = async () => {
clear();
await lensLogout();
onLogout();
console.log("logged out");
};

return (
Expand Down
2 changes: 1 addition & 1 deletion src/networking/Web3Storage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Web3Storage } from "web3.storage";
import { Web3Storage } from "node_modules/web3.storage";

const WEB3_STORAGE_TOKEN = process.env.NEXT_PUBLIC_WEB3_STORAGE_TOKEN;

Expand Down
55 changes: 7 additions & 48 deletions src/pages/index.tsx
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}
/>
);
};
Loading

0 comments on commit 6741d99

Please sign in to comment.