@@ -21,13 +41,13 @@ export default function Profile() {
-
John Doe
+
{session.name}
San Francisco, CA
-
+
@@ -55,8 +75,8 @@ export default function Profile() {
- {adts.slice(0, 3).map((adt) => (
-
+ {user?.adts.map((adt) => (
+
))}
diff --git a/app/(root)/profile/settings/page.tsx b/app/(root)/profile/settings/page.tsx
new file mode 100644
index 0000000..e4cfe9e
--- /dev/null
+++ b/app/(root)/profile/settings/page.tsx
@@ -0,0 +1,33 @@
+import Header from "@/components/Header"
+import { ProfileForm } from "@/components/shared/profile-form"
+import { getUserSession } from "@/lib/get-user-session"
+import { prisma } from "@/prisma/prisma-client"
+import { redirect } from "next/navigation"
+
+
+export default async function Profile() {
+ const session = await getUserSession()
+
+ if (!session) {
+ return redirect('/not-auth')
+ }
+
+ const user = await prisma.user.findFirst({
+ where: {
+ id: Number(session?.id)
+ },
+ include: {
+ adts: true
+ }
+ })
+
+ if (!user) {
+ return redirect('/not-auth')
+ }
+
+ console.log(user?.adts)
+
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/app/actions.ts b/app/actions.ts
new file mode 100644
index 0000000..83174c8
--- /dev/null
+++ b/app/actions.ts
@@ -0,0 +1,97 @@
+'use server'
+
+import { getUserSession } from "@/lib/get-user-session";
+import { prisma } from "@/prisma/prisma-client";
+import { Category, Prisma } from "@prisma/client";
+import { hashSync } from "bcrypt";
+
+
+export async function updateUserInfo(body: Prisma.UserUpdateInput) {
+ try {
+ const currentUser = await getUserSession();
+
+ if (!currentUser) {
+ throw new Error('Not found user')
+ }
+
+ const findUser = await prisma.user.findFirst({
+ where: {
+ id: Number(currentUser.id),
+ },
+ });
+
+ await prisma.user.update({
+ where: {
+ id: Number(currentUser.id),
+ },
+ data: {
+ name: body.name,
+ email: body.email,
+ password: body.password ? hashSync(body.password as string, 10) : findUser?.password ,
+ }
+ })
+
+
+ } catch (error) {
+ console.log('Error [UPDATE_USER]', error);
+ throw error;
+ }
+}
+
+export async function registerUser(body: Prisma.UserCreateInput) {
+ try {
+ const user = await prisma.user.findFirst({
+ where: {
+ email: body.email
+ }
+ })
+
+ if (user) {
+ throw new Error('user exist')
+ }
+
+ await prisma.user.create({
+ data: {
+ name: body.name,
+ email: body.email,
+ password: hashSync(body.password as string, 10) ,
+ }
+ })
+
+ } catch (error) {
+ console.log('Erro [create user]', error);
+ throw error;
+ }
+}
+
+
+export async function createAdt(body: Prisma.AdtCreateInput, categories: Category[]) {
+ try {
+
+ const currentUser = await getUserSession();
+
+ if (!currentUser) {
+ throw new Error('Not found user')
+ }
+
+
+ await prisma.adt.create({
+ data: {
+ title: body.title,
+ categories: {
+ connect: categories?.map((category) => ({
+ id: category.id,
+ })),
+ },
+ price: body.price,
+ description: body.description,
+ image: body.image,
+ location: body.location,
+ userId: Number(currentUser.id),
+ }
+ })
+ } catch (error) {
+ console.log('Error [create adt]', error);
+ throw error;
+ }
+}
\ No newline at end of file
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 0000000..7108fb1
--- /dev/null
+++ b/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,153 @@
+import NextAuth, { AuthOptions } from "next-auth"
+import GithubProvider from "next-auth/providers/github"
+import CredentialsProvider from 'next-auth/providers/credentials';
+import { prisma } from "@/prisma/prisma-client";
+import { compare, hashSync } from "bcrypt";
+import { Role } from "@prisma/client";
+
+export const authOptions: AuthOptions = {
+ providers: [
+ GithubProvider({
+ clientId: process.env.GITHUB_ID || '',
+ clientSecret: process.env.GITHUB_SECRET || '',
+ profile(profile) {
+ return {
+ id: profile.id,
+ name: profile.name || profile.login,
+ email: profile.email,
+ image: profile.avatar_url,
+ role: 'USER' as Role
+ }
+ }
+ }),
+ CredentialsProvider({
+ name: 'Credentials',
+ credentials: {
+ email: {label: 'Email', type: 'text'},
+ password: {label: 'Password', type: 'password'},
+ },
+ async authorize(credentials) {
+ if (!credentials) {
+ return null;
+ }
+
+ const values = {
+ email: credentials.email
+ }
+
+ const findUser = await prisma.user.findFirst({
+ where: values
+ })
+
+ if (!findUser) {
+ return null;
+ }
+
+ const isPasswordValid = await compare(credentials.password, findUser.password);
+
+ if (!isPasswordValid) {
+ return null;
+ }
+
+ // verified //
+
+ return {
+ id: String(findUser.id),
+
+ email: findUser.email,
+ name: findUser.name,
+ role: findUser.role,
+ }
+
+
+ }
+ })
+ ],
+ secret: process.env.NEXTAUTH_SECRET,
+ session: {
+ strategy: 'jwt'
+ },
+ callbacks: {
+ async signIn({ user, account}) {
+ try {
+ if (account?.provaider === 'credentials') {
+ return true
+ }
+
+ if (!user.email){
+ return false
+ }
+
+ const findUser = await prisma.user.findFirst({
+ where: {
+ OR: [
+ { provider: account?.provider, providerId: account?.providerId },
+ { email: user.email }
+ ]
+ }
+ })
+
+ if (findUser) {
+ await prisma.user.update({
+ where: {
+ id: findUser.id
+ },
+ data: {
+ provider: account?.provider,
+ providerId: account?.providerAccountId
+ }
+ })
+ return true
+ }
+
+ await prisma.user.create({
+ data: {
+ email: user.email,
+ name: user.name || 'User #' + user.id,
+ password: hashSync(user.id.toString(), 10), // ИЗМЕНИТЬ
+ provider: account?.provider,
+ providerId: account?.providerAccountId
+ }
+ })
+
+ return true;
+
+ } catch (error) {
+ console.error('Error [SIGNIN]', error)
+ return false
+ }
+ },
+
+ async jwt({ token }) {
+ if (!token.email) {
+ return token;
+ }
+
+ const findUser = await prisma.user.findFirst({
+ where: {
+ email: token.email
+ }
+ })
+ if (findUser) {
+ token.id = String(findUser.id);
+ token.email = String(findUser.email);
+ token.name = String(findUser.name);
+ token.role = String(findUser.role);
+ }
+
+ return token
+ },
+ session({ session, token }) {
+ if (session?.user) {
+ session.user.id = token.id,
+ session.user.role = token.role
+ }
+
+ return session;
+ }
+ }
+}
+
+export const handler = NextAuth(authOptions)
+
+export { handler as GET, handler as POST }
\ No newline at end of file
diff --git a/app/layout.tsx b/app/layout.tsx
index 9542946..85cce89 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,9 +1,9 @@
+"use client"
+
import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";
-
-
-
+import { SessionProvider } from "next-auth/react"
export default function RootLayout({
@@ -13,10 +13,10 @@ export default function RootLayout({
}>) {
return (
-
- {children}
+
+
+ {children}
+
);
diff --git a/components/Header.tsx b/components/Header.tsx
index cbd5b08..967aa4b 100644
--- a/components/Header.tsx
+++ b/components/Header.tsx
@@ -2,8 +2,14 @@
import React from 'react';
import { Search, PlusCircle, Bell, User } from 'lucide-react';
import Link from 'next/link';
+import { useSession, signIn } from 'next-auth/react';
+import { Button } from './ui/button';
+import { ProfileButton } from './shared/profile-button';
+import { AuthModal } from './shared/modals/auth-modal/auth-modal';
export default function Header() {
+ const [openAuthModal, setOpenAuthModal] = React.useState(false)
+
return (