panduan pengambilan foto

This commit is contained in:
kizadl 2026-05-20 11:12:33 +07:00
parent 86c4fb3189
commit 7c969b72de
4 changed files with 103 additions and 6 deletions

View File

@ -33,6 +33,7 @@
<!-- CTAs -->
<div class="flex flex-col sm:flex-row items-center justify-center gap-4 mb-16">
<button
@click="scrollToScanner"
class="shimmer-btn bg-white text-zinc-950 hover:bg-zinc-200 rounded-full px-8 py-3 text-base font-medium shadow-lg shadow-white/10 flex items-center gap-2"
>
Mulai Klasifikasi
@ -47,7 +48,7 @@
<!-- Social Proof -->
<div class="flex flex-col items-center gap-4">
<div class="flex items-center -space-x-3">
<!-- <div class="flex items-center -space-x-3">
<img
v-for="(avatar, index) in avatars"
:key="index"
@ -56,9 +57,9 @@
class="w-10 h-10 rounded-full border-2 border-zinc-950 object-cover"
loading="lazy"
/>
</div>
</div> -->
<p class="text-sm text-zinc-500">
Telah digunakan oleh <span class="text-zinc-300 font-medium">2,000+</span> orang
Telah digunakan <span class="text-zinc-300 font-medium">{{ totalClassifications ? totalClassifications.toLocaleString('id-ID') : '0' }}</span> kali
</p>
</div>
</div>
@ -68,6 +69,14 @@
<script setup lang="ts">
import { ArrowRight } from 'lucide-vue-next'
defineProps<{
totalClassifications?: number
}>()
const scrollToScanner = () => {
document.getElementById('klasifikasi')?.scrollIntoView({ behavior: 'smooth' })
}
const avatars = [
'/professional-headshot-1.png',
'/professional-headshot-2.png',

View File

@ -21,13 +21,23 @@
Unggah foto biji kopi Arabika Anda. Pastikan gambar jelas dan mendapatkan pencahayaan yang cukup untuk hasil terbaik.
</p>
<div class="flex items-center gap-3">
<div class="flex flex-wrap items-center gap-3">
<div class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-emerald-500/10 border border-emerald-500/20">
<div :class="['w-2 h-2 rounded-full bg-emerald-500', isLoading ? 'animate-ping' : 'animate-pulse']"></div>
<span class="text-[10px] font-bold text-emerald-500 uppercase tracking-wider">
{{ isLoading ? 'Processing...' : 'AI Model Ready' }}
</span>
</div>
<button
@click="showGuideModal = true"
class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-zinc-800/80 border border-zinc-700 hover:border-emerald-500/50 hover:bg-zinc-800 transition-all group"
>
<Info class="w-3.5 h-3.5 text-zinc-400 group-hover:text-emerald-400 transition-colors" />
<span class="text-[10px] font-bold text-zinc-400 group-hover:text-emerald-400 uppercase tracking-wider transition-colors">
Panduan Foto
</span>
</button>
</div>
</div>
@ -128,6 +138,77 @@
</div>
</div>
<!-- Modal Panduan -->
<transition
enter-active-class="transition duration-300 ease-out"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition duration-200 ease-in"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div v-if="showGuideModal" class="fixed inset-0 z-[100] flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm" @click="showGuideModal = false">
<div class="bg-zinc-900 border border-zinc-800 rounded-3xl max-w-3xl w-full p-6 sm:p-8 relative overflow-hidden shadow-2xl" @click.stop>
<button @click="showGuideModal = false" class="absolute top-4 right-4 text-zinc-400 hover:text-white bg-zinc-800 hover:bg-zinc-700 p-2 rounded-full transition-colors z-10">
<X class="w-5 h-5" />
</button>
<div class="flex items-center gap-3 mb-8 pr-8">
<div class="p-2.5 rounded-xl bg-emerald-500/10">
<Info class="w-6 h-6 text-emerald-500" />
</div>
<h3 class="text-2xl font-bold text-white font-display">Panduan Pengambilan Foto</h3>
</div>
<div class="grid md:grid-cols-2 gap-8 items-center">
<div class="space-y-4">
<div class="bg-black/50 rounded-2xl overflow-hidden border border-zinc-800 relative group">
<img src="/pict_example.jpg" alt="Contoh Foto Benar" class="w-full h-auto aspect-video object-cover" />
<div class="absolute inset-0 border-2 border-emerald-500/0 group-hover:border-emerald-500/50 rounded-2xl transition-colors pointer-events-none"></div>
</div>
<div class="flex items-center gap-2 text-emerald-400 text-sm font-medium">
<div class="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></div>
Contoh Foto yang Benar
</div>
</div>
<div class="flex flex-col justify-center space-y-6">
<div>
<h4 class="text-lg font-bold text-white mb-3 flex items-center gap-2">
<span class="text-emerald-500">Tips</span> agar hasil akurat:
</h4>
<ul class="space-y-3">
<li class="flex items-start gap-3">
<div class="min-w-[24px] h-6 rounded-full bg-emerald-500/10 text-emerald-500 flex items-center justify-center text-xs font-bold mt-0.5 border border-emerald-500/20">1</div>
<p class="text-zinc-300 text-sm leading-relaxed">Pastikan objek biji kopi <strong>fokus</strong> dan tidak buram (blur).</p>
</li>
<li class="flex items-start gap-3">
<div class="min-w-[24px] h-6 rounded-full bg-emerald-500/10 text-emerald-500 flex items-center justify-center text-xs font-bold mt-0.5 border border-emerald-500/20">2</div>
<p class="text-zinc-300 text-sm leading-relaxed">Gunakan <strong>pencahayaan yang cukup</strong> (cahaya matahari/lampu terang) agar tekstur dan warna jelas.</p>
</li>
<li class="flex items-start gap-3">
<div class="min-w-[24px] h-6 rounded-full bg-emerald-500/10 text-emerald-500 flex items-center justify-center text-xs font-bold mt-0.5 border border-emerald-500/20">3</div>
<p class="text-zinc-300 text-sm leading-relaxed">Hindari <strong>bayangan yang terlalu gelap</strong> atau pantulan cahaya yang menyilaukan.</p>
</li>
<li class="flex items-start gap-3">
<div class="min-w-[24px] h-6 rounded-full bg-emerald-500/10 text-emerald-500 flex items-center justify-center text-xs font-bold mt-0.5 border border-emerald-500/20">4</div>
<p class="text-zinc-300 text-sm leading-relaxed">Ambil foto dari <strong>jarak yang pas</strong>. Biji kopi harus terlihat jelas secara keseluruhan.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="mt-8 pt-6 border-t border-zinc-800 flex justify-end">
<button @click="showGuideModal = false" class="px-6 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-bold rounded-xl transition-colors">
Mengerti
</button>
</div>
</div>
</div>
</transition>
</section>
</template>
@ -135,12 +216,13 @@
import { ref, computed } from 'vue'
import { router } from '@inertiajs/vue3'
import { route } from 'ziggy-js'
import { Upload, Plus, X, Loader2, Bean } from 'lucide-vue-next'
import { Upload, Plus, X, Loader2, Bean, Info } from 'lucide-vue-next'
const imagePreview = ref<string | null>(null)
const selectedFile = ref<File | null>(null)
const predictionResult = ref<{ label: string, confidence: string, details?: string, status?: string } | null>(null)
const isLoading = ref(false)
const showGuideModal = ref(false)
const statusInfo = computed(() => {
if (!predictionResult.value) return null

View File

@ -1,7 +1,7 @@
<template>
<div class="bg-background text-foreground min-h-screen">
<Navbar />
<Hero />
<Hero :total-classifications="totalClassifications" />
<Logo />
<Scanner />
<Keunggulan />
@ -21,4 +21,8 @@ import Scanner from '@/components/public/Scanner.vue'
import Teknologi from '@/components/public/Teknologi.vue'
import FAQ from '@/components/public/FAQ.vue'
import FinalCta from '@/components/public/FinalCta.vue'
defineProps<{
totalClassifications?: number
}>()
</script>

View File

@ -6,6 +6,7 @@
use App\Http\Controllers\Admin\DashboardController;
use App\Http\Controllers\Public\ClassificationController;
use App\Http\Controllers\Admin\ClassificationController as AdminClassificationController;
use App\Models\Classification;
Route::get('dashboard', function () {
if (auth()->user()->role === 'admin') {
@ -17,6 +18,7 @@
Route::get('/', function () {
return inertia('public/Home', [
'canRegister' => Features::enabled(Features::registration()),
'totalClassifications' => Classification::count(),
]);
})->name('home');