Skip to content

Commit

Permalink
feat: switch to app dir (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
baptadn authored Oct 22, 2023
1 parent e538620 commit 54937e3
Show file tree
Hide file tree
Showing 66 changed files with 2,994 additions and 1,597 deletions.
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,29 @@
"@chakra-ui/react": "^2.4.2",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@next-auth/prisma-adapter": "^1.0.5",
"@next/font": "^13.0.6",
"@next-auth/prisma-adapter": "^1.0.7",
"@prisma/client": "^4.7.1",
"@stripe/react-stripe-js": "^1.16.0",
"@stripe/stripe-js": "^1.46.0",
"@types/node": "18.11.10",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",
"@types/uniqid": "^5.3.2",
"@vercel/analytics": "^0.1.5",
"@vercel/analytics": "^1.1.1",
"aws-crt": "^1.18.1",
"axios": "^1.2.0",
"date-fns": "^2.29.3",
"eslint": "8.29.0",
"eslint-config-next": "13.0.6",
"framer-motion": "^7.6.19",
"framer-motion": "^10.16.4",
"image-blob-reduce": "^4.1.0",
"jszip": "^3.10.1",
"keen-slider": "^6.8.5",
"mjml": "^4.13.0",
"mjml-react": "^2.0.8",
"next": "13.0.6",
"next-auth": "^4.18.0",
"next-s3-upload": "^0.2.8",
"next": "13.5.6",
"next-auth": "^4.24.3",
"next-s3-upload": "^0.3.3",
"nodemailer": "^6.9.0",
"openai": "^3.1.0",
"plaiceholder": "^2.5.0",
Expand All @@ -48,7 +48,7 @@
"react-dom": "18.2.0",
"react-dropzone": "^14.2.3",
"react-icons": "^4.7.1",
"react-medium-image-zoom": "^5.1.2",
"react-medium-image-zoom": "^5.1.8",
"react-parallax-tilt": "^1.7.77",
"react-query": "^3.39.2",
"sharp": "^0.31.2",
Expand Down
10 changes: 10 additions & 0 deletions src/app/(auth)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import DashboardPage from "@/components/pages/DashboardPage";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Dashboard",
};

const Dashboard = () => <DashboardPage />;

export default Dashboard;
11 changes: 11 additions & 0 deletions src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { getCurrentUserOrRedirect } from "@/lib/sessions";

type Props = {
children: React.ReactNode;
};

export default async function Layout({ children }: Props) {
await getCurrentUserOrRedirect();

return <>{children}</>;
}
57 changes: 57 additions & 0 deletions src/app/(auth)/studio/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import StudioPage from "@/components/pages/StudioPage";
import replicateClient from "@/core/clients/replicate";
import db from "@/core/db";
import { getCurrentSessionRedirect } from "@/lib/sessions";
import { Metadata } from "next";
import { notFound } from "next/navigation";

const PROJECTS_PER_PAGE = 9;

export const metadata: Metadata = {
title: "My Studio",
};

const Studio = async ({ params }: { params: { id: string } }) => {
const session = await getCurrentSessionRedirect();
const projectId = params.id;

const project = await db.project.findFirst({
where: {
id: projectId,
userId: session.userId,
modelStatus: "succeeded",
},
include: {
_count: {
select: { shots: true },
},
shots: {
orderBy: { createdAt: "desc" },
take: PROJECTS_PER_PAGE,
skip: 0,
},
},
orderBy: { createdAt: "desc" },
});

if (!project) {
notFound();
}

const { data: model } = await replicateClient.get(
`https://api.replicate.com/v1/models/${process.env.REPLICATE_USERNAME}/${project.id}/versions/${project.modelVersionId}`
);

const hasImageInputAvailable = Boolean(
model.openapi_schema?.components?.schemas?.Input?.properties?.image?.title
);

return (
<StudioPage
project={project}
hasImageInputAvailable={hasImageInputAvailable}
/>
);
};

export default Studio;
10 changes: 10 additions & 0 deletions src/app/(public)/faq/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import FaqPage from "@/components/pages/FaqPage";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "FAQ",
};

const Faq = () => <FaqPage />;

export default Faq;
29 changes: 29 additions & 0 deletions src/app/(public)/gallery/[userId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import GalleryPage from "@/components/pages/GalleryPage";
import db from "@/core/db";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Gallery",
};

const Gallery = async ({ params }: { params: { userId: string } }) => {
const userId = params.userId;

const shots = await db.shot.findMany({
select: { outputUrl: true, blurhash: true },
orderBy: { createdAt: "desc" },
where: {
outputUrl: { not: { equals: null } },
bookmarked: true,
Project: {
userId: {
equals: userId,
},
},
},
});

return <GalleryPage shots={shots} />;
};

export default Gallery;
10 changes: 10 additions & 0 deletions src/app/(public)/how-it-works/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import HowItWorksPage from "@/components/pages/HowItWorksPage";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "AI Avatar: how it works",
};

const HowItWorks = () => <HowItWorksPage />;

export default HowItWorks;
15 changes: 15 additions & 0 deletions src/app/(public)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import LoginPage from "@/components/pages/LoginPage";
import { getCurrentUser } from "@/lib/sessions";
import { redirect } from "next/navigation";

const Login = async () => {
const user = await getCurrentUser();

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

return <LoginPage />;
};

export default Login;
45 changes: 45 additions & 0 deletions src/app/(public)/prompts/dreambooth/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import PromptDetailPage, {
TPrompt,
} from "@/components/pages/prompts/PromptDetailPage";
import { prompts } from "@/core/utils/prompts";

export function generateStaticParams() {
return prompts.map((prompt) => ({
slug: prompt.slug,
}));
}

export async function generateMetadata({
params,
}: {
params: { slug: string };
}) {
const slug = params?.slug as string;
const prompt = prompts.find((prompt) => prompt.slug === slug)!;

return {
title: `Free prompt ${prompt.label} - Photoshot`,
description:
"Our free AI prompt covers a wide range of themes and topics to help you create a unique avatar. Use theme with our Studio or your Stable Diffusion or Dreambooth models.",
};
}

const PromptDetail = async ({ params }: { params: { slug: string } }) => {
const slug = params?.slug as string;
const promptIndex = prompts.findIndex((prompt) => prompt.slug === slug)!;
const prompt = prompts[promptIndex];

const morePrompts: TPrompt[] = [];

for (let i = promptIndex + 1; i < promptIndex + 6; i++) {
if (i > prompts.length - 1) {
morePrompts.push(prompts[Math.abs(i - prompts.length)]);
} else {
morePrompts.push(prompts[i]);
}
}

return <PromptDetailPage morePrompts={morePrompts} prompt={prompt} />;
};

export default PromptDetail;
12 changes: 12 additions & 0 deletions src/app/(public)/prompts/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import PromptsListPage from "@/components/pages/prompts/PromptsListPage";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "AI Prompts Inspiration",
description:
"Our free AI prompt covers a wide range of themes and topics to help you create a unique avatar. Use theme with our Studio or your Stable Diffusion or Dreambooth models.",
};

const PromptsList = () => <PromptsListPage />;

export default PromptsList;
10 changes: 10 additions & 0 deletions src/app/(public)/terms/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import TermsPage from "@/components/pages/TermsPage";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Photoshot Privacy Policy",
};

const Terms = () => <TermsPage />;

export default Terms;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import db from "@/core/db";
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import NextAuth, { NextAuthOptions } from "next-auth";
import EmailProvider from "next-auth/providers/email";
import db from "@/core/db";

export const authOptions: NextAuthOptions = {
adapter: PrismaAdapter(db),
Expand All @@ -24,4 +24,6 @@ export const authOptions: NextAuthOptions = {
secret: process.env.SECRET,
};

export default NextAuth(authOptions);
const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { NextApiRequest, NextApiResponse } from "next";
import Stripe from "stripe";
import db from "@/core/db";
import { stripe } from "@/lib/stripe";
import { NextResponse } from "next/server";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: "2022-11-15",
});

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
export async function GET(
req: Request,
{ params }: { params: { ppi: string; sessionId: string } }
) {
const sessionId = req.query.sessionId as string;
const ppi = req.query.ppi as string;
const sessionId = params.sessionId;
const ppi = params.ppi;

const session = await stripe.checkout.sessions.retrieve(sessionId);

Expand All @@ -25,9 +21,10 @@ export default async function handler(
});

if (payments.length > 0) {
return res
.status(400)
.json({ success: false, error: "payment_already_processed" });
return NextResponse.json(
{ success: false, error: "payment_already_processed" },
{ status: 400 }
);
}

if (
Expand All @@ -54,12 +51,20 @@ export default async function handler(
},
});

return res.status(200).json({
success: true,
credits: project.credits,
promptWizardCredits: project.promptWizardCredits,
});
return NextResponse.json(
{
success: true,
credits: project.credits,
promptWizardCredits: project.promptWizardCredits,
},
{ status: 200 }
);
}

return res.status(400).json({ success: false });
return NextResponse.json(
{
success: false,
},
{ status: 400 }
);
}
37 changes: 37 additions & 0 deletions src/app/api/checkout/check/[ppi]/[sessionId]/studio/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import db from "@/core/db";
import { stripe } from "@/lib/stripe";
import { NextResponse } from "next/server";

export async function GET(
req: Request,
{ params }: { params: { ppi: string; sessionId: string } }
) {
const sessionId = params.sessionId;
const ppi = params.ppi;

const session = await stripe.checkout.sessions.retrieve(sessionId);

if (
session.payment_status === "paid" &&
session.metadata?.projectId === ppi
) {
await db.project.update({
where: { id: ppi },
data: { stripePaymentId: session.id },
});

return NextResponse.json(
{
success: true,
},
{ status: 200 }
);
}

return NextResponse.json(
{
success: false,
},
{ status: 400 }
);
}
Loading

1 comment on commit 54937e3

@vercel
Copy link

@vercel vercel bot commented on 54937e3 Oct 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.