{"id":35000,"date":"2025-11-24T17:31:55","date_gmt":"2025-11-24T14:31:55","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/"},"modified":"2025-11-24T17:31:55","modified_gmt":"2025-11-24T14:31:55","slug":"modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/","title":{"rendered":"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?"},"content":{"rendered":"<p>Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme<\/p>\n<p>G\u00fcn\u00fcm\u00fcz rekabet\u00e7i dijital d\u00fcnyas\u0131nda, emlak sekt\u00f6r\u00fcnde faaliyet g\u00f6steren i\u015fletmelerin ba\u015far\u0131l\u0131 olabilmesi i\u00e7in h\u0131zl\u0131, g\u00fcvenli ve kullan\u0131c\u0131 dostu web uygulamalar\u0131na sahip olmas\u0131 art\u0131k bir zorunluluk haline geldi. Peki, s\u0131f\u0131rdan ba\u015flayarak modern web teknolojileriyle, hem geli\u015ftirici deneyimini hem de son kullan\u0131c\u0131 memnuniyetini en \u00fcst d\u00fczeye \u00e7\u0131karan bir emlak uygulamas\u0131n\u0131 nas\u0131l in\u015fa edebilirsiniz? Bu rehberde, pop\u00fcler ve g\u00fc\u00e7l\u00fc ara\u00e7lar olan Next.js, Prisma, BetterAuth ve ShadCN\/UI&#8217;\u0131n sundu\u011fu imkanlar\u0131 ke\u015ffederek, hayalinizdeki emlak uygulamas\u0131n\u0131 ad\u0131m ad\u0131m hayata ge\u00e7irme s\u00fcrecini detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu teknoloji y\u0131\u011f\u0131n\u0131, size sadece bir web sitesi de\u011fil, gelece\u011fe haz\u0131r, \u00f6l\u00e7eklenebilir ve y\u00f6netimi kolay bir platform sunacak.<\/p>\n<p>Emlak sekt\u00f6r\u00fc, son y\u0131llarda dijitalle\u015fmenin en h\u0131zl\u0131 ya\u015fand\u0131\u011f\u0131 alanlardan biri haline geldi. Potansiyel al\u0131c\u0131lar veya kirac\u0131lar art\u0131k bir emlak ofisine gitmeden \u00f6nce internet \u00fczerinden kapsaml\u0131 ara\u015ft\u0131rmalar yap\u0131yor, ilanlar\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131yor ve sanal turlar talep ediyorlar. Bu ba\u011flamda, bir emlak web uygulamas\u0131n\u0131n performans\u0131, aray\u00fcz\u00fcn\u00fcn kullan\u0131m kolayl\u0131\u011f\u0131 ve sundu\u011fu \u00f6zellikler, do\u011frudan m\u00fc\u015fteri \u00e7ekme ve i\u015flem tamamlama oranlar\u0131n\u0131 etkiliyor. Geleneksel web siteleri genellikle yava\u015f y\u00fcklenme s\u00fcreleri, g\u00fcncel olmayan tasar\u0131mlar ve yetersiz g\u00fcvenlik \u00f6nlemleri nedeniyle kullan\u0131c\u0131lar\u0131 ka\u00e7\u0131rma riski ta\u015f\u0131rken, modern bir yakla\u015f\u0131m bu dezavantajlar\u0131 ortadan kald\u0131r\u0131yor.<\/p>\n<p>Bu noktada, Next.js, Prisma, BetterAuth ve ShadCN\/UI gibi yenilik\u00e7i teknolojilerin bir araya gelmesi, geli\u015ftiricilere ve i\u015fletmelere e\u015fsiz avantajlar sunar. Next.js, \u00f6zellikle SEO performans\u0131n\u0131 art\u0131ran sunucu taraf\u0131 render (SSR) ve statik site olu\u015fturma (SSG) yetenekleriyle, emlak ilanlar\u0131n\u0131n arama motorlar\u0131nda daha g\u00f6r\u00fcn\u00fcr olmas\u0131n\u0131 sa\u011flar. Ayr\u0131ca, h\u0131zl\u0131 sayfa ge\u00e7i\u015fleri ve optimize edilmi\u015f g\u00f6rseller sayesinde kullan\u0131c\u0131lar\u0131n uygulamada daha uzun s\u00fcre kalmas\u0131na yard\u0131mc\u0131 olur. Bir emlak uygulamas\u0131nda binlerce hatta y\u00fcz binlerce ilan olabilece\u011fi d\u00fc\u015f\u00fcn\u00fcld\u00fc\u011f\u00fcnde, performans kritik bir \u00f6neme sahiptir. Kullan\u0131c\u0131lar, bir ilan\u0131 incelerken yava\u015f bir y\u00fckleme deneyimiyle kar\u015f\u0131la\u015ft\u0131klar\u0131nda, genellikle ba\u015fka bir siteye y\u00f6nelirler. Next.js&#8217;in sa\u011flad\u0131\u011f\u0131 performans optimizasyonlar\u0131, bu riski minimize eder.<\/p>\n<p>Veritaban\u0131 y\u00f6netimi, emlak uygulamalar\u0131n\u0131n temelini olu\u015fturur. \u0130lanlar, kullan\u0131c\u0131 bilgileri, rezervasyonlar, mesajlar ve daha bir\u00e7ok veri, g\u00fcvenli ve verimli bir \u015fekilde depolanmal\u0131 ve eri\u015filebilir olmal\u0131d\u0131r. Prisma, bu karma\u015f\u0131k s\u00fcreci basitle\u015ftiren g\u00fc\u00e7l\u00fc bir ORM (Object-Relational Mapper) arac\u0131d\u0131r. Type-safe (t\u00fcr g\u00fcvenli) yap\u0131s\u0131 sayesinde, geli\u015ftirme s\u00fcrecinde olu\u015fabilecek bir\u00e7ok hatay\u0131 \u00f6nler ve veri modelleri \u00fczerinde \u00e7al\u0131\u015fmay\u0131 \u00e7ok daha keyifli hale getirir. \u00d6rne\u011fin, bir ilan\u0131n fiyat alan\u0131 say\u0131sal bir de\u011fer beklerken metin girilmeye \u00e7al\u0131\u015f\u0131ld\u0131\u011f\u0131nda, Prisma bunu derleme a\u015famas\u0131nda yakalayarak, \u00fcretim ortam\u0131nda ya\u015fanabilecek potansiyel hatalar\u0131 engeller. Bu da geli\u015ftirme s\u00fcresini k\u0131salt\u0131r ve daha sa\u011flam bir uygulama ortaya koyar. Veritaban\u0131 \u015femas\u0131 de\u011fi\u015fikliklerini y\u00f6netmek i\u00e7in kullan\u0131lan migrasyon \u00f6zellikleri de, uygulaman\u0131n evrimi boyunca veritaban\u0131n\u0131n tutarl\u0131 kalmas\u0131n\u0131 garanti eder. Bu sayede, yeni \u00f6zellikler eklemek veya mevcutlar\u0131 de\u011fi\u015ftirmek \u00e7ok daha g\u00fcvenli ve kontroll\u00fc bir s\u00fcre\u00e7 haline gelir.<\/p>\n<p>Emlak uygulamalar\u0131nda kullan\u0131c\u0131 g\u00fcvenli\u011fi ve kimlik do\u011frulama s\u00fcre\u00e7leri hayati \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131n ki\u015fisel bilgilerini, ilan detaylar\u0131n\u0131 ve hatta \u00f6deme bilgilerini i\u00e7eren hassas veriler, k\u00f6t\u00fc niyetli sald\u0131r\u0131lara kar\u015f\u0131 korunmal\u0131d\u0131r. BetterAuth, bu noktada devreye girerek, geli\u015ftiricilerin kimlik do\u011frulama ve yetkilendirme s\u00fcre\u00e7lerini kolayca entegre etmesini sa\u011flar. Geleneksel kullan\u0131c\u0131 ad\u0131\/\u015fifre, sosyal medya entegrasyonlar\u0131, sihirli ba\u011flant\u0131lar (magic links) gibi farkl\u0131 kimlik do\u011frulama y\u00f6ntemlerini destekleyebilir. Ayr\u0131ca, rol tabanl\u0131 eri\u015fim kontrol\u00fc (RBAC) ile y\u00f6neticilerin, emlak dan\u0131\u015fmanlar\u0131n\u0131n ve normal kullan\u0131c\u0131lar\u0131n uygulamadaki farkl\u0131 b\u00f6l\u00fcmlere eri\u015fim yetkilerini hassas bir \u015fekilde tan\u0131mlamay\u0131 m\u00fcmk\u00fcn k\u0131lar. Bu, \u00f6zellikle bir emlak dan\u0131\u015fman\u0131n\u0131n yaln\u0131zca kendi ilanlar\u0131n\u0131 d\u00fczenleyebilmesi veya bir y\u00f6neticinin t\u00fcm ilanlar\u0131 y\u00f6netebilmesi gibi senaryolarda b\u00fcy\u00fck kolayl\u0131k sa\u011flar. Uygulama genelinde g\u00fcvenli\u011fi art\u0131r\u0131rken, geli\u015ftiricilerin g\u00fcvenlik a\u00e7\u0131klar\u0131n\u0131 manuel olarak ele alma y\u00fck\u00fcn\u00fc hafifletir.<\/p>\n<p>Son olarak, kullan\u0131c\u0131 deneyimi, bir uygulaman\u0131n ba\u015far\u0131s\u0131n\u0131 do\u011frudan etkileyen bir fakt\u00f6rd\u00fcr. ShadCN\/UI, geli\u015ftiricilere modern, eri\u015filebilir ve y\u00fcksek performansl\u0131 kullan\u0131c\u0131 aray\u00fczleri olu\u015fturma konusunda benzersiz bir esneklik sunar. Klasik UI k\u00fct\u00fcphanelerinin aksine, ShadCN\/UI size \u00f6nceden derlenmi\u015f bile\u015fenler yerine, kopyalay\u0131p projenize entegre edebilece\u011finiz, \u00f6zelle\u015ftirilebilir bile\u015fen kodlar\u0131 sa\u011flar. Bu yakla\u015f\u0131m, uygulaman\u0131n tasar\u0131m dilini tamamen kontrol etmenize ve markan\u0131za \u00f6zg\u00fc bir g\u00f6r\u00fcn\u00fcm elde etmenize olanak tan\u0131r. Tailwind CSS ile m\u00fckemmel entegrasyonu sayesinde, h\u0131zla prototip olu\u015fturabilir ve responsive tasar\u0131mlar\u0131 kolayca uygulayabilirsiniz. \u00d6rne\u011fin, emlak ilanlar\u0131n\u0131 listeleyen kartlar\u0131n farkl\u0131 ekran boyutlar\u0131na g\u00f6re d\u00fczenini otomatik olarak ayarlamas\u0131, mobil cihazlarda da sorunsuz bir deneyim sunar. Bir emlak uygulamas\u0131nda g\u00f6rsellik \u00f6n planda oldu\u011fundan, ShadCN\/UI ile olu\u015fturulan \u015f\u0131k ve tutarl\u0131 aray\u00fcz, kullan\u0131c\u0131lar\u0131n uygulaman\u0131zda daha fazla zaman ge\u00e7irmesini ve ilanlar\u0131 daha rahat incelemesini sa\u011flar. Bu d\u00f6rt teknolojinin birle\u015fimi, modern emlak uygulamas\u0131 geli\u015ftirme s\u00fcrecini hem daha verimli hem de daha keyifli hale getirir.<\/p>\n<h2>Teknolojinin Temel Ta\u015flar\u0131: Next.js, Prisma, BetterAuth ve ShadCN\/UI Nedir?<\/h2>\n<p>Bir emlak uygulamas\u0131 geli\u015ftirmeye ba\u015flamadan \u00f6nce, kullanaca\u011f\u0131m\u0131z ara\u00e7lar\u0131n temel \u00f6zelliklerini ve neden bu kadar pop\u00fcler olduklar\u0131n\u0131 anlamak b\u00fcy\u00fck \u00f6nem ta\u015f\u0131r. Bu b\u00f6l\u00fcmde, projemizin temelini olu\u015fturan bu d\u00f6rt teknolojiyi yak\u0131ndan tan\u0131yaca\u011f\u0131z.<\/p>\n<h3>Next.js: React Geli\u015ftirmede Yeni Bir Standart m\u0131 Sunuyor?<\/h3>\n<p>Next.js, Vercel taraf\u0131ndan geli\u015ftirilen a\u00e7\u0131k kaynakl\u0131 bir React \u00e7er\u00e7evesidir. Geli\u015ftiricilere, React uygulamalar\u0131n\u0131 sunucu taraf\u0131nda render etme (SSR), statik site olu\u015fturma (SSG) ve art\u0131ml\u0131 statik yenileme (ISR) gibi geli\u015fmi\u015f render yetenekleriyle geli\u015ftirmeleri i\u00e7in g\u00fc\u00e7l\u00fc bir platform sunar. Bu yetenekler, \u00f6zellikle SEO performans\u0131, ba\u015flang\u0131\u00e7 y\u00fckleme h\u0131z\u0131 ve genel kullan\u0131c\u0131 deneyimi a\u00e7\u0131s\u0131ndan geleneksel istemci taraf\u0131 render (CSR) yakla\u015f\u0131mlar\u0131na g\u00f6re \u00f6nemli avantajlar sa\u011flar.<\/p>\n<p>Bir emlak uygulamas\u0131nda, binlerce ilan\u0131n Google gibi arama motorlar\u0131nda iyi s\u0131ralanmas\u0131 kritik bir pazarlama stratejisidir. Next.js&#8217;in SSR ve SSG \u00f6zellikleri, bu ilanlar\u0131n HTML i\u00e7eri\u011fini sunucuda olu\u015fturarak arama motoru botlar\u0131n\u0131n sayfalar\u0131 daha kolay taramas\u0131n\u0131 ve indekslemesini sa\u011flar. \u00d6rne\u011fin, bir ilan\u0131n detay sayfas\u0131 SSG ile \u00f6nceden olu\u015fturulabilir ve CDN&#8217;den \u00e7ok h\u0131zl\u0131 bir \u015fekilde sunularak ultra d\u00fc\u015f\u00fck y\u00fckleme s\u00fcreleri elde edilebilir. E\u011fer ilanlar s\u0131k\u00e7a g\u00fcncelleniyorsa, ISR (Incremental Static Regeneration) ile belirli aral\u0131klarla arka planda sayfalar\u0131n yeniden olu\u015fturulmas\u0131n\u0131 sa\u011flayarak, her zaman g\u00fcncel veriyi, statik bir sayfan\u0131n performans\u0131 ile sunabiliriz. Ayr\u0131ca, Next.js&#8217;in dosya tabanl\u0131 y\u00f6nlendirme sistemi, URL yap\u0131lar\u0131n\u0131 y\u00f6netmeyi basitle\u015ftirir; her dosya veya klas\u00f6r, belirli bir rota ile e\u015fle\u015ferek geli\u015ftiricilerin kod organizasyonunu kolayla\u015ft\u0131r\u0131r. Dahili API Rotalar\u0131 ise, ayr\u0131 bir backend sunucusuna ihtiya\u00e7 duymadan do\u011frudan Next.js projesi i\u00e7inde API endpoint&#8217;leri olu\u015fturman\u0131za olanak tan\u0131r, bu da monolitik bir geli\u015ftirme deneyimi sunar ve \u00f6zellikle k\u00fc\u00e7\u00fck ve orta \u00f6l\u00e7ekli projelerde geli\u015ftirme h\u0131z\u0131n\u0131 art\u0131r\u0131r.<\/p>\n<h3>Prisma: Veritaban\u0131 Y\u00f6netimini Nas\u0131l Basitle\u015ftirir ve Geli\u015ftirici Verimlili\u011fini Art\u0131r\u0131r?<\/h3>\n<p>Prisma, Node.js ve TypeScript uygulamalar\u0131 i\u00e7in yeni nesil bir ORM (Object-Relational Mapper) arac\u0131d\u0131r. Geleneksel ORM&#8217;lere k\u0131yasla daha modern bir yakla\u015f\u0131m sunarak, veritaban\u0131 i\u015flemlerini daha t\u00fcr g\u00fcvenli, verimli ve sezgisel hale getirir. Prisma, geli\u015ftiricilerin veritaban\u0131 \u015femalar\u0131n\u0131 deklaratif bir \u015fekilde tan\u0131mlamalar\u0131na olanak tan\u0131yan \u00f6zel bir \u015fema dili kullan\u0131r. Bu \u015fema dosyas\u0131, uygulaman\u0131z\u0131n veritaban\u0131 modellerini ve aralar\u0131ndaki ili\u015fkileri tek bir merkezden y\u00f6netmenizi sa\u011flar.<\/p>\n<p>Emlak uygulamas\u0131nda kullan\u0131c\u0131lar, ilanlar, emlak\u00e7\u0131lar ve hatta rezervasyonlar gibi bir\u00e7ok farkl\u0131 veri modeli bulunur. Prisma, bu modelleri TypeScript entegrasyonu sayesinde t\u00fcr g\u00fcvenli bir \u015fekilde y\u00f6netmenizi sa\u011flar. Yani, veritaban\u0131ndan bir &#8220;\u0130lan&#8221; nesnesi \u00e7ekti\u011finizde, o nesnenin hangi \u00f6zelliklere (ba\u015fl\u0131k, a\u00e7\u0131klama, fiyat, foto\u011fraflar vb.) sahip oldu\u011funu ve bu \u00f6zelliklerin veri tiplerini (string, number, boolean, Date) TypeScript otomatik olarak bilir. Bu, geli\u015ftirme s\u0131ras\u0131nda potansiyel hatalar\u0131 (\u00f6rne\u011fin, bir say\u0131y\u0131 string olarak kullanmaya \u00e7al\u0131\u015fmak) derleme a\u015famas\u0131nda yakalamaya yard\u0131mc\u0131 olur, b\u00f6ylece \u00e7al\u0131\u015fma zaman\u0131 hatalar\u0131 azal\u0131r. Prisma ayr\u0131ca, veritaban\u0131 \u015femas\u0131ndaki de\u011fi\u015fiklikleri uygulaman\u0131za ta\u015f\u0131yan migrasyon sistemine sahiptir. \u00d6rne\u011fin, bir ilana yeni bir &#8220;banyo_say\u0131s\u0131&#8221; alan\u0131 eklemek istedi\u011finizde, Prisma CLI (Komut Sat\u0131r\u0131 Aray\u00fcz\u00fc) arac\u0131l\u0131\u011f\u0131yla kolayca bir migrasyon dosyas\u0131 olu\u015fturabilir ve bu de\u011fi\u015fikli\u011fi veritaban\u0131n\u0131za uygulayabilirsiniz. Destekledi\u011fi veritabanlar\u0131 aras\u0131nda PostgreSQL, MySQL, SQLite, SQL Server ve MongoDB gibi pop\u00fcler se\u00e7enekler bulunur, bu da projenizin ihtiya\u00e7lar\u0131na g\u00f6re esneklik sa\u011flar.<\/p>\n<h3>BetterAuth: Kimlik Do\u011frulamay\u0131 Neden Daha G\u00fcvenli ve Daha H\u0131zl\u0131 Hale Getirir?<\/h3>\n<p>Kimlik do\u011frulama (authentication) ve yetkilendirme (authorization), modern web uygulamalar\u0131n\u0131n olmazsa olmaz\u0131d\u0131r. BetterAuth (veya benzeri robust bir kimlik do\u011frulama \u00e7\u00f6z\u00fcm\u00fc), kullan\u0131c\u0131lar\u0131n g\u00fcvenli bir \u015fekilde kaydolmas\u0131n\u0131, giri\u015f yapmas\u0131n\u0131 ve yetkilerine g\u00f6re uygulamadaki belirli kaynaklara eri\u015fmesini sa\u011flamak i\u00e7in tasarlanm\u0131\u015ft\u0131r. Bu t\u00fcr \u00e7\u00f6z\u00fcmler, geli\u015ftiricilerin s\u0131f\u0131rdan bir kimlik do\u011frulama sistemi kurma y\u00fck\u00fcn\u00fc ortadan kald\u0131rarak, g\u00fcvenlik en iyi uygulamalar\u0131n\u0131 otomatik olarak projenize entegre etmenizi sa\u011flar.<\/p>\n<p>Emlak uygulamas\u0131nda, farkl\u0131 kullan\u0131c\u0131 rolleri (\u00f6rne\u011fin, y\u00f6netici, emlak\u00e7\u0131, normal kullan\u0131c\u0131) ve bu rollere \u00f6zg\u00fc eri\u015fim yetkileri bulunur. BetterAuth, bu rol tabanl\u0131 eri\u015fim kontrol\u00fcn\u00fc kolayca yap\u0131land\u0131rman\u0131za olanak tan\u0131r. Bir emlak\u00e7\u0131, yaln\u0131zca kendi ilanlar\u0131n\u0131 olu\u015fturabilir, d\u00fczenleyebilir veya silebilirken, bir y\u00f6netici t\u00fcm ilanlar \u00fczerinde tam kontrole sahip olabilir. Kullan\u0131c\u0131lar\u0131n g\u00fcvenli \u015fifre saklama, token tabanl\u0131 oturum y\u00f6netimi (JWT gibi), \u00e7ok fakt\u00f6rl\u00fc kimlik do\u011frulama (MFA) ve \u015fifre s\u0131f\u0131rlama gibi \u00f6zellikler, BetterAuth taraf\u0131ndan otomatik olarak sa\u011flan\u0131r. Ayr\u0131ca, Google, Facebook gibi \u00fc\u00e7\u00fcnc\u00fc taraf servislerle sosyal medya giri\u015flerini entegre etme yetene\u011fi, kullan\u0131c\u0131lar\u0131n kay\u0131t ve giri\u015f s\u00fcrecini daha da basitle\u015ftirir. Bu, geli\u015ftiricilerin g\u00fcvenlik a\u00e7\u0131klar\u0131n\u0131 manuel olarak ele alma endi\u015fesini azalt\u0131r ve uygulaman\u0131n \u00e7ekirdek \u00f6zelliklerine odaklanmalar\u0131n\u0131 sa\u011flar. Sonu\u00e7 olarak, BetterAuth projenize hem sa\u011flam bir g\u00fcvenlik katman\u0131 ekler hem de kullan\u0131c\u0131lar\u0131n kolayca eri\u015fim sa\u011flamas\u0131na olanak tan\u0131r.<\/p>\n<h3>ShadCN\/UI: Geli\u015ftirici Deneyimini ve Tasar\u0131m\u0131 Nas\u0131l \u0130yile\u015ftirir?<\/h3>\n<p>ShadCN\/UI, bir bile\u015fen k\u00fct\u00fcphanesinden ziyade, Tailwind CSS ve Radix UI \u00fczerine kurulu, tamamen \u00f6zelle\u015ftirilebilir bile\u015fenlerin bir koleksiyonudur. Geli\u015ftiricilere, kendi projelerine do\u011frudan kopyalay\u0131p yap\u0131\u015ft\u0131rabilecekleri, eri\u015filebilir ve modern UI bile\u015fenleri sunar. Bu yakla\u015f\u0131m, geleneksel UI k\u00fct\u00fcphanelerinin aksine, size tam bir tasar\u0131m \u00f6zg\u00fcrl\u00fc\u011f\u00fc ve esneklik sa\u011flar, \u00e7\u00fcnk\u00fc her bile\u015fenin koduna tam eri\u015fiminiz olur ve diledi\u011finiz gibi de\u011fi\u015ftirebilirsiniz.<\/p>\n<p>Emlak uygulamalar\u0131nda estetik ve i\u015flevsellik el ele gitmelidir. ShadCN\/UI ile olu\u015fturulan bile\u015fenler, modern ve \u015f\u0131k bir g\u00f6r\u00fcn\u00fcm sunarken, ayn\u0131 zamanda eri\u015filebilirlik standartlar\u0131na uygun olarak tasarlanm\u0131\u015ft\u0131r. Butonlar, input alanlar\u0131, kartlar, diyalog kutular\u0131 (modallar), navigasyon men\u00fcleri gibi temel UI elemanlar\u0131n\u0131 h\u0131zl\u0131ca olu\u015fturabilir ve projenizin tasar\u0131m diline uygun hale getirebilirsiniz. \u00d6rne\u011fin, ilanlar\u0131 listeleyen kartlar, ShadCN\/UI&#8217;\u0131n <code>Card<\/code> bile\u015fenleri kullan\u0131larak h\u0131zl\u0131ca olu\u015fturulabilir ve Tailwind CSS s\u0131n\u0131flar\u0131yla kolayca stilize edilebilir. Uygulaman\u0131z\u0131n renk paletini, tipografisini ve di\u011fer g\u00f6rsel \u00f6zelliklerini merkezi bir tema dosyas\u0131nda tan\u0131mlayarak, t\u00fcm bile\u015fenlerin tutarl\u0131 bir \u015fekilde g\u00f6r\u00fcnmesini sa\u011flayabilirsiniz. Bu, \u00f6zellikle b\u00fcy\u00fck \u00f6l\u00e7ekli projelerde veya birden fazla geli\u015ftiricinin \u00e7al\u0131\u015ft\u0131\u011f\u0131 ekiplerde tasar\u0131m tutarl\u0131l\u0131\u011f\u0131n\u0131 korumak i\u00e7in hayati \u00f6neme sahiptir. ShadCN\/UI, size sadece g\u00fczel g\u00f6r\u00fcnen de\u011fil, ayn\u0131 zamanda bak\u0131m\u0131 kolay ve performansl\u0131 bir kullan\u0131c\u0131 aray\u00fcz\u00fc olu\u015fturma g\u00fcc\u00fc verir.<\/p>\n<h2>Proje Kurulumu ve Temel Yap\u0131land\u0131rma Ad\u0131mlar\u0131 Nelerdir?<\/h2>\n<p>Herhangi bir b\u00fcy\u00fck projeye ba\u015flarken, sa\u011flam bir temel olu\u015fturmak esast\u0131r. Emlak uygulamam\u0131z\u0131 bu g\u00fc\u00e7l\u00fc teknoloji y\u0131\u011f\u0131n\u0131yla in\u015fa etmek i\u00e7in ilk ad\u0131mlar\u0131m\u0131z, projenin ba\u015flat\u0131lmas\u0131 ve temel bile\u015fenlerin yap\u0131land\u0131r\u0131lmas\u0131 olacakt\u0131r. Bu s\u00fcre\u00e7, Next.js projesinin olu\u015fturulmas\u0131ndan, veritaban\u0131 ba\u011flant\u0131s\u0131na ve kullan\u0131c\u0131 aray\u00fcz\u00fc entegrasyonuna kadar bir dizi \u00f6nemli ad\u0131m\u0131 i\u00e7erir. Bu ad\u0131mlar\u0131 do\u011fru bir \u015fekilde takip etmek, gelecekteki geli\u015ftirmelerin sorunsuz ilerlemesini sa\u011flar.<\/p>\n<h3>Next.js Projesinin Ba\u015flat\u0131lmas\u0131 ve Temel Yap\u0131land\u0131rma<\/h3>\n<p>Yeni bir Next.js projesi olu\u015fturmak olduk\u00e7a basittir. Terminalinizde a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131rarak ba\u015flayabiliriz. Bu komut, bize projenin ad\u0131 ve kullan\u0131lacak \u00f6zellikler (TypeScript, ESLint, Tailwind CSS vb.) hakk\u0131nda baz\u0131 sorular soracakt\u0131r. T\u00fcm sorulara evet diyerek varsay\u0131lan se\u00e7enekleri kabul etmek genellikle iyi bir ba\u015flang\u0131\u00e7t\u0131r, \u00f6zellikle ShadCN\/UI, Tailwind CSS ile iyi anla\u015ft\u0131\u011f\u0131 i\u00e7in bu kurulum bizim i\u00e7in idealdir.<\/p>\n<pre><code>\nnpx create-next-app@latest emlak-uygulamasi --typescript --tailwind --eslint\n<\/pre>\n<p><\/code><\/p>\n<p>Proje olu\u015fturulduktan sonra, projenin dizinine ge\u00e7i\u015f yap\u0131n ve geli\u015ftirme sunucusunu ba\u015flat\u0131n:<\/p>\n<pre><code>\ncd emlak-uygulamasi\nnpm run dev\n<\/pre>\n<p><\/code><\/p>\n<p>Art\u0131k taray\u0131c\u0131n\u0131zda <code>http:\/\/localhost:3000<\/code> adresine giderek varsay\u0131lan Next.js uygulamas\u0131n\u0131 g\u00f6rebilirsiniz. Projemizin temel yap\u0131s\u0131 art\u0131k haz\u0131r.<\/p>\n<h3>Prisma Kurulumu, Veritaban\u0131 Ba\u011flant\u0131s\u0131 ve \u0130lk Model Tan\u0131m\u0131<\/h3>\n<p>Prisma'y\u0131 projemize entegre etmek i\u00e7in \u00f6ncelikle gerekli paketleri kurmal\u0131y\u0131z:<\/p>\n<pre><code>\nnpm install prisma @prisma\/client\nnpm install -D prisma\nnpx prisma init\n<\/pre>\n<p><\/code><\/p>\n<p><code>npx prisma init<\/code> komutu, projemizin k\u00f6k dizininde bir <code>prisma<\/code> klas\u00f6r\u00fc ve i\u00e7inde <code>schema.prisma<\/code> dosyas\u0131n\u0131 olu\u015fturur. Ayr\u0131ca, <code>.env<\/code> dosyan\u0131z\u0131 da g\u00fcncelleyecektir. <code>schema.prisma<\/code> dosyas\u0131nda veritaban\u0131 sa\u011flay\u0131c\u0131s\u0131n\u0131 ve ba\u011flant\u0131 URL'sini tan\u0131mlamam\u0131z gerekiyor. \u00d6rne\u011fin, PostgreSQL kullan\u0131yorsak:<\/p>\n<pre><code>\n\/\/ prisma\/schema.prisma\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\ndatasource db {\n  provider = \"postgresql\" \/\/ Veya \"mysql\", \"sqlite\", \"mongodb\"\n  url      = env(\"DATABASE_URL\")\n}\n\nmodel User {\n  id        String   @id @default(uuid())\n  email     String   @unique\n  password  String\n  name      String?\n  createdAt DateTime @default(now())\n  updatedAt DateTime @updatedAt\n  listings  Listing[]\n}\n\nmodel Listing {\n  id          String    @id @default(uuid())\n  title       String\n  description String\n  price       Float\n  address     String\n  city        String\n  country     String\n  bedrooms    Int\n  bathrooms   Int\n  area        Float\n  imageUrl    String[]\n  isPublished Boolean   @default(false)\n  createdAt   DateTime  @default(now())\n  updatedAt   DateTime  @updatedAt\n  author      User      @relation(fields: [authorId], references: [id])\n  authorId    String\n}\n<\/pre>\n<p><\/code><\/p>\n<p><code>.env<\/code> dosyan\u0131za veritaban\u0131 ba\u011flant\u0131 dizenizi ekleyin:<\/p>\n<pre><code>\nDATABASE_URL=\"postgresql:\/\/kullanici:sifre@localhost:5432\/emlakdb?schema=public\"\n<\/pre>\n<p><\/code><\/p>\n<p>Modelleri tan\u0131mlad\u0131ktan sonra, veritaban\u0131na uygulamak i\u00e7in migrasyon olu\u015fturun ve \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code>\nnpx prisma migrate dev --name init_schema\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut, veritaban\u0131n\u0131zda <code>User<\/code> ve <code>Listing<\/code> tablolar\u0131n\u0131 olu\u015fturacakt\u0131r. Ard\u0131ndan, Prisma Client'\u0131 olu\u015fturmak i\u00e7in a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code>\nnpx prisma generate\n<\/pre>\n<p><\/code><\/p>\n<p>Art\u0131k Prisma, veritaban\u0131n\u0131zla etkile\u015fim kurmaya haz\u0131r.<\/p>\n<h3>BetterAuth Entegrasyonu \u0130\u00e7in Genel Ad\u0131mlar<\/h3>\n<p>BetterAuth'un kurulumu, kulland\u0131\u011f\u0131n\u0131z \u00f6zel pakete veya hizmete g\u00f6re de\u011fi\u015fiklik g\u00f6sterebilir. Genellikle, bir kimlik do\u011frulama \u00e7\u00f6z\u00fcm\u00fcn\u00fc entegre etmek i\u00e7in a\u015fa\u011f\u0131daki ad\u0131mlar izlenir:<\/p>\n<ol>\n<li><strong>Paket Kurulumu:<\/strong> BetterAuth veya benzeri bir k\u00fct\u00fcphaneyi (\u00f6rne\u011fin NextAuth.js), <code>npm install betterauth<\/code> veya <code>npm install next-auth<\/code> komutuyla projenize ekleyin.<\/li>\n<li><strong>API Rotalar\u0131 Olu\u015fturma:<\/strong> Next.js'in API rotalar\u0131n\u0131 kullanarak kimlik do\u011frulama endpoint'lerini (giri\u015f, kay\u0131t, \u00e7\u0131k\u0131\u015f, \u015fifre s\u0131f\u0131rlama) olu\u015fturun. BetterAuth genellikle bu rotalar\u0131 otomatik olarak y\u00f6netmenizi sa\u011flayan bir yap\u0131 sunar.<\/li>\n<li><strong>Sa\u011flay\u0131c\u0131lar\u0131 Yap\u0131land\u0131rma:<\/strong> Veritaban\u0131 adapt\u00f6r\u00fcn\u00fc (Prisma ile \u00e7al\u0131\u015facak \u015fekilde) ve kullanmak istedi\u011finiz kimlik do\u011frulama sa\u011flay\u0131c\u0131lar\u0131n\u0131 (e-posta\/\u015fifre, Google, GitHub vb.) yap\u0131land\u0131r\u0131n.<\/li>\n<li><strong>Oturum Y\u00f6netimi:<\/strong> Kullan\u0131c\u0131n\u0131n oturum bilgilerini (JWT veya oturum \u00e7erezleri) y\u00f6netmek i\u00e7in client-side'da Context API veya SWR gibi k\u00fct\u00fcphaneleri kullanarak k\u00fcresel bir oturum durumu sa\u011flay\u0131n.<\/li>\n<li><strong>Korunan Rotalar:<\/strong> API rotalar\u0131nda veya sayfalarda, kullan\u0131c\u0131n\u0131n oturum a\u00e7m\u0131\u015f olup olmad\u0131\u011f\u0131n\u0131 kontrol eden bir ara yaz\u0131l\u0131m (middleware) veya yard\u0131mc\u0131 fonksiyonlar kullanarak yetkilendirme uygulay\u0131n.<\/li>\n<\/ol>\n<p>BetterAuth ile ilgili detayl\u0131 dok\u00fcmantasyona bakarak spesifik entegrasyon ad\u0131mlar\u0131n\u0131 takip etmek en do\u011frusu olacakt\u0131r. Ancak temel mant\u0131k, sunucu taraf\u0131nda g\u00fcvenli kimlik do\u011frulama ak\u0131\u015flar\u0131n\u0131 y\u00f6netmek ve istemci taraf\u0131nda kullan\u0131c\u0131 oturum durumunu takip etmektir.<\/p>\n<h3>ShadCN\/UI Kurulumu ve \u0130lk Bile\u015fenlerin Eklenmesi<\/h3>\n<p>ShadCN\/UI, \u00f6nceden derlenmi\u015f bir k\u00fct\u00fcphane olmad\u0131\u011f\u0131 i\u00e7in, bile\u015fenlerini projemize \u00f6zel bir komutla ekleriz. Projenizde Tailwind CSS zaten y\u00fckl\u00fc oldu\u011fu i\u00e7in bu s\u00fcre\u00e7 daha da kolayd\u0131r:<\/p>\n<pre><code>\nnpx shadcn-ui@latest init\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komut, <code>components.json<\/code> dosyas\u0131n\u0131 olu\u015fturacak ve Tailwind CSS yap\u0131land\u0131rman\u0131zda baz\u0131 de\u011fi\u015fiklikler yapman\u0131z\u0131 isteyecektir. Ayarlar\u0131 varsay\u0131lan olarak kabul edebilirsiniz. Ard\u0131ndan, ilk bile\u015fenlerimizi ekleyebiliriz. \u00d6rne\u011fin, bir <code>Button<\/code> ve <code>Input<\/code> bile\u015fenini ekleyelim:<\/p>\n<pre><code>\nnpx shadcn-ui@latest add button\nnpx shadcn-ui@latest add input\n<\/pre>\n<p><\/code><\/p>\n<p>Bu komutlar, <code>components\/ui<\/code> klas\u00f6r\u00fcn\u00fcn alt\u0131na <code>button.tsx<\/code> ve <code>input.tsx<\/code> dosyalar\u0131n\u0131 olu\u015fturacakt\u0131r. Art\u0131k bunlar\u0131 herhangi bir React bile\u015feninizde kullanabilirsiniz:<\/p>\n<pre><code>\n\/\/ app\/page.tsx (\u00d6rnek)\nimport { Button } from \"@\/components\/ui\/button\";\nimport { Input } from \"@\/components\/ui\/input\";\n\nexport default function Home() {\n  return (\n    <div className=\"flex flex-col items-center justify-center min-h-screen p-4\">\n      <h1 className=\"text-4xl font-bold mb-8\">Emlak Uygulamas\u0131na Ho\u015f Geldiniz<\/h1>\n      <div className=\"flex space-x-4 mb-4\">\n        <Input placeholder=\"E-posta adresiniz\" className=\"w-80\" \/>\n        <Button>Giri\u015f Yap<\/Button>\n      <\/div>\n      <Button variant=\"outline\">\u0130lanlar\u0131 G\u00f6r\u00fcnt\u00fcle<\/Button>\n    <\/div>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu kurulum ad\u0131mlar\u0131, Next.js, Prisma, BetterAuth ve ShadCN\/UI ile g\u00fc\u00e7l\u00fc ve modern bir emlak uygulamas\u0131 geli\u015ftirmek i\u00e7in sa\u011flam bir ba\u015flang\u0131\u00e7 noktas\u0131 sunar. Her bir bile\u015fenin do\u011fru \u015fekilde yap\u0131land\u0131r\u0131lmas\u0131, uygulaman\u0131z\u0131n performans\u0131n\u0131, g\u00fcvenli\u011fini ve geli\u015ftirme verimlili\u011fini do\u011frudan etkileyecektir.<\/p>\n<h2>Emlak \u0130lanlar\u0131 Nas\u0131l Y\u00f6netilir: Next.js ve Prisma ile CRUD Operasyonlar\u0131<\/h2>\n<p>Emlak uygulamas\u0131n\u0131n kalbi, ilanlar\u0131n olu\u015fturulmas\u0131, g\u00f6r\u00fcnt\u00fclenmesi, g\u00fcncellenmesi ve silinmesi gibi temel CRUD (Create, Read, Update, Delete) operasyonlar\u0131d\u0131r. Bu b\u00f6l\u00fcmde, Next.js'in API rotalar\u0131n\u0131 ve Prisma'y\u0131 kullanarak bu i\u015flemleri nas\u0131l ger\u00e7ekle\u015ftirece\u011fimizi ad\u0131m ad\u0131m inceleyece\u011fiz. Bu, uygulaman\u0131n dinamik veri y\u00f6netimi yetene\u011fini kazanmas\u0131n\u0131 sa\u011flayacakt\u0131r.<\/p>\n<h3>\u0130lan Olu\u015fturma (Create): Formlar ve API Rotas\u0131<\/h3>\n<p>Yeni bir emlak ilan\u0131 olu\u015fturmak i\u00e7in, kullan\u0131c\u0131lardan ba\u015fl\u0131k, a\u00e7\u0131klama, fiyat, adres, g\u00f6rseller gibi bilgileri toplayan bir form aray\u00fcz\u00fcne ihtiyac\u0131m\u0131z var. Bu formu ShadCN\/UI bile\u015fenleriyle olu\u015fturabiliriz. Formun g\u00f6nderilmesiyle birlikte, veriler Next.js API rotas\u0131na g\u00f6nderilecek ve Prisma arac\u0131l\u0131\u011f\u0131yla veritaban\u0131na kaydedilecektir.<\/p>\n<p>\u0130lk olarak, ilan olu\u015fturma formunuzun bulundu\u011fu bir sayfa olu\u015ftural\u0131m (\u00f6rne\u011fin, <code>\/app\/ilan-olustur\/page.tsx<\/code>). Bu sayfa, <code>Input<\/code>, <code>Textarea<\/code>, <code>Button<\/code> gibi ShadCN\/UI bile\u015fenlerini kullanabilir. Formun g\u00f6nderilmesiyle bir <code>POST<\/code> iste\u011fi at\u0131lacak ve bu iste\u011fi kar\u015f\u0131layacak bir API rotas\u0131 (<code>\/app\/api\/listings\/route.ts<\/code>) olu\u015fturmam\u0131z gerekecek.<\/p>\n<pre><code>\n\/\/ app\/api\/listings\/route.ts\nimport { NextResponse } from 'next\/server';\nimport { prisma } from '@\/lib\/prisma'; \/\/ Prisma client'\u0131 do\u011fru yoldan import etti\u011finizden emin olun\n\nexport async function POST(req: Request) {\n  try {\n    const body = await req.json();\n    const { title, description, price, address, city, country, bedrooms, bathrooms, area, imageUrl, authorId } = body;\n\n    if (!title || !description || !price || !address || !city || !country || !authorId) {\n      return NextResponse.json({ message: 'Eksik bilgiler var' }, { status: 400 });\n    }\n\n    \/\/ Ger\u00e7ek bir uygulamada, burada BetterAuth ile kullan\u0131c\u0131n\u0131n yetkilendirmesi kontrol edilmelidir.\n    \/\/ \u00d6rne\u011fin, 'authorId' ger\u00e7ekten oturum a\u00e7m\u0131\u015f kullan\u0131c\u0131n\u0131n ID'si mi?\n\n    const newListing = await prisma.listing.create({\n      data: {\n        title,\n        description,\n        price: parseFloat(price),\n        address,\n        city,\n        country,\n        bedrooms: parseInt(bedrooms),\n        bathrooms: parseInt(bathrooms),\n        area: parseFloat(area),\n        imageUrl: imageUrl || [], \/\/ Resim URL'leri bir dizi olarak\n        authorId, \/\/ \u0130lan\u0131 olu\u015fturan kullan\u0131c\u0131n\u0131n ID'si\n        isPublished: true, \/\/ Varsay\u0131lan olarak yay\u0131nland\u0131\n      },\n    });\n\n    return NextResponse.json(newListing, { status: 201 });\n  } catch (error) {\n    console.error('\u0130lan olu\u015fturma hatas\u0131:', error);\n    return NextResponse.json({ message: '\u0130lan olu\u015fturulurken bir hata olu\u015ftu.' }, { status: 500 });\n  }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu API rotas\u0131, gelen iste\u011fin g\u00f6vdesinden ilan bilgilerini al\u0131r, temel do\u011frulama yapar ve ard\u0131ndan Prisma'n\u0131n <code>create<\/code> metodu arac\u0131l\u0131\u011f\u0131yla veritaban\u0131na yeni bir ilan kayd\u0131 ekler. <code>authorId<\/code> alan\u0131n\u0131n BetterAuth ile g\u00fcvenli bir \u015fekilde do\u011frulanmas\u0131 gerekti\u011fi unutulmamal\u0131d\u0131r.<\/p>\n<h3>\u0130lanlar\u0131 Listeleme (Read): Sunucu Taraf\u0131 Render (SSR) veya Statik Olu\u015fturma (SSG)<\/h3>\n<p>Emlak ilanlar\u0131n\u0131 listelemek i\u00e7in Next.js'in veri getirme stratejilerinden yararlanabiliriz. E\u011fer ilanlar \u00e7ok s\u0131k g\u00fcncellenmiyorsa ve SEO kritikse, statik olu\u015fturma (SSG) harika bir se\u00e7enektir. Ancak ilanlar\u0131n s\u0131k\u00e7a g\u00fcncellendi\u011fi ve her istekte en g\u00fcncel veriyi g\u00f6stermek istedi\u011fimiz senaryolarda sunucu taraf\u0131 render (SSR) daha uygun olabilir.<\/p>\n<p>\u00d6rnek olarak, t\u00fcm ilanlar\u0131 listeleyecek bir ana sayfa (<code>\/app\/page.tsx<\/code>) d\u00fc\u015f\u00fcnelim. Bu sayfada, do\u011frudan sunucu taraf\u0131nda Prisma'y\u0131 kullanarak ilanlar\u0131 \u00e7ekebiliriz (Next.js 13+ ile server components):<\/p>\n<pre><code>\n\/\/ app\/page.tsx\nimport { prisma } from '@\/lib\/prisma';\nimport { ListingCard } from '@\/components\/listing-card'; \/\/ Kendi ListingCard bile\u015feninizi olu\u015fturmal\u0131s\u0131n\u0131z\n\nexport default async function HomePage() {\n  const listings = await prisma.listing.findMany({\n    where: {\n      isPublished: true,\n    },\n    include: {\n      author: {\n        select: {\n          name: true,\n          email: true,\n        },\n      },\n    },\n    orderBy: {\n      createdAt: 'desc',\n    },\n  });\n\n  return (\n    <div className=\"container mx-auto p-4\">\n      <h2 className=\"text-3xl font-bold mb-6 text-center\">G\u00fcncel Emlak \u0130lanlar\u0131<\/h2>\n      <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6\">\n        {listings.map((listing) => (\n          <ListingCard key={listing.id} listing={listing} \/>\n        ))}\n        {listings.length === 0 && (\n          <p className=\"col-span-full text-center text-gray-600\">Hen\u00fcz hi\u00e7 ilan bulunmuyor.<\/p>\n        )}\n      <\/div>\n    <\/div>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Burada <code>prisma.listing.findMany<\/code> ile t\u00fcm yay\u0131nlanm\u0131\u015f ilanlar\u0131 \u00e7ekiyoruz ve her ilan i\u00e7in bir <code>ListingCard<\/code> bile\u015feni render ediyoruz. <code>include<\/code> \u00f6zelli\u011fi sayesinde, ilan\u0131n yazar bilgilerini de tek bir sorguda alabiliriz, bu da sorgu say\u0131s\u0131n\u0131 azaltarak performans\u0131 art\u0131r\u0131r.<\/p>\n<h3>\u0130lan Detaylar\u0131 (Read): Dinamik Rotalar<\/h3>\n<p>Her bir ilan\u0131n kendi detay sayfas\u0131na sahip olmas\u0131 gerekir (\u00f6rne\u011fin, <code>\/app\/listings\/[id]\/page.tsx<\/code>). Next.js'in dinamik rotalar\u0131 bu senaryo i\u00e7in m\u00fckemmeldir. <code>[id]<\/code> \u015feklinde tan\u0131mlad\u0131\u011f\u0131n\u0131z bir klas\u00f6r, URL'deki dinamik parametreyi yakalar.<\/p>\n<pre><code>\n\/\/ app\/listings\/[id]\/page.tsx\nimport { prisma } from '@\/lib\/prisma';\nimport { notFound } from 'next\/navigation';\nimport { Card, CardContent, CardHeader, CardTitle } from '@\/components\/ui\/card';\nimport { Badge } from '@\/components\/ui\/badge';\nimport Image from 'next\/image';\n\ninterface ListingDetailPageProps {\n  params: {\n    id: string;\n  };\n}\n\nexport default async function ListingDetailPage({ params }: ListingDetailPageProps) {\n  const listing = await prisma.listing.findUnique({\n    where: {\n      id: params.id,\n      isPublished: true,\n    },\n    include: {\n      author: {\n        select: {\n          name: true,\n          email: true,\n        },\n      },\n    },\n  });\n\n  if (!listing) {\n    notFound(); \/\/ \u0130lan bulunamazsa 404 sayfas\u0131 g\u00f6ster\n  }\n\n  return (\n    <div className=\"container mx-auto p-6\">\n      <Card className=\"max-w-4xl mx-auto\">\n        <CardHeader>\n          <CardTitle className=\"text-4xl font-extrabold mb-2\">{listing.title}<\/CardTitle>\n          <p className=\"text-lg text-gray-600\">{listing.address}, {listing.city}, {listing.country}<\/p>\n          <div className=\"flex gap-2 mt-2\">\n            <Badge variant=\"secondary\">{listing.bedrooms} Yatak Odas\u0131<\/Badge>\n            <Badge variant=\"secondary\">{listing.bathrooms} Banyo<\/Badge>\n            <Badge variant=\"secondary\">{listing.area} m\u00b2<\/Badge>\n          <\/div>\n        <\/CardHeader>\n        <CardContent>\n          {listing.imageUrl.length > 0 && (\n            <div className=\"relative w-full h-96 mb-6\">\n              <Image\n                src={listing.imageUrl[0]}\n                alt={listing.title}\n                fill\n                style={{ objectFit: 'cover' }}\n                className=\"rounded-lg\"\n              \/>\n            <\/div>\n          )}\n          <h3 className=\"text-2xl font-semibold mb-3\">A\u00e7\u0131klama<\/h3>\n          <p className=\"text-gray-700 leading-relaxed mb-6\">{listing.description}<\/p>\n          \n          <h3 className=\"text-2xl font-semibold mb-3\">Fiyat<\/h3>\n          <p className=\"text-4xl font-bold text-green-600 mb-6\">{listing.price.toLocaleString('tr-TR', { style: 'currency', currency: 'TRY' })}<\/p>\n\n          {listing.author && (\n            <div className=\"mt-8 border-t pt-4\">\n              <h4 className=\"text-xl font-semibold mb-2\">Emlak\u00e7\u0131 Bilgileri<\/h4>\n              <p><span className=\"font-medium\">Ad\u0131:<\/span> {listing.author.name || 'Bilinmiyor'}<\/p>\n              <p><span className=\"font-medium\">E-posta:<\/span> {listing.author.email}<\/p>\n            <\/div>\n          )}\n        <\/CardContent>\n      <\/Card>\n    <\/div>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu sayfada, <code>params.id<\/code> ile gelen ilan ID'sini kullanarak <code>prisma.listing.findUnique<\/code> ile ilgili ilan\u0131 veritaban\u0131ndan \u00e7ekiyoruz. E\u011fer ilan bulunamazsa, <code>notFound()<\/code> fonksiyonu ile Next.js'in 404 sayfas\u0131n\u0131 tetikleyebiliriz. \u0130lan\u0131 bulduktan sonra, ShadCN\/UI'\u0131n <code>Card<\/code> bile\u015fenlerini ve Next.js'in <code>Image<\/code> bile\u015fenini kullanarak \u015f\u0131k bir detay sayfas\u0131 olu\u015ftururuz.<\/p>\n<h3>\u0130lan G\u00fcncelleme (Update) ve Silme (Delete): Yetkilendirme Kontrol\u00fc<\/h3>\n<p>\u0130lan g\u00fcncelleme ve silme i\u015flemleri, g\u00fcvenlik a\u00e7\u0131s\u0131ndan \u00f6zellikle \u00f6nemlidir. Sadece ilan\u0131n sahibi veya bir y\u00f6netici bu i\u015flemleri ger\u00e7ekle\u015ftirebilmelidir. Bu, BetterAuth ile entegrasyonu gerektiren bir yetkilendirme katman\u0131 eklemeyi gerektirir.<\/p>\n<p>G\u00fcncelleme i\u00e7in de bir API rotas\u0131 (<code>\/app\/api\/listings\/[id]\/route.ts<\/code>) ve bir d\u00fczenleme formu gerekir. <code>PUT<\/code> veya <code>PATCH<\/code> metodu kullan\u0131larak gelen iste\u011fi i\u015fleyebiliriz:<\/p>\n<pre><code>\n\/\/ app\/api\/listings\/[id]\/route.ts\nimport { NextResponse } from 'next\/server';\nimport { prisma } from '@\/lib\/prisma';\nimport { auth } from '@\/lib\/betterauth'; \/\/ BetterAuth entegrasyonunuzu buradan import edin\n\nexport async function PUT(req: Request, { params }: { params: { id: string } }) {\n  try {\n    const session = await auth(); \/\/ BetterAuth ile oturum kontrol\u00fc\n    if (!session || !session.user) {\n      return NextResponse.json({ message: 'Yetkisiz eri\u015fim' }, { status: 401 });\n    }\n\n    const listingId = params.id;\n    const body = await req.json();\n    const { title, description, price, address, city, country, bedrooms, bathrooms, area, imageUrl, isPublished } = body;\n\n    const existingListing = await prisma.listing.findUnique({\n      where: { id: listingId },\n    });\n\n    if (!existingListing) {\n      return NextResponse.json({ message: '\u0130lan bulunamad\u0131' }, { status: 404 });\n    }\n\n    \/\/ \u0130lan\u0131 sadece sahibi veya y\u00f6netici g\u00fcncelleyebilir\n    \/\/ Ger\u00e7ek bir uygulamada, kullan\u0131c\u0131n\u0131n rol\u00fcn\u00fc de kontrol etmelisiniz.\n    if (existingListing.authorId !== session.user.id) {\n        return NextResponse.json({ message: 'Bu ilan\u0131 g\u00fcncelleme yetkiniz yok' }, { status: 403 });\n    }\n\n    const updatedListing = await prisma.listing.update({\n      where: { id: listingId },\n      data: {\n        title: title ?? existingListing.title,\n        description: description ?? existingListing.description,\n        price: price ? parseFloat(price) : existingListing.price,\n        address: address ?? existingListing.address,\n        city: city ?? existingListing.city,\n        country: country ?? existingListing.country,\n        bedrooms: bedrooms ? parseInt(bedrooms) : existingListing.bedrooms,\n        bathrooms: bathrooms ? parseInt(bathrooms) : existingListing.bathrooms,\n        area: area ? parseFloat(area) : existingListing.area,\n        imageUrl: imageUrl ?? existingListing.imageUrl,\n        isPublished: isPublished ?? existingListing.isPublished,\n      },\n    });\n\n    return NextResponse.json(updatedListing, { status: 200 });\n  } catch (error) {\n    console.error('\u0130lan g\u00fcncelleme hatas\u0131:', error);\n    return NextResponse.json({ message: '\u0130lan g\u00fcncellenirken bir hata olu\u015ftu.' }, { status: 500 });\n  }\n}\n\nexport async function DELETE(req: Request, { params }: { params: { id: string } }) {\n  try {\n    const session = await auth();\n    if (!session || !session.user) {\n      return NextResponse.json({ message: 'Yetkisiz eri\u015fim' }, { status: 401 });\n    }\n\n    const listingId = params.id;\n\n    const existingListing = await prisma.listing.findUnique({\n        where: { id: listingId },\n    });\n\n    if (!existingListing) {\n        return NextResponse.json({ message: '\u0130lan bulunamad\u0131' }, { status: 404 });\n    }\n\n    if (existingListing.authorId !== session.user.id) {\n        return NextResponse.json({ message: 'Bu ilan\u0131 silme yetkiniz yok' }, { status: 403 });\n    }\n\n    await prisma.listing.delete({\n      where: { id: listingId },\n    });\n\n    return NextResponse.json({ message: '\u0130lan ba\u015far\u0131yla silindi' }, { status: 200 });\n  } catch (error) {\n    console.error('\u0130lan silme hatas\u0131:', error);\n    return NextResponse.json({ message: '\u0130lan silinirken bir hata olu\u015ftu.' }, { status: 500 });\n  }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu API rotalar\u0131nda <code>auth()<\/code> fonksiyonu (BetterAuth'tan geldi\u011fi varsay\u0131lan) ile kullan\u0131c\u0131n\u0131n oturum bilgilerini al\u0131yoruz. <code>session.user.id<\/code> ile mevcut ilan\u0131n <code>authorId<\/code> de\u011ferini kar\u015f\u0131la\u015ft\u0131rarak, sadece ilan\u0131 olu\u015fturan kullan\u0131c\u0131n\u0131n veya bir y\u00f6neticinin (ek rol kontrol\u00fcyle) bu i\u015flemleri yapmas\u0131na izin veriyoruz. Bu, uygulaman\u0131z\u0131n g\u00fcvenli\u011fini art\u0131r\u0131r ve veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc korur. G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere, Next.js API rotalar\u0131 ve Prisma, emlak ilanlar\u0131 gibi dinamik verileri y\u00f6netmek i\u00e7in g\u00fc\u00e7l\u00fc ve esnek bir yap\u0131 sunar.<\/p>\n<h2>Kullan\u0131c\u0131 Deneyimini Zenginle\u015ftirme: ShadCN\/UI ile Modern Bir Aray\u00fcz<\/h2>\n<p>Bir emlak web uygulamas\u0131nda, kullan\u0131c\u0131 aray\u00fcz\u00fc (UI), kullan\u0131c\u0131lar\u0131n uygulamayla etkile\u015fimini, ilanlar\u0131 ke\u015ffetme kolayl\u0131\u011f\u0131n\u0131 ve genel memnuniyeti do\u011frudan etkiler. ShadCN\/UI, bu noktada geli\u015ftiricilere hem estetik hem de i\u015flevsel a\u00e7\u0131dan zengin bir deneyim sunan modern ve \u00f6zelle\u015ftirilebilir bile\u015fenler olu\u015fturma imkan\u0131 tan\u0131r. Tailwind CSS ile entegrasyonu sayesinde, responsive tasar\u0131mlar\u0131 h\u0131zl\u0131ca uygulayabilir ve markan\u0131za \u00f6zg\u00fc bir g\u00f6r\u00fcn\u00fcm elde edebilirsiniz.<\/p>\n<h3>Emlak Uygulamas\u0131nda Form Bile\u015fenlerinin Kullan\u0131m\u0131<\/h3>\n<p>Emlak ilanlar\u0131 olu\u015fturmak, kullan\u0131c\u0131 profili g\u00fcncellemek veya ileti\u015fim formlar\u0131 doldurmak gibi bir\u00e7ok senaryoda form bile\u015fenlerine ihtiya\u00e7 duyar\u0131z. ShadCN\/UI, bu ama\u00e7la <code>Input<\/code>, <code>Textarea<\/code>, <code>Select<\/code>, <code>Checkbox<\/code> ve <code>Button<\/code> gibi temel form elemanlar\u0131n\u0131 sunar. Bu bile\u015fenler, eri\u015filebilirlik standartlar\u0131na uygun olarak tasarlanm\u0131\u015ft\u0131r ve Tailwind CSS s\u0131n\u0131flar\u0131yla kolayca stilize edilebilir.<\/p>\n<pre><code>\n\/\/ components\/ui\/listing-form.tsx (\u00d6rnek bir form bile\u015feni)\nimport { Input } from \"@\/components\/ui\/input\";\nimport { Textarea } from \"@\/components\/ui\/textarea\";\nimport { Button } from \"@\/components\/ui\/button\";\nimport { Label } from \"@\/components\/ui\/label\"; \/\/ Label bile\u015fenini de eklemelisiniz\n\nexport function ListingForm() {\n  return (\n    <form className=\"space-y-6 p-6 border rounded-lg shadow-sm bg-white\">\n      <div>\n        <Label htmlFor=\"title\">\u0130lan Ba\u015fl\u0131\u011f\u0131<\/Label>\n        <Input id=\"title\" placeholder=\"Geni\u015f ve Ferah Daire\" \/>\n      <\/div>\n      <div>\n        <Label htmlFor=\"description\">A\u00e7\u0131klama<\/Label>\n        <Textarea id=\"description\" placeholder=\"Emlak hakk\u0131nda detayl\u0131 bilgi girin...\" rows={5} \/>\n      <\/div>\n      <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n        <div>\n          <Label htmlFor=\"price\">Fiyat (TL)<\/Label>\n          <Input id=\"price\" type=\"number\" placeholder=\"\u00d6rn: 1500000\" \/>\n        <\/div>\n        <div>\n          <Label htmlFor=\"city\">\u015eehir<\/Label>\n          <Input id=\"city\" placeholder=\"\u00d6rn: \u0130stanbul\" \/>\n        <\/div>\n      <\/div>\n      <Button type=\"submit\" className=\"w-full\">\u0130lan\u0131 Olu\u015ftur<\/Button>\n    <\/form>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>Label<\/code> bile\u015feni ile <code>Input<\/code> ve <code>Textarea<\/code> bile\u015fenlerini birle\u015ftirerek anlaml\u0131 ve eri\u015filebilir form alanlar\u0131 olu\u015fturuyoruz. Tailwind CSS'in grid sistemi sayesinde, form alanlar\u0131n\u0131 farkl\u0131 ekran boyutlar\u0131na g\u00f6re otomatik olarak d\u00fczenleyebiliriz. \u00d6rne\u011fin, <code>md:grid-cols-2<\/code> ifadesi, orta boyutlu ekranlardan itibaren iki s\u00fctunlu bir d\u00fczen sa\u011flar.<\/p>\n<h3>Navigasyon ve \u0130lan G\u00f6sterimi \u0130\u00e7in Kartlar ve Modallar<\/h3>\n<p>Bir emlak uygulamas\u0131n\u0131n ana gezinme (navigation) men\u00fcs\u00fc, kullan\u0131c\u0131lar\u0131n farkl\u0131 sayfalara (Ana Sayfa, \u0130lanlar, Hesab\u0131m, \u0130lan Olu\u015ftur) h\u0131zl\u0131ca ula\u015fmas\u0131n\u0131 sa\u011flamal\u0131d\u0131r. ShadCN\/UI'\u0131n <code>Menubar<\/code>, <code>DropdownMenu<\/code> veya <code>NavigationMenu<\/code> gibi bile\u015fenleri, bu t\u00fcr men\u00fcleri \u015f\u0131k ve i\u015flevsel bir \u015fekilde olu\u015fturmak i\u00e7in kullan\u0131labilir.<\/p>\n<p>Emlak ilanlar\u0131n\u0131n ana listeleme sayfas\u0131nda, her bir ilan\u0131 g\u00f6steren kartlar hayati \u00f6neme sahiptir. Bu kartlar, ilan\u0131n temel bilgilerini (resim, ba\u015fl\u0131k, fiyat, konum) \u00f6zetlemeli ve t\u0131klanabilir olmal\u0131d\u0131r. ShadCN\/UI'\u0131n <code>Card<\/code> bile\u015feni bu ama\u00e7 i\u00e7in idealdir:<\/p>\n<pre><code>\n\/\/ components\/listing-card.tsx\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from \"@\/components\/ui\/card\";\nimport Image from \"next\/image\";\nimport Link from \"next\/link\";\nimport { Badge } from \"@\/components\/ui\/badge\";\n\ninterface ListingCardProps {\n  listing: {\n    id: string;\n    title: string;\n    description: string;\n    price: number;\n    city: string;\n    imageUrl: string[];\n    bedrooms: number;\n    bathrooms: number;\n    area: number;\n  };\n}\n\nexport function ListingCard({ listing }: ListingCardProps) {\n  return (\n    <Link href={<code>\/listings\/${listing.id}<\/code>} passHref>\n      <Card className=\"overflow-hidden hover:shadow-lg transition-shadow duration-300 ease-in-out cursor-pointer h-full flex flex-col\">\n        {listing.imageUrl.length > 0 && (\n          <div className=\"relative w-full h-48\">\n            <Image\n              src={listing.imageUrl[0]}\n              alt={listing.title}\n              fill\n              style={{ objectFit: 'cover' }}\n              className=\"object-cover\"\n            \/>\n          <\/div>\n        )}\n        <CardHeader>\n          <CardTitle className=\"text-xl line-clamp-1\">{listing.title}<\/CardTitle>\n          <CardDescription className=\"line-clamp-2\">{listing.description}<\/CardDescription>\n        <\/CardHeader>\n        <CardContent className=\"flex-grow\">\n          <div className=\"flex flex-wrap gap-2 text-sm text-gray-600 mb-2\">\n            <Badge variant=\"outline\">{listing.bedrooms} Yatak Odas\u0131<\/Badge>\n            <Badge variant=\"outline\">{listing.bathrooms} Banyo<\/Badge>\n            <Badge variant=\"outline\">{listing.area} m\u00b2<\/Badge>\n          <\/div>\n          <p className=\"text-2xl font-bold text-primary\">\n            {listing.price.toLocaleString('tr-TR', { style: 'currency', currency: 'TRY' })}\n          <\/p>\n        <\/CardContent>\n        <CardFooter>\n          <p className=\"text-sm text-gray-500\">{listing.city}<\/p>\n        <\/CardFooter>\n      <\/Card>\n    <\/Link>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu <code>ListingCard<\/code> bile\u015feni, ilan\u0131n birincil g\u00f6rselini, ba\u015fl\u0131\u011f\u0131n\u0131, k\u0131sa a\u00e7\u0131klamas\u0131n\u0131, ana \u00f6zelliklerini (<code>Badge<\/code> kullanarak) ve fiyat\u0131n\u0131 g\u00f6sterir. <code>Link<\/code> bile\u015feni ile t\u0131klanabilir hale getirilir. \u0130lan silme onay\u0131 gibi durumlarda, <code>AlertDialog<\/code> veya <code>Dialog<\/code> (modal) bile\u015fenleri kullanarak kullan\u0131c\u0131lardan onay alabiliriz. Bu, hatal\u0131 silme i\u015flemlerini \u00f6nler ve kullan\u0131c\u0131ya geri bildirim sa\u011flar.<\/p>\n<h3>Responsive Tasar\u0131m: Mobil Uyumlu Emlak Uygulamas\u0131<\/h3>\n<p>Mobil cihazlar \u00fczerinden emlak aramas\u0131 yapan kullan\u0131c\u0131 say\u0131s\u0131 giderek artt\u0131\u011f\u0131 i\u00e7in, uygulaman\u0131z\u0131n responsive (duyarl\u0131) olmas\u0131 zorunludur. ShadCN\/UI, temel ald\u0131\u011f\u0131 Tailwind CSS sayesinde bu konuda m\u00fckemmel bir destek sunar. Tailwind'in utility-first yakla\u015f\u0131m\u0131, do\u011frudan HTML i\u015faretlemesinde <code>media query<\/code> benzeri s\u0131n\u0131flar tan\u0131mlaman\u0131za olanak tan\u0131r.<\/p>\n<p class=\"expert-tip\">Uzman \u0130pucu: Tailwind CSS'in responsive s\u0131n\u0131flar\u0131n\u0131 (\u00f6rne\u011fin <code>sm:<\/code>, <code>md:<\/code>, <code>lg:<\/code>) kullanarak her bir bile\u015fenin farkl\u0131 ekran boyutlar\u0131ndaki davran\u0131\u015f\u0131n\u0131 kolayca kontrol edebilirsiniz. Bu, \u00f6zel CSS <code>media query<\/code> yazma ihtiyac\u0131n\u0131 b\u00fcy\u00fck \u00f6l\u00e7\u00fcde azalt\u0131r ve geli\u015ftirme h\u0131z\u0131n\u0131z\u0131 art\u0131r\u0131r. \u00d6rne\u011fin, bir grid d\u00fczeninde <code>grid-cols-1 sm:grid-cols-2 lg:grid-cols-3<\/code> s\u0131n\u0131flar\u0131n\u0131 kullanarak, k\u00fc\u00e7\u00fck ekranlarda tek s\u00fctun, orta ekranlarda iki s\u00fctun ve b\u00fcy\u00fck ekranlarda \u00fc\u00e7 s\u00fctunlu bir d\u00fczen elde edebilirsiniz.<\/p>\n<p>Yukar\u0131daki <code>ListingCard<\/code> \u00f6rne\u011finde, ilan kartlar\u0131n\u0131n ana listeleyici sayfas\u0131nda <code>grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6<\/code> gibi bir s\u0131n\u0131f kombinasyonu kullanarak otomatik responsive d\u00fczen elde ettik. Bu, CSS'te manuel olarak <code>@media<\/code> kurallar\u0131 yazmak yerine, do\u011frudan Tailwind s\u0131n\u0131flar\u0131yla bile\u015fenlerin nas\u0131l davranaca\u011f\u0131n\u0131 belirtmenizi sa\u011flar. B\u00f6ylece, uygulaman\u0131z masa\u00fcst\u00fc bilgisayarlardan tablet ve ak\u0131ll\u0131 telefonlara kadar t\u00fcm cihazlarda sorunsuz ve optimize edilmi\u015f bir kullan\u0131c\u0131 deneyimi sunar.<\/p>\n<p>ShadCN\/UI ile olu\u015fturulan bile\u015fenler, sadece g\u00f6rsel olarak \u00e7ekici olmakla kalmaz, ayn\u0131 zamanda eri\u015filebilirlik (WCAG standartlar\u0131) g\u00f6z \u00f6n\u00fcnde bulundurularak tasarlanm\u0131\u015ft\u0131r. Bu da, uygulaman\u0131z\u0131n daha geni\u015f bir kullan\u0131c\u0131 kitlesi taraf\u0131ndan kullan\u0131labilir olmas\u0131n\u0131 sa\u011flar. Bu sayede emlak uygulaman\u0131z, sadece modern g\u00f6r\u00fcnmekle kalmaz, ayn\u0131 zamanda her kullan\u0131c\u0131 i\u00e7in kolayca eri\u015filebilir ve anla\u015f\u0131l\u0131r olur.<\/p>\n<h2>G\u00fcvenli\u011fe Odaklanma: BetterAuth ile Kimlik Do\u011frulama ve Yetkilendirme<\/h2>\n<p>Herhangi bir web uygulamas\u0131nda, \u00f6zellikle kullan\u0131c\u0131 verileri ve hassas bilgilere eri\u015fimin oldu\u011fu bir emlak uygulamas\u0131nda g\u00fcvenlik en temel \u00f6nceliklerden biridir. BetterAuth, bu karma\u015f\u0131k alan\u0131 basitle\u015ftirerek, g\u00fc\u00e7l\u00fc kimlik do\u011frulama ve yetkilendirme mekanizmalar\u0131n\u0131 uygulaman\u0131za entegre etmenizi sa\u011flar. Bu b\u00f6l\u00fcmde, BetterAuth ile kullan\u0131c\u0131 kay\u0131t, giri\u015f, rol tabanl\u0131 eri\u015fim kontrol\u00fc ve API rotalar\u0131nda yetkilendirme s\u00fcre\u00e7lerini nas\u0131l y\u00f6netece\u011fimizi inceleyece\u011fiz.<\/p>\n<h3>Kay\u0131t Olma ve Giri\u015f Yapma Ak\u0131\u015flar\u0131<\/h3>\n<p>Kullan\u0131c\u0131lar\u0131n emlak uygulaman\u0131za g\u00fcvenli bir \u015fekilde kaydolabilmesi ve giri\u015f yapabilmesi BetterAuth'\u0131n temel i\u015flevlerinden biridir. BetterAuth, e-posta\/\u015fifre kombinasyonunun yan\u0131 s\u0131ra, Google, Facebook gibi sosyal medya hesaplar\u0131yla veya sihirli ba\u011flant\u0131lar (magic links) arac\u0131l\u0131\u011f\u0131yla giri\u015fi destekleyebilir. Bu, kullan\u0131c\u0131lara esneklik sunarken, geli\u015ftiricilere de farkl\u0131 kimlik do\u011frulama stratejilerini kolayca entegre etme imkan\u0131 tan\u0131r.<\/p>\n<p>\u00d6rne\u011fin, bir kullan\u0131c\u0131 giri\u015f sayfas\u0131nda, kullan\u0131c\u0131n\u0131n e-posta ve \u015fifresini alacak ShadCN\/UI tabanl\u0131 bir form olu\u015fturabiliriz. Bu formun g\u00f6nderilmesiyle, BetterAuth'\u0131n sa\u011flad\u0131\u011f\u0131 API endpoint'lerine bir POST iste\u011fi g\u00f6nderilir:<\/p>\n<pre><code>\n\/\/ app\/auth\/login\/page.tsx (\u00d6rnek bir giri\u015f sayfas\u0131)\n'use client';\n\nimport { useState } from 'react';\nimport { Button } from '@\/components\/ui\/button';\nimport { Input } from '@\/components\/ui\/input';\nimport { Label } from '@\/components\/ui\/label';\n\/\/ import { signIn } from '@\/lib\/betterauth-client'; \/\/ BetterAuth'un client-side signIn fonksiyonu\n\nexport default function LoginPage() {\n  const [email, setEmail] = useState('');\n  const [password, setPassword] = useState('');\n  const [error, setError] = useState<string | null>(null);\n\n  const handleSubmit = async (e: React.FormEvent) => {\n    e.preventDefault();\n    setError(null);\n    try {\n      \/\/ Bu k\u0131s\u0131m BetterAuth'un client-side SDK's\u0131na g\u00f6re de\u011fi\u015fecektir.\n      \/\/ \u00d6rnek olarak, NextAuth.js'deki signIn fonksiyonuna benzer bir \u00e7a\u011fr\u0131\n      \/\/ const result = await signIn('credentials', {\n      \/\/   redirect: false,\n      \/\/   email,\n      \/\/   password,\n      \/\/ });\n\n      \/\/ if (result?.error) {\n      \/\/   setError(result.error);\n      \/\/ } else {\n      \/\/   window.location.href = '\/dashboard'; \/\/ Ba\u015far\u0131l\u0131 giri\u015f sonras\u0131 y\u00f6nlendirme\n      \/\/ }\n      \n      \/\/ Ge\u00e7ici olarak ba\u015far\u0131l\u0131 mesaj\u0131 g\u00f6sterelim\n      console.log('Giri\u015f iste\u011fi g\u00f6nderildi:', { email, password });\n      alert('Giri\u015f denemesi ba\u015far\u0131l\u0131! (BetterAuth entegrasyonu sim\u00fcle edildi)');\n      window.location.href = '\/'; \n\n    } catch (err) {\n      setError('Bir hata olu\u015ftu. L\u00fctfen tekrar deneyin.');\n      console.error(err);\n    }\n  };\n\n  return (\n    <div className=\"flex items-center justify-center min-h-screen bg-gray-50\">\n      <div className=\"w-full max-w-md p-8 space-y-6 bg-white rounded-lg shadow-md\">\n        <h2 className=\"text-3xl font-bold text-center\">Hesab\u0131n\u0131za Giri\u015f Yap\u0131n<\/h2>\n        <form onSubmit={handleSubmit} className=\"space-y-4\">\n          <div>\n            <Label htmlFor=\"email\">E-posta<\/Label>\n            <Input\n              id=\"email\"\n              type=\"email\"\n              placeholder=\"eposta@example.com\"\n              value={email}\n              onChange={(e) => setEmail(e.target.value)}\n              required\n            \/>\n          <\/div>\n          <div>\n            <Label htmlFor=\"password\">\u015eifre<\/Label>\n            <Input\n              id=\"password\"\n              type=\"password\"\n              placeholder=\"\u015eifreniz\"\n              value={password}\n              onChange={(e) => setPassword(e.target.value)}\n              required\n            \/>\n          <\/div>\n          {error && <p className=\"text-red-500 text-sm\">{error}<\/p>}\n          <Button type=\"submit\" className=\"w-full\">Giri\u015f Yap<\/Button>\n        <\/form>\n        <p className=\"text-center text-sm text-gray-600\">\n          Hesab\u0131n\u0131z yok mu? <a href=\"\/auth\/register\" className=\"text-blue-600 hover:underline\">Kaydolun<\/a>\n        <\/p>\n      <\/div>\n    <\/div>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Benzer bir yap\u0131yla kay\u0131t olma sayfas\u0131 da olu\u015fturulabilir. BetterAuth, bu s\u00fcre\u00e7lerde \u015fifreleri g\u00fcvenli bir \u015fekilde hash'leme, oturum token'lar\u0131n\u0131 olu\u015fturma ve y\u00f6netme gibi kritik g\u00fcvenlik ad\u0131mlar\u0131n\u0131 otomatik olarak ele al\u0131r.<\/p>\n<h3>Kullan\u0131c\u0131 Rolleri ve Rol Bazl\u0131 Eri\u015fim Kontrol\u00fc (RBAC)<\/h3>\n<p>Emlak uygulamas\u0131nda farkl\u0131 t\u00fcrde kullan\u0131c\u0131lar bulunabilir: normal kullan\u0131c\u0131lar (ilanlar\u0131 arayanlar), emlak\u00e7\u0131lar (ilanlar\u0131 yay\u0131nlayanlar) ve y\u00f6neticiler (t\u00fcm uygulamay\u0131 y\u00f6netenler). Her rol\u00fcn, uygulaman\u0131n farkl\u0131 b\u00f6l\u00fcmlerine veya fonksiyonlar\u0131na eri\u015fim yetkisi farkl\u0131 olmal\u0131d\u0131r. BetterAuth, bu rol tabanl\u0131 eri\u015fim kontrol\u00fcn\u00fc (RBAC) kolayca uygulaman\u0131za olanak tan\u0131r.<\/p>\n<p>Prisma \u015femam\u0131zda <code>User<\/code> modeline bir <code>role<\/code> alan\u0131 ekleyerek ba\u015flayabiliriz:<\/p>\n<pre><code>\n\/\/ prisma\/schema.prisma\nenum Role {\n  USER\n  AGENT\n  ADMIN\n}\n\nmodel User {\n  \/\/ ... di\u011fer alanlar ...\n  role      Role     @default(USER)\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u015fema de\u011fi\u015fikli\u011fini veritaban\u0131na uygulamak i\u00e7in <code>npx prisma migrate dev<\/code> komutunu \u00e7al\u0131\u015ft\u0131rmay\u0131 unutmay\u0131n.<\/p>\n<p>BetterAuth ile oturum a\u00e7m\u0131\u015f kullan\u0131c\u0131n\u0131n rol bilgisini alabilir ve bu bilgiye g\u00f6re UI'da veya API rotalar\u0131nda yetkilendirme kontrol\u00fc yapabiliriz. \u00d6rne\u011fin, \"\u0130lan Olu\u015ftur\" butonunu sadece <code>AGENT<\/code> veya <code>ADMIN<\/code> rol\u00fcne sahip kullan\u0131c\u0131lara g\u00f6stermek isteyebiliriz:<\/p>\n<pre><code>\n\/\/ components\/main-nav.tsx (\u00d6rnek bir navigasyon bile\u015feni)\n'use client';\n\nimport Link from 'next\/link';\n\/\/ import { useSession } from '@\/lib\/betterauth-client'; \/\/ BetterAuth'un client-side session hook'u\n\nexport function MainNav() {\n  \/\/ const { data: session } = useSession(); \/\/ BetterAuth oturumunu al\n  \/\/ const userRole = session?.user?.role; \/\/ Kullan\u0131c\u0131n\u0131n rol\u00fc\n\n  \/\/ BetterAuth entegrasyonu olmad\u0131\u011f\u0131 i\u00e7in mock bir rol kullanal\u0131m\n  const userRole = 'AGENT'; \/\/ 'USER', 'AGENT', 'ADMIN'\n\n  return (\n    <nav className=\"flex items-center space-x-4 lg:space-x-6\">\n      <Link href=\"\/\" className=\"text-sm font-medium transition-colors hover:text-primary\">\n        Ana Sayfa\n      <\/Link>\n      <Link href=\"\/listings\" className=\"text-sm font-medium transition-colors hover:text-primary\">\n        \u0130lanlar\n      <\/Link>\n      {(userRole === 'AGENT' || userRole === 'ADMIN') && (\n        <Link href=\"\/ilan-olustur\" className=\"text-sm font-medium transition-colors hover:text-primary\">\n          \u0130lan Olu\u015ftur\n        <\/Link>\n      )}\n      {userRole === 'ADMIN' && (\n        <Link href=\"\/admin\" className=\"text-sm font-medium transition-colors hover:text-primary\">\n          Y\u00f6netici Paneli\n        <\/Link>\n      )}\n      <!-- ... Di\u011fer navigasyon \u00f6\u011feleri ... -->\n    <\/nav>\n  );\n}\n<\/pre>\n<p><\/code><\/p>\n<h3>API Rotalar\u0131nda Yetkilendirme Kontrol\u00fc<\/h3>\n<p>Kullan\u0131c\u0131 aray\u00fcz\u00fcnde belirli \u00f6\u011feleri gizlemek veya g\u00f6stermek yeterli de\u011fildir; as\u0131l g\u00fcvenlik, sunucu taraf\u0131nda API rotalar\u0131nda yetkilendirme kontrol\u00fc yaparak sa\u011flan\u0131r. Daha \u00f6nce ilan g\u00fcncelleme ve silme API rotalar\u0131nda g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi, BetterAuth ile kullan\u0131c\u0131n\u0131n oturum bilgilerini al\u0131p, bu bilgileri bir ilan\u0131n <code>authorId<\/code>'si ile kar\u015f\u0131la\u015ft\u0131rarak veya kullan\u0131c\u0131n\u0131n rol\u00fcn\u00fc kontrol ederek yetkilendirme yapabiliriz.<\/p>\n<pre><code>\n\/\/ app\/api\/admin\/users\/route.ts (Sadece y\u00f6neticinin eri\u015febilece\u011fi bir API rotas\u0131 \u00f6rne\u011fi)\nimport { NextResponse } from 'next\/server';\nimport { prisma } from '@\/lib\/prisma';\nimport { auth } from '@\/lib\/betterauth'; \/\/ BetterAuth entegrasyonunuzu buradan import edin\n\nexport async function GET(req: Request) {\n  try {\n    const session = await auth();\n    \/\/ Kullan\u0131c\u0131n\u0131n oturum a\u00e7m\u0131\u015f olup olmad\u0131\u011f\u0131n\u0131 kontrol et\n    if (!session || !session.user) {\n      return NextResponse.json({ message: 'Yetkisiz eri\u015fim' }, { status: 401 });\n    }\n\n    \/\/ Kullan\u0131c\u0131n\u0131n y\u00f6netici rol\u00fcne sahip olup olmad\u0131\u011f\u0131n\u0131 kontrol et\n    \/\/ session.user BetterAuth'tan gelen kullan\u0131c\u0131 bilgilerini i\u00e7erir ve rol alan\u0131 varsay\u0131lan olarak yoktur,\n    \/\/ BetterAuth'u Prisma ile entegre etti\u011finizde bu bilgiyi oturum nesnesine eklemeniz gerekir.\n    \/\/ Varsayal\u0131m ki session.user.role alan\u0131 var.\n    const user = await prisma.user.findUnique({\n      where: { id: session.user.id },\n      select: { role: true },\n    });\n\n    if (!user || user.role !== 'ADMIN') {\n      return NextResponse.json({ message: 'Bu kayna\u011fa eri\u015fim yetkiniz yok.' }, { status: 403 });\n    }\n\n    const users = await prisma.user.findMany({\n        select: {\n            id: true,\n            email: true,\n            name: true,\n            role: true,\n            createdAt: true,\n        },\n    });\n    return NextResponse.json(users, { status: 200 });\n  } catch (error) {\n    console.error('Kullan\u0131c\u0131lar\u0131 getirme hatas\u0131:', error);\n    return NextResponse.json({ message: 'Kullan\u0131c\u0131lar getirilirken bir hata olu\u015ftu.' }, { status: 500 });\n  }\n}\n<\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>\/api\/admin\/users<\/code> rotas\u0131na yap\u0131lan isteklerde, \u00f6ncelikle kullan\u0131c\u0131n\u0131n oturum a\u00e7\u0131p a\u00e7mad\u0131\u011f\u0131, ard\u0131ndan da <code>ADMIN<\/code> rol\u00fcne sahip olup olmad\u0131\u011f\u0131 kontrol ediliyor. Sadece yetkili kullan\u0131c\u0131lar\u0131n bu t\u00fcr hassas verilere eri\u015fmesine izin verilerek, uygulaman\u0131n genel g\u00fcvenli\u011fi sa\u011flan\u0131r. BetterAuth'\u0131n sa\u011flad\u0131\u011f\u0131 bu kolay entegrasyon, g\u00fcvenlik katmanlar\u0131n\u0131 do\u011fru ve tutarl\u0131 bir \u015fekilde uygulamaya dahil etmeyi m\u00fcmk\u00fcn k\u0131lar, b\u00f6ylece geli\u015ftiriciler \u00e7ekirdek i\u015f mant\u0131\u011f\u0131na daha fazla odaklanabilir.<\/p>\n<h2>\u0130leri D\u00fczey Uygulamalar ve Optimizasyon Stratejileri<\/h2>\n<p>Bir emlak uygulamas\u0131n\u0131 temel CRUD operasyonlar\u0131n\u0131n \u00f6tesine ta\u015f\u0131mak ve onu daha verimli, \u00f6l\u00e7eklenebilir ve kullan\u0131c\u0131 dostu hale getirmek i\u00e7in ileri d\u00fczey teknikler ve optimizasyon stratejileri uygulamak kritik \u00f6neme sahiptir. Bu b\u00f6l\u00fcmde, performans, veri y\u00f6netimi ve da\u011f\u0131t\u0131m konular\u0131nda uygulaman\u0131z\u0131 bir sonraki seviyeye ta\u015f\u0131yacak ipu\u00e7lar\u0131n\u0131 ve p\u00fcf noktalar\u0131n\u0131 ele alaca\u011f\u0131z.<\/p>\n<h3>Next.js'in Veri Getirme Y\u00f6ntemlerini Ak\u0131ll\u0131ca Kullanma<\/h3>\n<p>Next.js, farkl\u0131 veri getirme stratejileri sunarak her senaryoya uygun bir \u00e7\u00f6z\u00fcm sa\u011flar:<\/p>\n<ul>\n<li>\n        <strong>Statik Site Olu\u015fturma (SSG) - <code>getStaticProps<\/code> (Sayfa Y\u00f6nlendirici):<\/strong> Emlak ilanlar\u0131 gibi nispeten statik i\u00e7erikler i\u00e7in idealdir. Sayfa, derleme zaman\u0131nda olu\u015fturulur ve CDN \u00fczerinden \u00e7ok h\u0131zl\u0131 bir \u015fekilde sunulur. Bu, \u00f6zellikle arama motorlar\u0131 i\u00e7in m\u00fckemmel SEO sa\u011flar. \u0130lanlar s\u0131k g\u00fcncellenmiyorsa, ana ilan listeleme sayfalar\u0131 i\u00e7in kullan\u0131labilir.<\/p>\n<pre><code>\n        \/\/ pages\/listings\/index.tsx (Sayfa Y\u00f6nlendirici i\u00e7in \u00f6rnek)\n        import { prisma } from '@\/lib\/prisma';\n        \n        export async function getStaticProps() {\n          const listings = await prisma.listing.findMany({\n            where: { isPublished: true },\n            orderBy: { createdAt: 'desc' },\n          });\n          return {\n            props: { listings: JSON.parse(JSON.stringify(listings)) }, \/\/ Tarih objeleri i\u00e7in serialize etme\n            revalidate: 60, \/\/ Her 60 saniyede bir yeniden olu\u015ftur\n          };\n        }\n        \n        export default function ListingsPage({ listings }) {\n          \/\/ ... \u0130lanlar\u0131 render et ...\n        }\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>Sunucu Taraf\u0131 Render (SSR) - <code>getServerSideProps<\/code> (Sayfa Y\u00f6nlendirici) veya Sunucu Bile\u015fenleri (Uygulama Y\u00f6nlendirici):<\/strong> Her istekte g\u00fcncel veriyi almak gerekti\u011finde kullan\u0131l\u0131r. \u00d6rne\u011fin, kullan\u0131c\u0131n\u0131n oturum bilgisine veya konumuna g\u00f6re ki\u015fiselle\u015ftirilmi\u015f ilanlar g\u00f6stermek i\u00e7in. Uygulama Y\u00f6nlendirici'de (<code>\/app<\/code> dizini), varsay\u0131lan olarak sunucu bile\u015fenleri kullan\u0131l\u0131r ve bu, otomatik olarak sunucu taraf\u0131nda veri getirme yetene\u011fi sunar, bu da <code>getServerSideProps<\/code>'a benzer bir mant\u0131k sa\u011flar.<\/p>\n<pre><code>\n        \/\/ app\/user-dashboard\/page.tsx (Uygulama Y\u00f6nlendirici i\u00e7in sunucu bile\u015feni)\n        import { prisma } from '@\/lib\/prisma';\n        \/\/ import { auth } from '@\/lib\/betterauth'; \/\/ Auth session'\u0131n\u0131 almak i\u00e7in\n        \n        export default async function UserDashboardPage() {\n          \/\/ const session = await auth(); \/\/ Sunucu taraf\u0131nda oturum bilgisini al\n          \/\/ if (!session?.user) {\n          \/\/   \/\/ Y\u00f6nlendirme veya hata mesaj\u0131\n          \/\/ }\n          \n          \/\/ const userListings = await prisma.listing.findMany({\n          \/\/   where: { authorId: session.user.id },\n          \/\/ });\n          \n          const userListings = []; \/\/ Ge\u00e7ici bo\u015f dizi\n        \n          return (\n            <div>\n              <h1>Emlaklar\u0131m<\/h1>\n              {\/* Kulan\u0131c\u0131n\u0131n ilanlar\u0131n\u0131 listele *\/}\n            <\/div>\n          );\n        }\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>Art\u0131ml\u0131 Statik Yenileme (ISR):<\/strong> SSG ile SSR'nin birle\u015fimi gibidir. Statik olarak olu\u015fturulmu\u015f sayfalar\u0131 belirli aral\u0131klarla veya on-demand olarak yeniden olu\u015fturur. Bu, hem h\u0131z hem de g\u00fcncellik aras\u0131nda iyi bir denge sa\u011flar.\n    <\/li>\n<\/ul>\n<p class=\"expert-tip\">Uzman \u0130pucu: B\u00fcy\u00fck emlak uygulamalar\u0131nda, ilan listeleme sayfalar\u0131 i\u00e7in ISR, tekil ilan detay sayfalar\u0131 i\u00e7in ise SSG (e\u011fer ilan verisi \u00e7ok s\u0131k de\u011fi\u015fmiyorsa) veya SSR (ger\u00e7ek zamanl\u0131 fiyat\/durum g\u00fcncellemeleri varsa) kullanmak en iyi performans\u0131 sa\u011flar. Ana sayfa gibi s\u0131k eri\u015filen ve ki\u015fiselle\u015ftirme gerektirmeyen sayfalar\u0131 SSG ile olu\u015fturmak, sunucu y\u00fck\u00fcn\u00fc azalt\u0131r.<\/p>\n<h3>Prisma Performans\u0131: \u0130li\u015fkisel Veriler, \u0130ndeksler ve Sorgu Optimizasyonu<\/h3>\n<p>Prisma, kullan\u0131m\u0131 kolay olsa da, b\u00fcy\u00fck veri k\u00fcmeleriyle \u00e7al\u0131\u015f\u0131rken performans optimizasyonlar\u0131 yapmak \u00f6nemlidir:<\/p>\n<ol>\n<li>\n        <strong>\u0130li\u015fkisel Veri Y\u00fckleme (<code>include<\/code> ve <code>select<\/code>):<\/strong> Veritaban\u0131ndan sadece ihtiyac\u0131n\u0131z olan verileri \u00e7ekin. \u00d6rne\u011fin, bir ilan\u0131 \u00e7ekerken yazar bilgilerini de istiyorsan\u0131z <code>include<\/code> kullan\u0131n. Sadece belirli alanlar\u0131 istiyorsan\u0131z <code>select<\/code> kullan\u0131n.<\/p>\n<pre><code>\n        \/\/ T\u00fcm yazar bilgilerini getir\n        const listingWithAuthor = await prisma.listing.findUnique({\n          where: { id: 'listing-id' },\n          include: { author: true },\n        });\n        \n        \/\/ Yazar\u0131n sadece ad\u0131n\u0131 ve e-postas\u0131n\u0131 getir\n        const listingWithSelectedAuthor = await prisma.listing.findUnique({\n          where: { id: 'listing-id' },\n          include: {\n            author: {\n              select: { name: true, email: true },\n            },\n          },\n        });\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>\u0130ndeksler:<\/strong> S\u0131k\u00e7a sorgulad\u0131\u011f\u0131n\u0131z alanlara (\u00f6rne\u011fin <code>listing.city<\/code>, <code>listing.price<\/code>, <code>user.email<\/code>) veritaban\u0131 indeksleri ekleyerek sorgu performans\u0131n\u0131 art\u0131r\u0131n. Bu, <code>schema.prisma<\/code> dosyan\u0131zda <code>@unique<\/code> veya <code>@index<\/code> anahtar kelimeleriyle yap\u0131labilir.<\/p>\n<pre><code>\n        model Listing {\n          \/\/ ...\n          city        String\n          price       Float\n          \n          @@index([city]) \/\/ \u015eehir alan\u0131na indeks ekle\n          @@index([price]) \/\/ Fiyat alan\u0131na indeks ekle\n        }\n        <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n        <strong>Sayfalama (Pagination):<\/strong> Binlerce ilan\u0131n\u0131z oldu\u011funda, t\u00fcm\u00fcn\u00fc tek seferde \u00e7ekmek yerine sayfalama (<code>skip<\/code> ve <code>take<\/code> veya <code>cursor<\/code> tabanl\u0131 sayfalama) kullan\u0131n.<\/p>\n<pre><code>\n        const listings = await prisma.listing.findMany({\n          skip: 0,   \/\/ \u0130lk 0 kayd\u0131 atla\n          take: 10,  \/\/ Sonraki 10 kayd\u0131 al\n          orderBy: { createdAt: 'desc' },\n        });\n        <\/pre>\n<p><\/code>\n    <\/li>\n<\/ol>\n<h3>Resim Optimizasyonu ve \u00d6nbellekleme Mekanizmalar\u0131<\/h3>\n<p>Emlak uygulamalar\u0131nda g\u00f6rseller, sayfa boyutunun ve y\u00fckleme s\u00fcresinin b\u00fcy\u00fck bir k\u0131sm\u0131n\u0131 olu\u015fturur. Next.js'in <code>next\/image<\/code> bile\u015feni, bu konuda otomatik optimizasyonlar sunar. Resimleri do\u011fru boyutland\u0131rma, lazy loading (tembel y\u00fckleme) ve farkl\u0131 formatlara (WebP gibi) d\u00f6n\u00fc\u015ft\u00fcrme gibi i\u015flemlerle performans\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r.<\/p>\n<pre><code>\nimport Image from 'next\/image';\n\n<Image\n  src=\"\/images\/emlak-ornegi.jpg\"\n  alt=\"Geni\u015f Ev\"\n  width={500} \/\/ G\u00f6r\u00fcnt\u00fcn\u00fcn orijinal geni\u015fli\u011fi\n  height={300} \/\/ G\u00f6r\u00fcnt\u00fcn\u00fcn orijinal y\u00fcksekli\u011fi\n  sizes=\"(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw\" \/\/ Responsive boyutlar\n  priority \/\/ \u0130lk y\u00fcklemede y\u00fcksek \u00f6ncelik\n\/>\n<\/pre>\n<p><\/code><\/p>\n<p>\u00d6nbellekleme, sunucu y\u00fck\u00fcn\u00fc azaltmak ve yan\u0131t s\u00fcrelerini h\u0131zland\u0131rmak i\u00e7in hayati \u00f6neme sahiptir. Veritaban\u0131ndan s\u0131k\u00e7a \u00e7ekilen ancak nadiren de\u011fi\u015fen veriler i\u00e7in Redis gibi bir \u00f6nbellekleme katman\u0131 kullanabilirsiniz. Next.js'in API rotalar\u0131nda veya veri getirme fonksiyonlar\u0131nda, \u00f6nbellek kontrol ba\u015fl\u0131klar\u0131n\u0131 (<code>Cache-Control<\/code>) kullanarak HTTP \u00f6nbelleklemesini etkinle\u015ftirebilirsiniz.<\/p>\n<h3>Hata Y\u00f6netimi ve Loglama<\/h3>\n<p>\u00dcretim ortam\u0131ndaki hatalar\u0131 h\u0131zl\u0131ca tespit etmek ve d\u00fczeltmek i\u00e7in kapsaml\u0131 hata y\u00f6netimi ve loglama stratejileri uygulanmal\u0131d\u0131r. Sentry, DataDog veya kendi \u00f6zel loglama sisteminizi (\u00f6rne\u011fin, Pino ile) entegre edebilirsiniz. Next.js API rotalar\u0131nda <code>try...catch<\/code> bloklar\u0131 kullanarak hatalar\u0131 yakalay\u0131n ve loglay\u0131n. Kullan\u0131c\u0131lara da anla\u015f\u0131l\u0131r hata mesajlar\u0131 g\u00f6sterin.<\/p>\n<h3>Da\u011f\u0131t\u0131m (Deployment)<\/h3>\n<p>Uygulaman\u0131z\u0131 canl\u0131ya almak i\u00e7in Vercel, AWS Amplify veya Netlify gibi platformlar\u0131 kullanabilirsiniz. Next.js, Vercel taraf\u0131ndan geli\u015ftirildi\u011fi i\u00e7in Vercel ile en sorunsuz entegrasyonu sunar. Otomatik da\u011f\u0131t\u0131m, sunucusuz fonksiyonlar ve CDN entegrasyonu gibi avantajlardan yararlanabilirsiniz. Prisma kullan\u0131yorsan\u0131z, veritaban\u0131 ba\u011flant\u0131lar\u0131n\u0131z\u0131n ortam de\u011fi\u015fkenleri arac\u0131l\u0131\u011f\u0131yla g\u00fcvenli bir \u015fekilde yap\u0131land\u0131r\u0131ld\u0131\u011f\u0131ndan emin olun.<\/p>\n<p>Bu ileri d\u00fczey stratejiler, emlak uygulaman\u0131z\u0131n sadece \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamakla kalmaz, ayn\u0131 zamanda y\u00fcksek performansl\u0131, g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir platform olmas\u0131n\u0131 garantiler. Bu sayede hem geli\u015ftiriciler hem de son kullan\u0131c\u0131lar i\u00e7in daha iyi bir deneyim sunulmu\u015f olur.<\/p>\n<h2>Sonu\u00e7: Gelece\u011fe Y\u00f6nelik Emlak Uygulamalar\u0131<\/h2>\n<p>Bu kapsaml\u0131 makale boyunca, Next.js, Prisma, BetterAuth ve ShadCN\/UI teknolojilerini kullanarak modern bir emlak web uygulamas\u0131 geli\u015ftirmenin t\u00fcm a\u015famalar\u0131n\u0131 detayl\u0131 bir \u015fekilde inceledik. G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere, bu d\u00f6rtl\u00fc, birlikte \u00e7al\u0131\u015farak geli\u015ftiricilere h\u0131zl\u0131, g\u00fcvenli, performansl\u0131 ve kullan\u0131c\u0131 dostu uygulamalar olu\u015fturma konusunda e\u015fsiz bir g\u00fc\u00e7 ve esneklik sunuyor. Next.js'in sunucu taraf\u0131 render ve statik site olu\u015fturma yetenekleri sayesinde SEO avantaj\u0131 ve y\u0131ld\u0131r\u0131m h\u0131z\u0131nda sayfa y\u00fcklemeleri sa\u011flarken, Prisma t\u00fcr g\u00fcvenli ORM yap\u0131s\u0131yla veritaban\u0131 y\u00f6netimini basitle\u015ftiriyor ve hatalar\u0131 minimize ediyor. BetterAuth, kimlik do\u011frulama ve yetkilendirme s\u00fcre\u00e7lerini g\u00fcvenli ve zahmetsiz hale getirirken, ShadCN\/UI ise \u00f6zelle\u015ftirilebilir ve eri\u015filebilir bile\u015fenleriyle g\u00f6rsel a\u00e7\u0131dan \u00e7arp\u0131c\u0131 bir kullan\u0131c\u0131 deneyimi sunuyor.<\/p>\n<p>Emlak sekt\u00f6r\u00fc gibi dinamik ve rekabet\u00e7i bir alanda, teknolojinin sa\u011flad\u0131\u011f\u0131 bu avantajlar\u0131 kullanmak, i\u015fletmelerin dijital varl\u0131klar\u0131n\u0131 g\u00fc\u00e7lendirmesi ve m\u00fc\u015fteri memnuniyetini art\u0131rmas\u0131 i\u00e7in kritik \u00f6neme sahiptir. Bu teknoloji y\u0131\u011f\u0131n\u0131 ile olu\u015fturulan bir uygulama, sadece bug\u00fcn\u00fcn de\u011fil, gelece\u011fin de ihtiya\u00e7lar\u0131na cevap verebilecek kapasitede olacakt\u0131r. \u00d6l\u00e7eklenebilirlik, bak\u0131m kolayl\u0131\u011f\u0131 ve geli\u015ftirici verimlili\u011fi sayesinde, uygulaman\u0131z\u0131 s\u00fcrekli olarak geli\u015ftirebilir, yeni \u00f6zellikler ekleyebilir ve pazar\u0131n de\u011fi\u015fen taleplerine h\u0131zla uyum sa\u011flayabilirsiniz. Art\u0131k modern bir emlak uygulamas\u0131 geli\u015ftirmek i\u00e7in ihtiyac\u0131n\u0131z olan t\u00fcm bilgilere ve ara\u00e7lara sahipsiniz. Bu rehberi bir ba\u015flang\u0131\u00e7 noktas\u0131 olarak kullanarak kendi \u00f6zg\u00fcn ve ba\u015far\u0131l\u0131 projenizi hayata ge\u00e7irebilirsiniz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<p><strong>1. Next.js mi yoksa sadece React m\u0131 tercih edilmeli?<\/strong><\/p>\n<p>E\u011fer uygulaman\u0131z\u0131n SEO performans\u0131, ilk y\u00fckleme h\u0131z\u0131 ve genel kullan\u0131c\u0131 deneyimi kritikse, Next.js tercih edilmelidir. Sunucu taraf\u0131 render (SSR), statik site olu\u015fturma (SSG) ve API rotalar\u0131 gibi \u00f6zellikler, sadece React ile elde edilmesi zor veya ek yap\u0131land\u0131rma gerektiren \u00f6nemli avantajlar sunar. Tek sayfal\u0131k, basit bir istemci taraf\u0131 uygulama geli\u015ftiriyorsan\u0131z saf React yeterli olabilir.<\/p>\n<p><strong>2. Prisma hangi veritabanlar\u0131n\u0131 destekler?<\/strong><\/p>\n<p>Prisma, geni\u015f bir veritaban\u0131 deste\u011fi sunar. Ba\u015fl\u0131ca desteklenenler aras\u0131nda PostgreSQL, MySQL, SQLite, SQL Server ve MongoDB (deneysel) bulunmaktad\u0131r. Projenizin ihtiya\u00e7lar\u0131na ve tercihlerinize g\u00f6re bu veritabanlar\u0131ndan herhangi birini se\u00e7ebilirsiniz. \u015eema tan\u0131m\u0131 ve migrasyon ara\u00e7lar\u0131 sayesinde, veritaban\u0131 ge\u00e7i\u015fleri de nispeten kolayla\u015f\u0131r.<\/p>\n<p><strong>3. BetterAuth yerine NextAuth.js kullan\u0131labilir mi?<\/strong><\/p>\n<p>Evet, BetterAuth yerine NextAuth.js (yeni ad\u0131yla Auth.js) Next.js uygulamalar\u0131 i\u00e7in pop\u00fcler ve g\u00fc\u00e7l\u00fc bir kimlik do\u011frulama k\u00fct\u00fcphanesidir. Benzer i\u015flevsellikler sunar ve Prisma gibi ORM'lerle sorunsuz bir \u015fekilde entegre edilebilir. Hatta BetterAuth gibi isimler genellikle kendi geli\u015ftirilen veya belirli bir amaca y\u00f6nelik \u00f6zelle\u015ftirilmi\u015f Auth \u00e7\u00f6z\u00fcmlerini ifade edebilir. Genel olarak, Next.js ekosisteminde Auth.js, geni\u015f topluluk deste\u011fi ve kapsaml\u0131 dok\u00fcmantasyonu nedeniyle s\u0131k\u00e7a tercih edilir.<\/p>\n<p><strong>4. ShadCN\/UI performans\u0131 nas\u0131l etkiler?<\/strong><\/p>\n<p>ShadCN\/UI, do\u011frudan projenize kopyalanan ve bu sayede tam kontrol sa\u011flayan bile\u015fenler sundu\u011fu i\u00e7in, genellikle performansa olumsuz bir etkisi olmaz, aksine olumlu y\u00f6nde katk\u0131da bulunabilir. Bile\u015fenlerinizi sadece ihtiyac\u0131n\u0131z olan k\u0131s\u0131mlar\u0131 alarak ve gereksiz ba\u011f\u0131ml\u0131l\u0131klardan ka\u00e7\u0131narak optimize edebilirsiniz. Tailwind CSS ile entegrasyonu, gereksiz CSS y\u00fck\u00fcn\u00fc azaltarak daha k\u00fc\u00e7\u00fck dosya boyutlar\u0131 ve daha h\u0131zl\u0131 y\u00fckleme s\u00fcreleri sa\u011flar. Radix UI primitives \u00fczerine in\u015fa edilmesi ise eri\u015filebilirlik ve performans optimizasyonlar\u0131n\u0131 temelden sa\u011flar.<\/p>\n<p><strong>5. Bu uygulamay\u0131 \u00fcretim ortam\u0131na da\u011f\u0131t\u0131rken nelere dikkat etmeliyim?<\/strong><\/p>\n<p>\u00dcretim ortam\u0131nda dikkat etmeniz gerekenler \u015funlard\u0131r: ortam de\u011fi\u015fkenlerini g\u00fcvenli bir \u015fekilde y\u00f6netin (\u00f6rne\u011fin veritaban\u0131 URL'leri, API anahtarlar\u0131), g\u00fcvenlik ba\u015fl\u0131klar\u0131n\u0131 yap\u0131land\u0131r\u0131n (CSP, HSTS), HTTPS kullan\u0131n, hata izleme ve loglama ara\u00e7lar\u0131 entegre edin (Sentry, DataDog), veritaban\u0131 yedekleme stratejileri uygulay\u0131n, \u00f6nbellekleme mekanizmalar\u0131n\u0131 do\u011fru yap\u0131land\u0131r\u0131n ve Next.js uygulaman\u0131z\u0131 Vercel, AWS Amplify gibi platformlarda optimize edilmi\u015f \u015fekilde da\u011f\u0131t\u0131n. Ayr\u0131ca, performans testleri ve g\u00fcvenlik denetimleri yapmay\u0131 ihmal etmeyin.<\/p>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme G\u00fcn\u00fcm\u00fcz rekabet\u00e7i dijital d\u00fcnyas\u0131nda, emlak sekt\u00f6r\u00fcnde faaliyet g\u00f6steren i\u015fletmelerin&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-35000","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?<\/title>\n<meta name=\"description\" content=\"Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?\" \/>\n<meta property=\"og:description\" content=\"Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-24T14:31:55+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"41 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?\",\"datePublished\":\"2025-11-24T14:31:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/\"},\"wordCount\":6338,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/\",\"name\":\"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-24T14:31:55+00:00\",\"description\":\"Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?","description":"Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/","og_locale":"tr_TR","og_type":"article","og_title":"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?","og_description":"Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme","og_url":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-24T14:31:55+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"41 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?","datePublished":"2025-11-24T14:31:55+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/"},"wordCount":6338,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/","url":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/","name":"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-24T14:31:55+00:00","description":"Next.js, Prisma, BetterAuth ve ShadCN\/UI ile Emlak Uygulamas\u0131 Geli\u015ftirme","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/modern-emlak-uygulamalari-neden-bu-kadar-onemli-ve-neden-bu-teknolojilerle-gelistirilmeli\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Modern Emlak Uygulamalar\u0131 Neden Bu Kadar \u00d6nemli ve Neden Bu Teknolojilerle Geli\u015ftirilmeli?"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35000","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=35000"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35000\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=35000"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=35000"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=35000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}