Skip to content

Commit

Permalink
feat: user profile page
Browse files Browse the repository at this point in the history
  • Loading branch information
Irere123 committed Oct 23, 2024
1 parent 5f3c8fa commit ffafa4c
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 65 deletions.
3 changes: 3 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const nextConfig = {
{
hostname: "www.google.com",
},
{
hostname: "lh3.googleusercontent.com",
},
],
},
};
Expand Down
5 changes: 5 additions & 0 deletions public/grid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import localFont from "next/font/local";
import "@/env.server";
import "./globals.css";
import { Providers } from "./providers";
import { Background } from "@/components/background";

const geistSans = localFont({
src: "./fonts/GeistVF.woff",
Expand Down
99 changes: 52 additions & 47 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,68 @@
import Link from "next/link";
import { Suspense } from "react";

import { Background } from "@/components/background";
import { Testimonials } from "@/components/home/Testimonials";
import { BookOpen } from "@/components/icons";
import { MainLayout } from "@/components/layouts/MainLayout";
import ProjectsList from "@/components/projects/projects-list";
import SearchBar, { SearchBarPlaceholder } from "@/components/ui/search-bar";
import Link from "next/link";
import { Suspense } from "react";

export default function Home() {
return (
<MainLayout>
<div className="relative z-10 mx-auto w-full max-w-xl px-5 py-10 xl:px-0">
<Link
href={`/why-build-this`}
className="mx-auto mb-5 flex max-w-fit animate-fade-up items-center justify-center space-x-2 overflow-hidden rounded-full border border-gray-200 bg-gray-100 px-7 py-2 transition-colors hover:bg-gray-50"
style={{ animationDelay: "0.1s", animationFillMode: "forwards" }}
>
<BookOpen className="text-sm h-5 w-5 text-gray-600" />
<p className="text-sm font-semibold text-gray-600">
Why we built ReLaunch?
<>
<Background />
<MainLayout>
<div className="relative z-10 mx-auto w-full max-w-xl px-5 py-10 xl:px-0">
<Link
href={`/why-build-this`}
className="mx-auto mb-5 flex max-w-fit animate-fade-up items-center justify-center space-x-2 overflow-hidden rounded-full border border-gray-200 bg-gray-100 px-7 py-2 transition-colors hover:bg-gray-50"
style={{ animationDelay: "0.1s", animationFillMode: "forwards" }}
>
<BookOpen className="text-sm h-5 w-5 text-gray-600" />
<p className="text-sm font-semibold text-gray-600">
Why we built ReLaunch?
</p>
</Link>
<h1
className="animate-fade-up bg-gradient-to-br from-black to-stone-500 bg-clip-text text-center text-4xl font-bold tracking-[-0.02em] text-transparent opacity-0 drop-shadow-sm [text-wrap:balance] md:text-6xl md:leading-[1.1]"
style={{ animationDelay: "0.15s", animationFillMode: "forwards" }}
>
Showcasing ideas to the public!
</h1>
<p
className="mt-6 animate-fade-up text-center text-gray-500 opacity-0 [text-wrap:balance] md:text-xl"
style={{ animationDelay: "0.25s", animationFillMode: "forwards" }}
>
Share your work and connect with a global audience in a space
designed to reflect your unique style.
</p>
</Link>
<h1
className="animate-fade-up bg-gradient-to-br from-black to-stone-500 bg-clip-text text-center text-4xl font-bold tracking-[-0.02em] text-transparent opacity-0 drop-shadow-sm [text-wrap:balance] md:text-6xl md:leading-[1.1]"
style={{ animationDelay: "0.15s", animationFillMode: "forwards" }}
>
Showcasing ideas to the public!
</h1>
<p
className="mt-6 animate-fade-up text-center text-gray-500 opacity-0 [text-wrap:balance] md:text-xl"
style={{ animationDelay: "0.25s", animationFillMode: "forwards" }}
>
Share your work and connect with a global audience in a space designed
to reflect your unique style.
</p>
<div
className="mx-auto mt-10 flex animate-fade-up items-center justify-center space-x-5 opacity-0"
style={{ animationDelay: "0.3s", animationFillMode: "forwards" }}
>
<Suspense fallback={<SearchBarPlaceholder />}>
<SearchBar />
</Suspense>
<div
className="mx-auto mt-10 flex animate-fade-up items-center justify-center space-x-5 opacity-0"
style={{ animationDelay: "0.3s", animationFillMode: "forwards" }}
>
<Suspense fallback={<SearchBarPlaceholder />}>
<SearchBar />
</Suspense>
</div>
</div>
</div>

<div
className="animate-fade-up opacity-0 mx-auto"
style={{ animationDelay: "0.35s", animationFillMode: "forwards" }}
>
<div className="mx-5 md:mx-0">
<div className="grid gap-4 w-full">
<Testimonials />
</div>
<div
className="animate-fade-up opacity-0 mx-auto"
style={{ animationDelay: "0.35s", animationFillMode: "forwards" }}
>
<div className="mx-5 md:mx-0">
<div className="grid gap-4 w-full">
<Testimonials />
</div>

<div className="grid gap-4">
<h2 className="font-medium text-center text-4xl">All projects</h2>
<ProjectsList />
<div className="grid gap-4">
<h2 className="font-medium text-center text-4xl">All projects</h2>
<ProjectsList />
</div>
</div>
</div>
</div>
</MainLayout>
</MainLayout>
</>
);
}
14 changes: 0 additions & 14 deletions src/app/profile/page.tsx

This file was deleted.

61 changes: 61 additions & 0 deletions src/app/u/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Image from "next/image";
import { redirect } from "next/navigation";

import { constructMetadata } from "@/lib/utils";
import { getUserProfile } from "@/modules/user/get-user";
import { MainLayout } from "@/components/layouts/MainLayout";
import { getUserProjects } from "@/modules/actions/get-user-projects";
import { ProjectsGrid } from "@/components/projects/projects-grid";

interface Props {
params: { id: string };
}

export async function generateMetadata({ params }: Props) {
const { id } = await params;
const user = await getUserProfile(id);

if (!user) return;

return constructMetadata({
title: `${user.name} | Relaunch`,
description: `Checkout ${user.name} Projects on Relaunch and give him feedback and support.`,
image: user.image,
});
}

export default async function ProfilePage({ params }: Props) {
const { id } = await params;
const user = await getUserProfile(id);
const projects = await getUserProjects({ userId: id });

if (!user) {
redirect("/");
}

return (
<MainLayout>
<div
className={
"relative aspect-[4/1] w-full rounded-t-2xl border-t border-border bg-gradient-to-tr mt-6 from-yellow-50 via-indigo-50 to-green-50"
}
/>
<div className="relative -mt-8 flex items-center justify-between px-4 sm:-mt-12 sm:items-end md:pr-0">
<Image
src={user.image!}
alt={user.name!}
width={100}
height={100}
className="h-16 w-16 rounded-full bg-white p-2 sm:h-24 sm:w-24"
/>
</div>

<div className="relative mx-4 flex flex-col min-h-[22rem] bg-white p-4">
<h2 className="font-medium text-lg">Gallery</h2>
<div className="py-10">
<ProjectsGrid projects={projects} />
</div>
</div>
</MainLayout>
);
}
59 changes: 59 additions & 0 deletions src/components/background.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export function Background() {
return (
<div style={styles.backgroundMain}>
<div style={styles.backgroundMainBefore} />
<div style={styles.backgroundMainAfter} />
<div style={styles.backgroundContent} />
</div>
);
}

const styles: { [key: string]: React.CSSProperties } = {
backgroundMain: {
width: "100vw",
minHeight: "100vh",
position: "fixed",
zIndex: 1,
display: "flex",
justifyContent: "center",
padding: "120px 24px 160px 24px",
pointerEvents: "none",
},
backgroundMainBefore: {
background: "radial-gridient(circle, rgba(2, 0, 36, 0) 0, #fafafa 100%)",
position: "absolute",
content: '""',
zIndex: 2,
width: "100%",
height: "100%",
top: 0,
},
backgroundMainAfter: {
content: '""',
backgroundImage: "url(/grid.svg)",
zIndex: 1,
position: "absolute",
width: "100%",
height: "100%",
top: 0,
opacity: 0.4,
filter: "invert(1)",
},
backgroundContent: {
zIndex: 3,
width: "100%",
maxWidth: "640px",
backgroundImage: `radial-gradient(at 27% 37%, hsla(215, 98%, 61%, 1) 0px, transparent 0%),
radial-gradient(at 97% 21%, hsla(125, 98%, 72%, 1) 0px, transparent 50%),
radial-gradient(at 52% 99%, hsla(354, 98%, 61%, 1) 0px, transparent 50%),
radial-gradient(at 10% 29%, hsla(256, 96%, 67%, 1) 0px, transparent 50%),
radial-gradient(at 97% 96%, hsla(38, 60%, 74%, 1) 0px, transparent 50%),
radial-gradient(at 33% 50%, hsla(222, 67%, 73%, 1) 0px, transparent 50%),
radial-gradient(at 79% 53%, hsla(343, 68%, 79%, 1) 0px, transparent 50%)`,
position: "absolute",
height: "100%",
filter: "blur(100px) saturate(150%)",
top: "80px",
opacity: 0.15,
},
};
2 changes: 1 addition & 1 deletion src/components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default function Navbar({
>
<Dashboard />
</Link>
<Link href={`/profile`}>
<Link href={`/u/${session.user.id}`}>
<Avatar>
<AvatarImage src={session.user.image!} />
</Avatar>
Expand Down
4 changes: 1 addition & 3 deletions src/modules/actions/get-user-projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ export const getUserProjects = async ({
userId,
}: {
userId: string;
}): Promise<Project[] | null> => {
}): Promise<Project[]> => {
const result = await db
.select()
.from(projects)
.where(eq(projects.userId, userId));

if (!result) return null;

return result;
};
17 changes: 17 additions & 0 deletions src/modules/user/get-user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { eq } from "drizzle-orm";
import { cache } from "react";

import { db } from "@/db";
import { users } from "@/db/schema";

export const getUserProfile = cache(async (id: string) => {
const [result] = await db
.select()
.from(users)
.where(eq(users.id, id))
.limit(1);

if (!result) return null;

return result;
});

0 comments on commit ffafa4c

Please sign in to comment.