fix login
This commit is contained in:
parent
75db98f254
commit
5d1780d670
@ -1,15 +1,19 @@
|
|||||||
|
// "use client"
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
// import { useParams } from 'next/navigation';
|
// import { useParams } from 'next/navigation';
|
||||||
import { MapPin, Calendar, Phone, MessageCircle, Share2, Flag, Heart } from 'lucide-react';
|
import { MapPin, Calendar, Phone, MessageCircle, Share2, Flag, Heart } from 'lucide-react';
|
||||||
import { prisma } from '@/prisma/prisma-client';
|
import { prisma } from '@/prisma/prisma-client';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
import { ShowNumberModal } from '@/components/shared/modals/show-number';
|
||||||
|
|
||||||
type Params = Promise<{ id: string }>
|
type Params = Promise<{ id: string }>
|
||||||
|
|
||||||
export default async function AdtPage(props: { params: Params }) {
|
export default async function AdtPage(props: { params: Params }) {
|
||||||
|
// const [ openShowNumberModal, setOpenShowNumberModal ] = React.useState(false)
|
||||||
const params = await props.params;
|
const params = await props.params;
|
||||||
|
|
||||||
const adt = await prisma.adt.findUnique({
|
const adt = await prisma.adt.findFirst({
|
||||||
where: {
|
where: {
|
||||||
id: Number(params.id),
|
id: Number(params.id),
|
||||||
},
|
},
|
||||||
@ -29,6 +33,7 @@ export default async function AdtPage(props: { params: Params }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{/* <ShowNumberModal open={openShowNumberModal} onClose={() => setOpenShowNumberModal(false)} /> */}
|
||||||
|
|
||||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||||
@ -54,8 +59,7 @@ export default async function AdtPage(props: { params: Params }) {
|
|||||||
|
|
||||||
<h2 className="font-semibold text-lg mb-3">Description</h2>
|
<h2 className="font-semibold text-lg mb-3">Description</h2>
|
||||||
<p className="text-gray-600 mb-6">
|
<p className="text-gray-600 mb-6">
|
||||||
This is a detailed description of the listing. It includes all the important information
|
{adt.description}
|
||||||
about the item, its condition, and any special features or considerations.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="flex gap-3">
|
<div className="flex gap-3">
|
||||||
@ -87,9 +91,10 @@ export default async function AdtPage(props: { params: Params }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{/* TODO всплывающее окно для показа номера */}
|
<button
|
||||||
|
// onClick={() => setOpenShowNumberModal(true)}
|
||||||
<button className="w-full flex items-center justify-center gap-2 bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700">
|
className="w-full flex items-center justify-center gap-2 bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700"
|
||||||
|
>
|
||||||
<Phone className="h-5 w-5" />
|
<Phone className="h-5 w-5" />
|
||||||
<span>Show Phone Number</span>
|
<span>Show Phone Number</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -2,11 +2,26 @@
|
|||||||
|
|
||||||
import Categories from "@/components/Categories";
|
import Categories from "@/components/Categories";
|
||||||
import ListingCard from "@/components/ListingCard";
|
import ListingCard from "@/components/ListingCard";
|
||||||
|
import { getUserSession } from "@/lib/get-user-session";
|
||||||
import { prisma } from "@/prisma/prisma-client";
|
import { prisma } from "@/prisma/prisma-client";
|
||||||
|
|
||||||
export default async function Home() {
|
export default async function Home() {
|
||||||
const adts = await prisma.adt.findMany()
|
const adts = await prisma.adt.findMany()
|
||||||
|
const session = await getUserSession()
|
||||||
|
|
||||||
|
// if (!session) {
|
||||||
|
// return redirect('/not-auth')
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const user = await prisma.user.findFirst({
|
||||||
|
// where: {
|
||||||
|
// id: Number(session?.id)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
// console.log(user)
|
||||||
|
console.log("session",session)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="min-h-screen bg-gray-100">
|
<div className="min-h-screen bg-gray-100">
|
||||||
|
|||||||
@ -5,6 +5,63 @@ import { getUserSession } from '@/lib/get-user-session';
|
|||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
|
||||||
|
// GET функция для получения списка объявлений с пагинацией
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
try {
|
||||||
|
// Получаем параметры из URL
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
|
||||||
|
// Параметры пагинации (по умолчанию: страница 1, 10 элементов на странице)
|
||||||
|
const page = Number(searchParams.get('page')) || 1;
|
||||||
|
const limit = Number(searchParams.get('limit')) || 10;
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
|
// Получаем общее количество объявлений для пагинации
|
||||||
|
const total = await prisma.adt.count();
|
||||||
|
|
||||||
|
// Получаем объявления с учетом пагинации
|
||||||
|
const adts = await prisma.adt.findMany({
|
||||||
|
skip,
|
||||||
|
take: limit,
|
||||||
|
include: {
|
||||||
|
categories: true,
|
||||||
|
user: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
email: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc' // Сортировка по дате создания (новые первыми)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Формируем метаданные для пагинации
|
||||||
|
const meta = {
|
||||||
|
currentPage: page,
|
||||||
|
itemsPerPage: limit,
|
||||||
|
totalItems: total,
|
||||||
|
totalPages: Math.ceil(total / limit)
|
||||||
|
};
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
data: adts,
|
||||||
|
meta
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching adts:', error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Ошибка при получении объявлений' },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function POST(request: Request) {
|
export async function POST(request: Request) {
|
||||||
try {
|
try {
|
||||||
const session = await getUserSession();
|
const session = await getUserSession();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import NextAuth from "next-auth"
|
import NextAuth from "next-auth"
|
||||||
import { authOptions } from "@/constants/auth-options"
|
import { authOptions } from "@/constants/auth-options"
|
||||||
|
|
||||||
const handler = NextAuth(authOptions)
|
export const handler = NextAuth(authOptions)
|
||||||
|
|
||||||
// Экспортируем напрямую функции GET и POST, без промежуточной переменной
|
// Экспортируем напрямую функции GET и POST, без промежуточной переменной
|
||||||
export const GET = handler
|
export const GET = handler
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Search, PlusCircle, Bell, User } from 'lucide-react';
|
import { Search, PlusCircle, Bell, User } from 'lucide-react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
@ -9,19 +9,21 @@ import { AuthModal } from './shared/modals/auth-modal/auth-modal';
|
|||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const [openAuthModal, setOpenAuthModal] = React.useState(false)
|
const [openAuthModal, setOpenAuthModal] = React.useState(false)
|
||||||
|
const [mobileSearchOpen, setMobileSearchOpen] = React.useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 bg-white shadow-sm">
|
<header className="sticky top-0 z-50 bg-white shadow-sm">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-6">
|
||||||
<div className="flex justify-between items-center h-16">
|
<div className="flex justify-between items-center h-16">
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<Link href="/" className="text-2xl font-bold text-indigo-600">
|
<Link href="/" className="text-xl font-bold text-indigo-600">
|
||||||
MarketSpot
|
Bazar
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1 max-w-2xl mx-8">
|
{/* Desktop Search */}
|
||||||
<div className="relative">
|
<div className="hidden sm:flex flex-1 max-w-2xl mx-8">
|
||||||
|
<div className="relative w-full">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Search listings..."
|
placeholder="Search listings..."
|
||||||
@ -31,33 +33,59 @@ export default function Header() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-4">
|
{/* Mobile Actions */}
|
||||||
|
<div className="flex sm:hidden items-center gap-3">
|
||||||
|
<button
|
||||||
|
onClick={() => setMobileSearchOpen(!mobileSearchOpen)}
|
||||||
|
className="p-2 hover:bg-gray-100 rounded-full"
|
||||||
|
>
|
||||||
|
<Search className="h-6 w-6 text-gray-600" />
|
||||||
|
</button>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="/adt/create"
|
href="/adt/create"
|
||||||
className="flex items-center gap-2 bg-indigo-600 text-white px-4 py-2 rounded-lg hover:bg-indigo-700 transition-colors"
|
className="p-2 hover:bg-gray-100 rounded-full"
|
||||||
>
|
>
|
||||||
<PlusCircle className="h-5 w-5" />
|
<PlusCircle className="h-6 w-6 text-indigo-600" />
|
||||||
<span>Post Ad</span>
|
|
||||||
</Link>
|
</Link>
|
||||||
<button className="relative p-2 hover:bg-gray-100 rounded-full">
|
|
||||||
|
<ProfileButton onClickSignIn={() => setOpenAuthModal(true)} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Desktop Navigation */}
|
||||||
|
<div className="hidden sm:flex items-center gap-4">
|
||||||
|
<Link
|
||||||
|
href="/adt/create"
|
||||||
|
className="p-2 hover:bg-gray-100 rounded-full"
|
||||||
|
>
|
||||||
|
<PlusCircle className="h-6 w-6 text-indigo-600" />
|
||||||
|
</Link>
|
||||||
|
{/* <button className="relative p-2 hover:bg-gray-100 rounded-full">
|
||||||
<Bell className="h-6 w-6 text-gray-600" />
|
<Bell className="h-6 w-6 text-gray-600" />
|
||||||
<span className="absolute top-0 right-0 h-4 w-4 bg-red-500 rounded-full text-xs text-white flex items-center justify-center">
|
<span className="absolute top-0 right-0 h-4 w-4 bg-red-500 rounded-full text-xs text-white flex items-center justify-center">
|
||||||
2
|
2
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button> */}
|
||||||
|
|
||||||
<AuthModal open={openAuthModal} onClose={() => setOpenAuthModal(false)} />
|
<AuthModal open={openAuthModal} onClose={() => setOpenAuthModal(false)} />
|
||||||
|
|
||||||
<ProfileButton onClickSignIn={() => setOpenAuthModal(true)} />
|
<ProfileButton onClickSignIn={() => setOpenAuthModal(true)} />
|
||||||
|
|
||||||
{/* <Link
|
|
||||||
href="/profile"
|
|
||||||
className="p-2 hover:bg-gray-100 rounded-full"
|
|
||||||
>
|
|
||||||
<User className="h-6 w-6 text-gray-600" />
|
|
||||||
</Link> */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Search */}
|
||||||
|
{mobileSearchOpen && (
|
||||||
|
<div className="sm:hidden py-2 border-t">
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search listings..."
|
||||||
|
className="w-full pl-10 pr-4 py-2 rounded-lg border border-gray-200 focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
|
||||||
|
/>
|
||||||
|
<Search className="absolute left-3 top-2.5 h-5 w-5 text-gray-400" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -31,8 +31,6 @@ export const LoginForm: React.FC<Props> = ({onClose}) => {
|
|||||||
throw Error();
|
throw Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onClose?.()
|
onClose?.()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error [LOGIN]', error)
|
console.error('Error [LOGIN]', error)
|
||||||
|
|||||||
45
components/shared/modals/show-number.tsx
Normal file
45
components/shared/modals/show-number.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { Dialog } from "@/components/ui/dialog";
|
||||||
|
import { getUserSession } from "@/lib/get-user-session";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ShowNumberModal: React.FC<Props> = ({ open, onClose}) => {
|
||||||
|
|
||||||
|
const [ session, setSession ] = React.useState<any>(null)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const getSession = async () => {
|
||||||
|
const userSession = await getUserSession()
|
||||||
|
setSession(userSession)
|
||||||
|
}
|
||||||
|
getSession()
|
||||||
|
}, [])
|
||||||
|
// const session = await getUserSession()
|
||||||
|
// const handleClose = () => {
|
||||||
|
// onClose()
|
||||||
|
// }
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={handleClose}>
|
||||||
|
{/* <DialogContent className="w-[450px] bg-white p-10"> */}
|
||||||
|
{/* {
|
||||||
|
// session && (
|
||||||
|
// <h1 className="text-2xl font-bold mb-4">892348924823</h1>
|
||||||
|
// )
|
||||||
|
} */}
|
||||||
|
|
||||||
|
{/* <h1 className="text-2xl font-bold mb-4">892348924823</h1> */}
|
||||||
|
<hr />
|
||||||
|
<div className="flex gap-2">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{/* </DialogContent> */}
|
||||||
|
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -22,7 +22,7 @@ export const authOptions: AuthOptions = {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
CredentialsProvider({
|
CredentialsProvider({
|
||||||
name: 'Credentials',
|
name: 'credentials',
|
||||||
credentials: {
|
credentials: {
|
||||||
email: {label: 'Email', type: 'text'},
|
email: {label: 'Email', type: 'text'},
|
||||||
password: {label: 'Password', type: 'password'},
|
password: {label: 'Password', type: 'password'},
|
||||||
@ -71,7 +71,7 @@ export const authOptions: AuthOptions = {
|
|||||||
callbacks: {
|
callbacks: {
|
||||||
async signIn({ user, account}) {
|
async signIn({ user, account}) {
|
||||||
try {
|
try {
|
||||||
if (account?.provaider === 'credentials') {
|
if (account?.provider === 'credentials') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
"prisma:push": "prisma db push",
|
"prisma:push": "prisma db push",
|
||||||
"prisma:studio": "prisma studio",
|
"prisma:studio": "prisma studio",
|
||||||
"prisma:seed": "prisma db seed",
|
"prisma:seed": "prisma db seed",
|
||||||
"postinstall": "prisma generate"
|
"postinstall": ""
|
||||||
},
|
},
|
||||||
"prisma": {
|
"prisma": {
|
||||||
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
|
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user