Skip to content

Commit

Permalink
Merge pull request #1 from iqbalpa/feat/detail
Browse files Browse the repository at this point in the history
Feat/detail
  • Loading branch information
iqbalpa authored Jul 20, 2024
2 parents b6d9017 + c3615ba commit 0b2b165
Show file tree
Hide file tree
Showing 13 changed files with 442 additions and 35 deletions.
17 changes: 17 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "gray",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@
"format:fix": "prettier --write --list-different ."
},
"dependencies": {
"@radix-ui/react-scroll-area": "^1.1.0",
"axios": "^1.7.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"daisyui": "^4.12.10",
"lint-staged": "^15.2.7",
"lucide-react": "^0.411.0",
"next": "14.2.2",
"react": "^18",
"react-dom": "^18"
"react-dom": "^18",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
13 changes: 13 additions & 0 deletions src/app/[id]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ScrollArea } from '@/components/ui/scroll-area';

export default function DetailLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<div className="flex h-screen flex-1 overflow-hidden overflow-y-auto">
{children}
</div>
);
}
66 changes: 66 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,69 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 224 71.4% 4.1%;
--card: 0 0% 100%;
--card-foreground: 224 71.4% 4.1%;
--popover: 0 0% 100%;
--popover-foreground: 224 71.4% 4.1%;
--primary: 220.9 39.3% 11%;
--primary-foreground: 210 20% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
--muted: 220 14.3% 95.9%;
--muted-foreground: 220 8.9% 46.1%;
--accent: 220 14.3% 95.9%;
--accent-foreground: 220.9 39.3% 11%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 20% 98%;
--border: 220 13% 91%;
--input: 220 13% 91%;
--ring: 224 71.4% 4.1%;
--radius: 0.5rem;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
}

.dark {
--background: 224 71.4% 4.1%;
--foreground: 210 20% 98%;
--card: 224 71.4% 4.1%;
--card-foreground: 210 20% 98%;
--popover: 224 71.4% 4.1%;
--popover-foreground: 210 20% 98%;
--primary: 210 20% 98%;
--primary-foreground: 220.9 39.3% 11%;
--secondary: 215 27.9% 16.9%;
--secondary-foreground: 210 20% 98%;
--muted: 215 27.9% 16.9%;
--muted-foreground: 217.9 10.6% 64.9%;
--accent: 215 27.9% 16.9%;
--accent-foreground: 210 20% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 20% 98%;
--border: 215 27.9% 16.9%;
--input: 215 27.9% 16.9%;
--ring: 216 12.2% 83.9%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
13 changes: 10 additions & 3 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import './globals.css';
import Header from '@/components/header/header';
import GoTopButton from '@/components/goTopButton/goTopButton';
import BackButton from '@/components/backButton/backButton';
import { ScrollArea } from '@/components/ui/scroll-area';
import Sidebar from '@/components/sidebar/sidebar';

const inter = Inter({ subsets: ['latin'] });

Expand All @@ -20,12 +22,17 @@ export default function RootLayout({
return (
<html lang="en">
<body
className={`${inter.className} relative bg-gray-800 text-slate-200`}
className={`${inter.className} flex h-screen flex-col bg-gray-800 text-slate-200`}
>
<Header />
<BackButton />
{children}
<div className="flex flex-1 flex-row">
<main className="flex-1 overflow-y-hidden">{children}</main>
<div className="flex max-h-screen flex-shrink-0 overflow-hidden overflow-y-auto bg-slate-900 pb-4 pt-16">
<Sidebar />
</div>
</div>
<GoTopButton />
<BackButton />
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';

const Header: React.FC = () => {
return (
<div className="flex flex-row items-center justify-between bg-gray-900 p-5">
<div className="fixed inset-x-0 z-10 flex flex-row items-center justify-between bg-gray-900 p-5">
<Link href="/" className="text-xl font-bold">
Al - Quran
</Link>
Expand Down
89 changes: 89 additions & 0 deletions src/components/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use client';

import { getAllSurah } from '@/api/api';
import { ISurah } from '@/constant/surah.constant';
import Link from 'next/link';
import React, { useEffect, useState } from 'react';
import { usePathname } from 'next/navigation';
import { ScrollArea } from '../ui/scroll-area';

const Sidebar: React.FC = () => {
const [surahs, setSurahs] = useState<ISurah[]>([]);
const pathname = usePathname();

useEffect(() => {
const fetchData = async () => {
try {
const res = await getAllSurah();
console.log(res);
setSurahs(res);
} catch (e) {
console.log('failed to fetch the surah');
}
};
fetchData();
}, []);

if (pathname === '/') {
return null;
}

return (
<ScrollArea>
<div className="hidden flex-col gap-2 p-4 md:flex">
{surahs.map((surah) => {
const isActive = pathname === `/${surah.nomor}`;

return (
<Link
href={`/${surah.nomor}`}
key={surah.nomor}
className={`group flex w-[250px] flex-row justify-between rounded-md border-[1px] border-slate-400 bg-slate-700 p-4 duration-200 hover:cursor-pointer ${
isActive ? 'border-teal-300' : 'hover:border-teal-300'
}`}
>
<div className="flex flex-row items-center gap-3">
<div
className={`flex h-10 w-10 items-center justify-center rounded-full bg-slate-900 ${
isActive ? 'bg-teal-300' : 'group-hover:bg-teal-300'
}`}
>
<p
className={`font-bold ${
isActive ? 'text-slate-900' : 'group-hover:text-slate-900'
}`}
>
{surah.nomor}
</p>
</div>

<div>
<p className="font-semibold">{surah.namaLatin}</p>
<p
className={`text-sm text-slate-400 ${
isActive ? 'text-teal-300' : 'group-hover:text-teal-300'
}`}
>
{surah.arti}
</p>
</div>
</div>
<div className="text-right">
<p>{surah.nama}</p>
<p
className={`text-sm text-slate-400 ${
isActive ? 'text-teal-300' : 'group-hover:text-teal-300'
}`}
>
{surah.jumlahAyat} ayat
</p>
</div>
</Link>
);
})}
</div>
</ScrollArea>
);
};

export default Sidebar;
48 changes: 48 additions & 0 deletions src/components/ui/scroll-area.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use client';

import * as React from 'react';
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';

import { cn } from '@/lib/utils';

const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
>(({ className, children, ...props }, ref) => (
<ScrollAreaPrimitive.Root
ref={ref}
className={cn('relative overflow-hidden', className)}
{...props}
>
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
));
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;

const ScrollBar = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
>(({ className, orientation = 'vertical', ...props }, ref) => (
<ScrollAreaPrimitive.ScrollAreaScrollbar
ref={ref}
orientation={orientation}
className={cn(
'flex touch-none select-none transition-colors',
orientation === 'vertical' &&
'h-full w-2.5 border-l border-l-transparent p-[1px]',
orientation === 'horizontal' &&
'h-2.5 flex-col border-t border-t-transparent p-[1px]',
className,
)}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
</ScrollAreaPrimitive.ScrollAreaScrollbar>
));
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;

export { ScrollArea, ScrollBar };
6 changes: 6 additions & 0 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
30 changes: 15 additions & 15 deletions src/modules/detailSurah/detailSurah.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { getSurahByNomor } from '@/api/api';
import { ScrollArea } from '@/components/ui/scroll-area';
import { DetailSurah } from '@/constant/surah.constant';
import { Play } from 'lucide-react';
import { usePathname } from 'next/navigation';
Expand All @@ -25,24 +26,23 @@ const DetailSurahPage: React.FC = () => {
}, [pathname]);

if (!surah) {
return;
return null;
}

return (
<div className="mt-20 flex flex-col items-center pb-20 md:mt-10">
<h1 className="text-xl font-bold">
{surah.namaLatin} - {surah.nama}
</h1>
<p>
{surah.jumlahAyat} ayat - {surah.arti} - {surah.tempatTurun}
</p>
<div className="max-w-screen mt-5 flex flex-col items-center gap-3 px-4 md:px-10 lg:px-14 xl:px-20">
<div className="flex h-full max-h-screen flex-col overflow-y-auto pb-4 pt-16">
<div className="flex flex-col items-center pt-20 md:pt-10">
<h1 className="text-xl font-bold">
{surah.namaLatin} - {surah.nama}
</h1>
<p>
{surah.jumlahAyat} ayat - {surah.arti} - {surah.tempatTurun}
</p>
</div>
<ScrollArea className="mt-5 flex flex-col items-center gap-3 overflow-y-auto px-4 pb-5 md:px-10 lg:px-14 xl:px-20">
{surah.ayat.map((ayat, _index) => (
<div className="flex w-full flex-col">
<div
key={ayat.nomorAyat}
className="flex w-full flex-row justify-between gap-3 text-sm md:text-base"
>
<div key={ayat.nomorAyat} className="flex w-full flex-col">
<div className="flex w-full flex-row justify-between gap-3 text-sm md:text-base">
<div className="flex flex-col items-center justify-between gap-2">
<p className="text-xs md:text-sm">
{surah.nomor}:{ayat.nomorAyat}
Expand All @@ -69,7 +69,7 @@ const DetailSurahPage: React.FC = () => {
<hr className="my-3 w-full border-t border-gray-600" />
</div>
))}
</div>
</ScrollArea>
</div>
);
};
Expand Down
3 changes: 2 additions & 1 deletion src/modules/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { useEffect, useState } from 'react';
import { getAllSurah } from '@/api/api';
import { ISurah } from '@/constant/surah.constant';
import Link from 'next/link';
import { ScrollArea } from '@/components/ui/scroll-area';

const HomeModule: React.FC = () => {
const [surahs, setSurahs] = useState<ISurah[]>([]);
Expand All @@ -22,7 +23,7 @@ const HomeModule: React.FC = () => {
}, []);

return (
<div className="mt-20 md:mt-10 max-w-screen m-10 flex min-h-screen flex-col items-center">
<div className="max-w-screen mt-36 flex min-h-screen flex-col items-center md:mt-28">
<h1 className="text-2xl font-bold">Baca Al-Quran Online</h1>
<div className="mt-5 grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
{surahs.map((surah, _index) => (
Expand Down
Loading

0 comments on commit 0b2b165

Please sign in to comment.