first commit
This commit is contained in:
264
app/apps/page.tsx
Normal file
264
app/apps/page.tsx
Normal file
@@ -0,0 +1,264 @@
|
||||
import { getApps, createApp, deleteApp } from "./actions";
|
||||
import {
|
||||
Smartphone,
|
||||
Plus,
|
||||
ArrowLeft,
|
||||
Globe,
|
||||
Apple,
|
||||
Play,
|
||||
Settings,
|
||||
ShoppingBag,
|
||||
SlidersHorizontal,
|
||||
ExternalLink,
|
||||
PackageSearch,
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import DeleteButton from "./DeleteButton";
|
||||
|
||||
export default async function AppsPage() {
|
||||
const allApps = await getApps();
|
||||
|
||||
async function handleDelete(formData: FormData) {
|
||||
"use server";
|
||||
const id = Number(formData.get("id"));
|
||||
await deleteApp(id);
|
||||
revalidatePath("/apps");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex h-screen bg-zinc-50 dark:bg-black font-sans text-zinc-900 dark:text-zinc-100">
|
||||
{/* Sidebar */}
|
||||
<aside className="w-64 bg-white dark:bg-zinc-900 border-r border-zinc-200 dark:border-zinc-800 flex flex-col">
|
||||
<div className="p-6 border-b border-zinc-200 dark:border-zinc-800 flex items-center gap-3">
|
||||
<Link
|
||||
href="/"
|
||||
className="w-8 h-8 bg-black dark:bg-white rounded-lg flex items-center justify-center"
|
||||
>
|
||||
<span className="text-white dark:text-black font-bold text-lg">A</span>
|
||||
</Link>
|
||||
<span className="font-bold text-lg tracking-tight">AppAdmin</span>
|
||||
</div>
|
||||
<nav className="flex-1 p-4 space-y-1">
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center gap-3 px-3 py-2 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg text-sm font-medium transition-colors"
|
||||
>
|
||||
<Globe size={18} /> Dashboard
|
||||
</Link>
|
||||
<Link
|
||||
href="/apps"
|
||||
className="flex items-center gap-3 px-3 py-2 bg-zinc-100 dark:bg-zinc-800 rounded-lg text-sm font-medium"
|
||||
>
|
||||
<Smartphone size={18} /> Uygulamalar
|
||||
</Link>
|
||||
<div className="px-3 py-2 text-zinc-400 text-[10px] uppercase font-bold tracking-wider mt-4">
|
||||
Sistem
|
||||
</div>
|
||||
<Link
|
||||
href="/config"
|
||||
className="flex items-center gap-3 px-3 py-2 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg text-sm font-medium transition-colors"
|
||||
>
|
||||
<SlidersHorizontal size={18} /> Remote Config
|
||||
</Link>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<main className="flex-1 overflow-y-auto p-8">
|
||||
<div className="max-w-5xl mx-auto space-y-8">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold">Uygulama Yönetimi</h1>
|
||||
<p className="text-zinc-500 mt-1">
|
||||
Sisteme kayıtlı tüm mobil uygulamalarınızı buradan yönetin.
|
||||
</p>
|
||||
</div>
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center gap-2 text-sm text-zinc-500 hover:text-black dark:hover:text-white transition-colors"
|
||||
>
|
||||
<ArrowLeft size={16} /> Geri Dön
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Yeni Uygulama Formu */}
|
||||
<div className="lg:col-span-1">
|
||||
<div className="bg-white dark:bg-zinc-900 p-6 rounded-2xl border border-zinc-200 dark:border-zinc-800 shadow-sm sticky top-8">
|
||||
<h2 className="text-lg font-bold mb-4 flex items-center gap-2">
|
||||
<Plus size={20} className="text-blue-500" /> Yeni Uygulama Ekle
|
||||
</h2>
|
||||
<form action={createApp} className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-xs font-bold uppercase text-zinc-500 mb-1 ml-1">
|
||||
Uygulama Adı
|
||||
</label>
|
||||
<input
|
||||
name="name"
|
||||
required
|
||||
className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-black text-sm focus:ring-2 focus:ring-black dark:focus:ring-white transition-all"
|
||||
placeholder="Örn: X-Tracker Pro"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-bold uppercase text-zinc-500 mb-1 ml-1">
|
||||
Bundle ID
|
||||
</label>
|
||||
<input
|
||||
name="bundleId"
|
||||
required
|
||||
className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-black text-sm font-mono focus:ring-2 focus:ring-black dark:focus:ring-white transition-all"
|
||||
placeholder="com.company.app"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-bold uppercase text-zinc-500 mb-1 ml-1">
|
||||
Platform
|
||||
</label>
|
||||
<select
|
||||
name="platform"
|
||||
className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-black text-sm focus:ring-2 focus:ring-black dark:focus:ring-white transition-all"
|
||||
>
|
||||
<option value="ios">iOS (App Store)</option>
|
||||
<option value="android">Android (Play Store)</option>
|
||||
<option value="dual">Dual (Cross Platform)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-bold uppercase text-zinc-500 mb-1 ml-1">
|
||||
Apple App ID (Opsiyonel)
|
||||
</label>
|
||||
<input
|
||||
name="appleId"
|
||||
className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 dark:border-zinc-800 bg-zinc-50 dark:bg-black text-sm focus:ring-2 focus:ring-black dark:focus:ring-white transition-all"
|
||||
placeholder="123456789"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full py-3 bg-black dark:bg-white text-white dark:text-black rounded-xl font-bold text-sm hover:opacity-90 transition-opacity mt-2"
|
||||
>
|
||||
Uygulamayı Kaydet
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Uygulama Listesi */}
|
||||
<div className="lg:col-span-2 space-y-4">
|
||||
{allApps.length === 0 ? (
|
||||
<div className="bg-white dark:bg-zinc-900 border-2 border-dashed border-zinc-200 dark:border-zinc-800 rounded-3xl p-12 text-center">
|
||||
<div className="w-16 h-16 bg-zinc-100 dark:bg-zinc-800 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<PackageSearch className="text-zinc-400" size={32} />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold">Henüz uygulama yok</h3>
|
||||
<p className="text-zinc-500 text-sm max-w-xs mx-auto mt-2">
|
||||
Sol taraftaki formu kullanarak ilk uygulamanızı sisteme kaydedin.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{allApps.map((app) => (
|
||||
<div
|
||||
key={app.id}
|
||||
className="bg-white dark:bg-zinc-900 p-6 rounded-2xl border border-zinc-200 dark:border-zinc-800 shadow-sm hover:border-zinc-300 dark:hover:border-zinc-700 transition-all"
|
||||
>
|
||||
{/* App info row */}
|
||||
<div className="flex items-center gap-5 mb-5">
|
||||
<div
|
||||
className={`w-14 h-14 rounded-2xl flex items-center justify-center shrink-0 ${
|
||||
app.platform === "ios"
|
||||
? "bg-zinc-100 dark:bg-white/5"
|
||||
: "bg-green-50 dark:bg-green-900/10"
|
||||
}`}
|
||||
>
|
||||
{app.platform === "ios" ? (
|
||||
<Apple className="text-zinc-900 dark:text-white" size={28} />
|
||||
) : (
|
||||
<Play className="text-green-600" size={28} />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h3 className="text-lg font-bold leading-none mb-1 truncate">
|
||||
{app.name}
|
||||
</h3>
|
||||
<div className="flex items-center gap-3 flex-wrap">
|
||||
<span className="text-xs font-mono text-zinc-500 truncate">
|
||||
{app.bundleId}
|
||||
</span>
|
||||
<span className="w-1 h-1 bg-zinc-300 rounded-full shrink-0" />
|
||||
<span className="text-[10px] uppercase font-bold text-zinc-400 tracking-widest">
|
||||
{app.platform}
|
||||
</span>
|
||||
{app.appleId && (
|
||||
<>
|
||||
<span className="w-1 h-1 bg-zinc-300 rounded-full shrink-0" />
|
||||
<span className="text-[10px] font-mono text-zinc-400">
|
||||
#{app.appleId}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Action buttons row */}
|
||||
<div className="flex items-center gap-2 flex-wrap pt-4 border-t border-zinc-100 dark:border-zinc-800">
|
||||
{/* App Store */}
|
||||
<Link
|
||||
href={`/apps/${app.id}/store`}
|
||||
className="flex items-center gap-1.5 px-3 py-2 bg-violet-50 dark:bg-violet-900/20 text-violet-700 dark:text-violet-400 border border-violet-200 dark:border-violet-800 rounded-xl text-xs font-bold hover:bg-violet-100 dark:hover:bg-violet-900/40 transition-colors"
|
||||
>
|
||||
<ShoppingBag size={13} /> App Store
|
||||
</Link>
|
||||
|
||||
{/* Remote Config */}
|
||||
<Link
|
||||
href={`/apps/${app.id}/config`}
|
||||
className="flex items-center gap-1.5 px-3 py-2 bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-400 border border-blue-200 dark:border-blue-800 rounded-xl text-xs font-bold hover:bg-blue-100 dark:hover:bg-blue-900/40 transition-colors"
|
||||
>
|
||||
<SlidersHorizontal size={13} /> Remote Config
|
||||
</Link>
|
||||
|
||||
{/* Edit */}
|
||||
<Link
|
||||
href={`/apps/${app.id}/edit`}
|
||||
className="flex items-center gap-1.5 px-3 py-2 bg-zinc-50 dark:bg-zinc-800 text-zinc-700 dark:text-zinc-300 border border-zinc-200 dark:border-zinc-700 rounded-xl text-xs font-bold hover:bg-zinc-100 dark:hover:bg-zinc-700 transition-colors"
|
||||
>
|
||||
<Settings size={13} /> Düzenle
|
||||
</Link>
|
||||
|
||||
{/* Apple Store external link */}
|
||||
{app.appleId && (
|
||||
<a
|
||||
href={`https://apps.apple.com/app/id${app.appleId}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1.5 px-3 py-2 bg-zinc-50 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 border border-zinc-200 dark:border-zinc-700 rounded-xl text-xs font-bold hover:text-black dark:hover:text-white transition-colors"
|
||||
>
|
||||
<ExternalLink size={13} /> App Store'da Gör
|
||||
</a>
|
||||
)}
|
||||
|
||||
{/* Spacer */}
|
||||
<div className="flex-1" />
|
||||
|
||||
{/* Delete */}
|
||||
<DeleteButton
|
||||
appId={app.id}
|
||||
appName={app.name}
|
||||
deleteAction={handleDelete}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user