├── public ├── fav.ico ├── placeholder-logo.png ├── placeholder.jpg ├── placeholder-user.jpg ├── placeholder-logo.svg └── placeholder.svg ├── .dockerignore ├── postcss.config.mjs ├── app ├── quran │ ├── page.tsx │ ├── surahs │ │ └── page.tsx │ ├── surah │ │ └── [id] │ │ │ └── page.tsx │ └── page │ │ └── [number] │ │ └── page.tsx ├── developers │ ├── metadata.ts │ └── page.tsx ├── page.tsx ├── api │ └── quran │ │ ├── chapters │ │ └── route.ts │ │ ├── surah │ │ └── [id] │ │ │ └── route.ts │ │ └── pages │ │ └── [number] │ │ └── route.ts ├── layout.tsx └── globals.css ├── components ├── ui │ ├── aspect-ratio.tsx │ ├── loading-spinner.tsx │ ├── skeleton.tsx │ ├── collapsible.tsx │ ├── use-mobile.tsx │ ├── textarea.tsx │ ├── label.tsx │ ├── input.tsx │ ├── separator.tsx │ ├── progress.tsx │ ├── toaster.tsx │ ├── sonner.tsx │ ├── checkbox.tsx │ ├── slider.tsx │ ├── switch.tsx │ ├── badge.tsx │ ├── tooltip.tsx │ ├── hover-card.tsx │ ├── popover.tsx │ ├── avatar.tsx │ ├── radio-group.tsx │ ├── toggle.tsx │ ├── alert.tsx │ ├── scroll-area.tsx │ ├── resizable.tsx │ ├── toggle-group.tsx │ ├── tabs.tsx │ ├── button.tsx │ ├── card.tsx │ ├── accordion.tsx │ ├── input-otp.tsx │ ├── calendar.tsx │ ├── breadcrumb.tsx │ ├── pagination.tsx │ ├── table.tsx │ ├── drawer.tsx │ ├── dialog.tsx │ ├── use-toast.ts │ ├── sheet.tsx │ ├── form.tsx │ ├── alert-dialog.tsx │ ├── toast.tsx │ ├── command.tsx │ └── navigation-menu.tsx ├── theme-provider.tsx ├── query-provider.tsx ├── language-toggle.tsx ├── theme-toggle.tsx ├── developers │ ├── developer-welcome.tsx │ ├── contribute.tsx │ └── community.tsx ├── layout │ ├── mobile-navigation.tsx │ ├── header.tsx │ └── footer.tsx ├── landing │ ├── features.tsx │ └── cta.tsx └── quran │ ├── surah-reader.tsx │ └── surah-navigation.tsx ├── next.config.mjs ├── docker-compose.yml ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ ├── hata-raporu.md │ └── ozellik-istegi.md ├── components.json ├── hooks ├── use-mobile.tsx ├── use-surah-name.ts └── use-toast.ts ├── lib └── utils.ts ├── Dockerfile ├── tsconfig.json ├── types └── quran.ts ├── package.json ├── CODE_OF_CONDUCT.md ├── tailwind.config.js ├── services ├── quran-api.ts └── api-client.ts ├── stores └── quran-store.ts ├── styles └── globals.css ├── INSTALLATION.md └── CONTRIBUTING.md /public/fav.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diyanet-bid/Kuran/HEAD/public/fav.ico -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | .git 4 | .gitignore 5 | Dockerfile 6 | docker-compose.yml 7 | *.log 8 | *.md 9 | .vscode 10 | .env 11 | *.tsbuildinfo -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /app/quran/page.tsx: -------------------------------------------------------------------------------- 1 | import { redirect } from "next/navigation" 2 | 3 | export default function QuranPage() { 4 | // Redirect to first page by default 5 | redirect("/quran/page/1") 6 | } 7 | -------------------------------------------------------------------------------- /components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /components/ui/loading-spinner.tsx: -------------------------------------------------------------------------------- 1 | import { Loader2 } from "lucide-react" 2 | 3 | export function LoadingSpinner() { 4 | return ( 5 |
{t("dev.welcome.subtitle")}
15 |
21 | {t("dev.welcome.modernTechDesc")}
25 |{t("dev.welcome.purposeDrivenDesc")}
35 |{t("dev.welcome.globalImpactDesc")}
45 |{t("features.subtitle")}
57 |{t("dev.contribute.subtitle")}
17 |{t("dev.contribute.frontendDesc")}
70 |{t("dev.contribute.backendDesc")}
74 |{t("dev.contribute.translationsDesc")}
78 |{t("quran.surahNotFound")}
46 |61 | {language === "tr" 62 | ? surahData.surah.names.tr 63 | : surahData.surah.names.en} 64 |
65 |66 | {surahData.surah.verses_count} {t("quran.verses")} 67 |
68 |40 | {currentSurah} 41 | {getOrdinal(currentSurah, language)} {t("navigation.surah")} 42 |
43 |{getSurahName(prevSurah)}
67 |{getSurahName(nextSurah)}
100 |15 | {t("dev.community.subtitle")} 16 |
17 |27 | {t("dev.community.soon")} 28 |
29 | 32 |{t("dev.community.telegramDesc")}
42 | 45 |{t("dev.community.githubDesc")}
55 | 61 | {t("dev.community.viewRepository")} 62 | 63 |{t("dev.community.emailDesc")}
73 | 79 | {t("dev.community.sendEmail")} 80 | 81 |163 | {body} 164 |
165 | ) 166 | }) 167 | FormMessage.displayName = "FormMessage" 168 | 169 | export { 170 | useFormField, 171 | Form, 172 | FormItem, 173 | FormLabel, 174 | FormControl, 175 | FormDescription, 176 | FormMessage, 177 | FormField, 178 | } 179 | -------------------------------------------------------------------------------- /components/landing/cta.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { Button } from "@/components/ui/button" 4 | import { BookOpen, Download, ArrowRight, Sparkles, Shield, Zap, Globe } from "lucide-react" 5 | import Link from "next/link" 6 | import { useLanguage } from "@/components/language-provider" 7 | 8 | export function CTA() { 9 | const { t } = useLanguage() 10 | 11 | return ( 12 |34 | {t("cta.description")} 35 |
36 | 37 |82 | 83 | {t("cta.supportedBy")} 84 | {" "} 85 | {t("cta.supportedByDesc")} 86 |
87 |