Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .env
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# ===================================
# CLOUDINARY
# ===================================
NEXT_PUBLIC_CLOUD_NAME=dwqknejrz
NEXT_PUBLIC_UPLOAD_PRESET=ad-app
NEXT_PUBLIC_CLOUD_NAME=
NEXT_PUBLIC_UPLOAD_PRESET=
# ===================================

# ===================================
Expand All @@ -15,4 +15,4 @@ NEXT_PUBLIC_UPLOAD_PRESET=ad-app
# VERCEL
# ===================================
# NEXT_PUBLIC_PROJECT_HTTP_URL=
# ===================================
# ===================================
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"dependencies": {
"@hookform/resolvers": "^3.3.1",
"@prisma/client": "^5.2.0",
"@tanstack/react-query": "^4.35.3",
"@types/react": "18.2.21",
"@types/react-dom": "18.2.7",
"classnames": "^2.3.2",
Expand Down
32 changes: 32 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions src/app/add-advertisement/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { AddAdvertisementFormSkeleton } from '@/components/add-advertisement/add-advertisement-form/add-advertisement-form'
import { BreadcrumbSkeleton } from '@/components/general/breadcrumb/breadcrumb'
import { NextPage } from 'next'

const Loading: NextPage = () => {
const Loading = () => {
return (
<div className='container'>
<BreadcrumbSkeleton />
Expand Down
3 changes: 1 addition & 2 deletions src/app/add-advertisement/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import AddAdvertisement from '@/components/add-advertisement/add-advertisement'
import { NextPage } from 'next'

const AddAdvertisementPage: NextPage = () => {
const AddAdvertisementPage = () => {
return <AddAdvertisement />
}

Expand Down
2 changes: 2 additions & 0 deletions src/app/api/advertisements/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { NextResponse } from 'next/server'
import moment from 'moment-timezone'
import prisma from '@/lib/prisma'

export const dynamic = 'force-dynamic'

export async function PATCH(
request: Request,
{ params }: { params: { id: string } }
Expand Down
13 changes: 13 additions & 0 deletions src/app/api/advertisements/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import { NextResponse } from 'next/server'
import prisma from '@/lib/prisma'
export const dynamic = 'force-dynamic'

export async function GET(request: Request) {
try {
const ads = await prisma.advertisement.findMany({
orderBy: [{ lastUpdated: 'desc' }]
})

return NextResponse.json(ads)
} catch (error: any) {
return new NextResponse(error.message, { status: 500 })
}
}

export async function POST(request: Request) {
try {
Expand Down
2 changes: 1 addition & 1 deletion src/app/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface Props {
reset: () => void
}

const Error: React.FC<Props> = ({ error, reset }) => {
const Error = ({ error, reset }: Props) => {
const [show, setShow] = useState(false)
const showError = () => {
setShow(true)
Expand Down
22 changes: 12 additions & 10 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Header from '@/components/layout/header/header'
import { Inter } from 'next/font/google'
import Main from '@/components/layout/main/main'
import type { Metadata } from 'next'
import { ReactQueryProviders } from '@/context/react-query.context'
import { SortOptionProvider } from '@/context/sort-option.context'
import Toast from '@/components/general/toast/toast'
import { ToastProvider } from '@/context/toast.context'
Expand All @@ -19,23 +20,24 @@ export const metadata: Metadata = {
}
}


interface Props {
children: React.ReactNode
}

const RootLayout: React.FC<Props> = ({ children }) => {
const RootLayout = ({ children }: Props) => {
return (
<html lang='en'>
<body className={inter.className}>
<ToastProvider>
<Toast />
<Header />
<SortOptionProvider>
<Main>{children}</Main>
<Footer />
</SortOptionProvider>
</ToastProvider>
<ReactQueryProviders>
<ToastProvider>
<Toast />
<Header />
<SortOptionProvider>
<Main>{children}</Main>
<Footer />
</SortOptionProvider>
</ToastProvider>
</ReactQueryProviders>
</body>
</html>
)
Expand Down
2 changes: 1 addition & 1 deletion src/app/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface Props {
reset: () => void
}

const Error: React.FC<Props> = ({ error, reset }) => {
const Error = ({ error, reset }: Props) => {
return (
<div className='textCenter'>
<h2 className='mb3xl'>Sayfa bulunamadı!</h2>
Expand Down
5 changes: 1 addition & 4 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import HomePage from '@/components/homepage/homepage'
import { NextPage } from 'next'

export const dynamic = 'force-dynamic'

const Home: NextPage = () => {
const Home = () => {
return <HomePage />
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ import { checkFile, uploadToCloudinary } from '@/utils/helpers'
import { Button } from '@/components/general/button/button'
import Icon from '@/components/general/icon/icon'
import { Skeleton } from '@/components/general/skeleton/skeleton'
import { addAdvertisements } from '@/lib/query-service'
import classNames from 'classnames'
import styles from './styles.module.scss'
import { useForm } from 'react-hook-form'
import { useMutation } from '@tanstack/react-query'
import { useQueryClientInstance } from '@/context/query-client.context'
// Because of using App dir, we need to use next/navigation instead of next/router
// See: https://nextjs.org/docs/messages/next-router-not-mounted
import { useRouter } from 'next/navigation'
import { useToast } from '@/hooks/use-toast'
import { yupResolver } from '@hookform/resolvers/yup'

export const AddAdvertisementForm: React.FC = () => {
export const AddAdvertisementForm = () => {
const [imageUploadLabel, setImageUploadLabel] = useState<string>('Yükle')
const [isLoading, setIsLoading] = useState<boolean>(false)
const formOptions = {
Expand All @@ -41,6 +44,22 @@ export const AddAdvertisementForm: React.FC = () => {
} = useForm(formOptions)
const { errors } = formState

const { queryClient } = useQueryClientInstance()

const { isLoading: dataIsLoading, mutate } = useMutation({
mutationFn: addAdvertisements,
onSuccess: () => {
showToast(
'İlan başarıyla kaydedilmiştir. Ana sayfaya yönlendiriliyorsunuz',
'success'
)
queryClient.invalidateQueries({ queryKey: ['ads'] })
},
onError: () => {
showToast('İlan eklenirken bir sorun oluştu.', 'error')
}
})

const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
setIsLoading(true)

Expand All @@ -66,25 +85,15 @@ export const AddAdvertisementForm: React.FC = () => {
}

const onSubmit = async () => {
const response = await fetch('/api/advertisements', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ...watch() })
})

if (response.ok) {
showToast(
'İlan başarıyla kaydedilmiştir. Ana sayfaya yönlendiriliyorsunuz',
'success'
)
} else {
const error = await response.text()
showToast(error, 'error')
}
reset()
setImageUploadLabel('Yükle')
router.refresh()
router.push('/')
mutate(
{ ...watch() },
{
onSuccess: () => {
setImageUploadLabel('Yükle')
router.push('/')
}
}
)
}

return (
Expand Down Expand Up @@ -164,7 +173,7 @@ export const AddAdvertisementForm: React.FC = () => {
</div>
<Button
type='submit'
disabled={isLoading}
disabled={isLoading || dataIsLoading}
className={styles.submitButton}
>
{isLoading ? <Icon name='Spinner' size={16} /> : 'KAYDET'}
Expand All @@ -174,7 +183,7 @@ export const AddAdvertisementForm: React.FC = () => {
)
}

export const AddAdvertisementFormSkeleton: React.FC = () => {
export const AddAdvertisementFormSkeleton = () => {
return (
<div className='centerAlignedItems ptXl'>
<div className={classNames(styles.wrapper, 'pl2xl')}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
}

.imageUploadButton {
height: unset;
height: initial;
display: inline-flex;
gap: $space-sm;
align-items: center;
Expand Down
2 changes: 1 addition & 1 deletion src/components/add-advertisement/add-advertisement.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AddAdvertisementForm } from './add-advertisement-form/add-advertisement-form'
import { Breadcrumb } from '@/components/general/breadcrumb/breadcrumb'

const AddAdvertisement: React.FC = () => {
const AddAdvertisement = () => {
return (
<div className='container'>
<Breadcrumb page='yeni ilan' subtitle='ekle' />
Expand Down
6 changes: 2 additions & 4 deletions src/components/general/breadcrumb/breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface Props {
children?: React.ReactNode
}

export const Breadcrumb: React.FC<Props> = ({ page, subtitle, children }) => {
export const Breadcrumb = ({ page, subtitle, children }: Props) => {
return (
<div className={styles.wrapper}>
<div className={styles.title}>
Expand All @@ -24,9 +24,7 @@ interface BreadcrumbSkeletonProps {
children?: React.ReactNode
}

export const BreadcrumbSkeleton: React.FC<BreadcrumbSkeletonProps> = ({
children
}) => {
export const BreadcrumbSkeleton = ({ children }: BreadcrumbSkeletonProps) => {
return (
<div className={styles.wrapper}>
<div className={styles.titleSkeleton}>
Expand Down
4 changes: 2 additions & 2 deletions src/components/general/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ interface Props {
type?: 'button' | 'submit' | 'reset'
}

export const Button: React.FC<Props> = ({
export const Button = ({
className,
disabled,
onClick,
children,
type
}) => {
}: Props) => {
return (
<button
onClick={onClick}
Expand Down
2 changes: 1 addition & 1 deletion src/components/general/icon/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface Props {
className?: string
}

const Icon: React.FC<Props> = ({ name, size, className }) => {
const Icon = ({ name, size, className }: Props) => {
const Component = iconNameMap[name]

return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/general/skeleton/skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ interface Props {
className?: string
}

export const Skeleton: React.FC<Props> = ({ className }) => {
export const Skeleton = ({ className }: Props) => {
return <div className={classNames(styles.skeleton, className)} />
}
2 changes: 1 addition & 1 deletion src/components/general/toast/toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ToastContext } from '@/context/toast.context'
import classNames from 'classnames'
import styles from './styles.module.scss'

const Toast: React.FC = () => {
const Toast = () => {
const {
state: { display, type, message }
} = useContext(ToastContext)
Expand Down
Loading