From a0b1d214a0edbab9151e820406b581895fbae854 Mon Sep 17 00:00:00 2001 From: Indra Gunanda Date: Sat, 6 Dec 2025 15:00:05 +0700 Subject: [PATCH 1/2] feat: Refine UI animations, improve code structure, update documentation, and add Lighthouse CI configuration. --- .github/workflows/ci.yml | 28 +++++++++++ CLAUDE.md | 11 ++++- lighthouserc.json | 30 ++++++++++++ src/app/globals.css | 21 ++++++++ src/app/page.tsx | 33 ++----------- src/components/landing/CTA.tsx | 21 ++------ src/components/landing/FAQ.tsx | 44 +++++++++-------- src/components/landing/Features.tsx | 70 +++++++++++---------------- src/components/landing/Hero.tsx | 36 ++++++-------- src/components/landing/Industries.tsx | 33 +++++-------- 10 files changed, 171 insertions(+), 156 deletions(-) create mode 100644 lighthouserc.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 970f5ec..483ef78 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -89,3 +89,31 @@ jobs: run: npm run build env: NEXT_TELEMETRY_DISABLED: 1 + + lighthouse: + name: Lighthouse + runs-on: ubuntu-latest + needs: [build] + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + env: + NEXT_TELEMETRY_DISABLED: 1 + + - name: Run Lighthouse CI + uses: treosh/lighthouse-ci-action@v12 + with: + configPath: './lighthouserc.json' + uploadArtifacts: true + temporaryPublicStorage: true diff --git a/CLAUDE.md b/CLAUDE.md index 8d8663c..2f90b32 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,6 +6,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Etags is a Next.js 16 application for product tagging and blockchain stamping. It manages brands, products, and tags with blockchain transaction tracking for authentication/verification purposes. +**Node.js requirement:** 20.x (LTS) + ## Commands - `npm run dev` - Start development server @@ -221,7 +223,14 @@ Solidity contracts are in `smartcontracts/` directory with separate Hardhat setu - `ETagRegistry.sol` - Main contract for tag lifecycle management (create, validate, update status, revoke) - `ETagCollectible.sol` - ERC721 NFT contract for collectibles (one NFT per tag) -See `smartcontracts/README.md` for contract development and testing. +Contract commands (run from `smartcontracts/` directory): + +- `npm run compile` - Compile contracts +- `npm run test` - Run contract tests +- `npm run deploy:local` - Deploy to local Hardhat node +- `npm run deploy:sepolia` - Deploy to Base Sepolia testnet + +See `smartcontracts/README.md` for full contract development documentation. ## Environment Variables diff --git a/lighthouserc.json b/lighthouserc.json new file mode 100644 index 0000000..c3208f8 --- /dev/null +++ b/lighthouserc.json @@ -0,0 +1,30 @@ +{ + "ci": { + "collect": { + "startServerCommand": "npm run start", + "startServerReadyPattern": "Ready", + "url": ["http://localhost:3000/"], + "numberOfRuns": 3, + "settings": { + "preset": "desktop", + "onlyCategories": [ + "performance", + "accessibility", + "best-practices", + "seo" + ] + } + }, + "assert": { + "assertions": { + "categories:performance": ["warn", { "minScore": 0.7 }], + "categories:accessibility": ["error", { "minScore": 0.9 }], + "categories:best-practices": ["warn", { "minScore": 0.8 }], + "categories:seo": ["warn", { "minScore": 0.8 }] + } + }, + "upload": { + "target": "temporary-public-storage" + } + } +} diff --git a/src/app/globals.css b/src/app/globals.css index 79da25f..7240d69 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -121,3 +121,24 @@ @apply bg-background text-foreground; } } + +/* Reduced motion support for older devices and accessibility */ +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} + +/* GPU acceleration hints for smoother animations */ +.blur-xl, +.blur-2xl, +.blur-3xl, +.blur-\[80px\] { + will-change: auto; + transform: translateZ(0); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index be24b12..a6b7207 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,3 @@ -'use client'; - -import { motion } from 'framer-motion'; import { Navbar } from '@/components/landing/Navbar'; import { Hero } from '@/components/landing/Hero'; import { Features } from '@/components/landing/Features'; @@ -9,37 +6,13 @@ import { FAQ } from '@/components/landing/FAQ'; import { CTA } from '@/components/landing/CTA'; import { Footer } from '@/components/landing/Footer'; -const MotionDiv = motion.div; - export default function Home() { return (
- {/* Animated Background Effects */} + {/* Static Background Effects - CSS only, no JS animations */}
- - +
+
diff --git a/src/components/landing/CTA.tsx b/src/components/landing/CTA.tsx index a37aee1..6cdd921 100644 --- a/src/components/landing/CTA.tsx +++ b/src/components/landing/CTA.tsx @@ -15,25 +15,12 @@ export function CTA() { initial={{ opacity: 0, scale: 0.95 }} whileInView={{ opacity: 1, scale: 1 }} viewport={{ once: true }} + transition={{ duration: 0.4 }} > - {/* Animated background */} + {/* Static background - no animations */}
- - +
+
diff --git a/src/components/landing/FAQ.tsx b/src/components/landing/FAQ.tsx index 84e9929..343fbe4 100644 --- a/src/components/landing/FAQ.tsx +++ b/src/components/landing/FAQ.tsx @@ -4,6 +4,25 @@ import { motion } from 'framer-motion'; const MotionDiv = motion.div; +const faqItems = [ + { + q: 'Apakah saya perlu crypto untuk menggunakan Etags?', + a: 'Tidak. Kami mengabstraksikan semua kompleksitas blockchain. Anda membayar dalam fiat, kami menangani biaya gas dan manajemen wallet.', + }, + { + q: 'Bisakah QR code disalin?', + a: 'Meskipun penyalinan fisik dimungkinkan, sistem kami mendeteksi scan duplikat dan anomali lokasi/waktu, menandai potensi pemalsuan segera.', + }, + { + q: 'Berapa lama proses integrasi?', + a: 'Anda dapat mulai menandai produk secara manual dalam hitungan menit. Integrasi API untuk lini manufaktur otomatis biasanya memakan waktu 1-2 minggu.', + }, + { + q: 'Apakah data saya publik?', + a: 'Hanya hash verifikasi yang publik. Intelijen bisnis sensitif dan data rantai pasokan Anda tetap pribadi dan terenkripsi.', + }, +]; + export function FAQ() { return (
@@ -13,6 +32,7 @@ export function FAQ() { initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} + transition={{ duration: 0.4 }} >

Pertanyaan yang Sering Diajukan @@ -20,32 +40,14 @@ export function FAQ() {
- {[ - { - q: 'Apakah saya perlu crypto untuk menggunakan Etags?', - a: 'Tidak. Kami mengabstraksikan semua kompleksitas blockchain. Anda membayar dalam fiat, kami menangani biaya gas dan manajemen wallet.', - }, - { - q: 'Bisakah QR code disalin?', - a: 'Meskipun penyalinan fisik dimungkinkan, sistem kami mendeteksi scan duplikat dan anomali lokasi/waktu, menandai potensi pemalsuan segera.', - }, - { - q: 'Berapa lama proses integrasi?', - a: 'Anda dapat mulai menandai produk secara manual dalam hitungan menit. Integrasi API untuk lini manufaktur otomatis biasanya memakan waktu 1-2 minggu.', - }, - { - q: 'Apakah data saya publik?', - a: 'Hanya hash verifikasi yang publik. Intelijen bisnis sensitif dan data rantai pasokan Anda tetap pribadi dan terenkripsi.', - }, - ].map((item, i) => ( + {faqItems.map((item, i) => (

{item.q} diff --git a/src/components/landing/Features.tsx b/src/components/landing/Features.tsx index 915a17c..42dea10 100644 --- a/src/components/landing/Features.tsx +++ b/src/components/landing/Features.tsx @@ -14,12 +14,13 @@ export function Features() {
-
+ {/* Simplified background - reduced blur */} +
@@ -53,17 +54,10 @@ export function Features() {
    {['Pelacakan scan geospasial', 'Peringatan upaya pemalsuan'].map( (item, i) => ( - +
  • {item} - +
  • ) )}
@@ -75,10 +69,10 @@ export function Features() {
@@ -93,28 +87,22 @@ export function Features() {

    {['Verifikasi instan', 'Tanpa download'].map((item, i) => ( - +
  • {item} - +
  • ))}
-
+ {/* Simplified background - reduced blur */} +
-
+ {/* Simplified background - reduced blur */} +
@@ -172,26 +161,21 @@ export function Features() { menciptakan catatan provenance yang tidak dapat dipalsukan.

- + {/* CSS hover instead of framer-motion */} +
99.9%
Uptime
- - +
+
<1dtk
Verifikasi
- +
diff --git a/src/components/landing/Hero.tsx b/src/components/landing/Hero.tsx index 5f5dc1e..9ba6c81 100644 --- a/src/components/landing/Hero.tsx +++ b/src/components/landing/Hero.tsx @@ -18,10 +18,10 @@ export function Hero() { {/* Text Content */}
@@ -33,7 +33,7 @@ export function Hero() { className="mb-6 text-4xl sm:text-5xl lg:text-7xl font-bold tracking-tight text-[#0C2340] leading-[1.1]" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.6, delay: 0.1 }} + transition={{ duration: 0.4, delay: 0.1 }} > Keaslian Produk,{' '} @@ -45,7 +45,7 @@ export function Hero() { className="mb-10 text-lg text-[#808080] leading-relaxed max-w-2xl mx-auto lg:mx-0" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.6, delay: 0.2 }} + transition={{ duration: 0.4, delay: 0.15 }} > Amankan rantai pasokan Anda dengan teknologi distributed ledger yang transparan dan tidak dapat dipalsukan. Berikan kepercayaan @@ -56,7 +56,7 @@ export function Hero() { className="flex flex-col sm:flex-row items-center justify-center lg:justify-start gap-4" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} - transition={{ duration: 0.6, delay: 0.3 }} + transition={{ duration: 0.4, delay: 0.2 }} >
- {/* Hero Illustration */} + {/* Hero Illustration - Static, no infinite animation */}
- {/* Background Glow */} -
+ {/* Background Glow - reduced blur */} +
- {/* Hero Image */} - + {/* Hero Image - no animation, CSS hover only */} +
Blockchain Product Authentication - +
diff --git a/src/components/landing/Industries.tsx b/src/components/landing/Industries.tsx index 1861c14..9e4e554 100644 --- a/src/components/landing/Industries.tsx +++ b/src/components/landing/Industries.tsx @@ -16,6 +16,7 @@ export function Industries() { initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} + transition={{ duration: 0.4 }} >

Disesuaikan untuk industri Anda @@ -27,22 +28,22 @@ export function Industries() {
- + Fashion Elektronik Farmasi @@ -50,11 +51,7 @@ export function Industries() {
- +

Lindungi Edisi Terbatas @@ -83,15 +80,11 @@ export function Industries() { className="w-full h-auto object-contain max-h-full" />

- +
- +

Garansi & Registrasi @@ -120,15 +113,11 @@ export function Industries() { className="w-full h-auto object-contain max-h-full" />

- +
- +

Keselamatan Pasien Utama @@ -157,7 +146,7 @@ export function Industries() { className="w-full h-auto object-contain max-h-full" />

- +

From e6e5e819c4c73c77aecae92ff6c3a44300593657 Mon Sep 17 00:00:00 2001 From: Indra Gunanda Date: Sat, 6 Dec 2025 08:23:20 +0700 Subject: [PATCH 2/2] style: update text color to #606060, refactor footer animations to CSS, and optimize image loading. --- src/app/layout.tsx | 1 - src/components/landing/FAQ.tsx | 2 +- src/components/landing/Features.tsx | 10 +++--- src/components/landing/Footer.tsx | 47 ++++++++++----------------- src/components/landing/Hero.tsx | 3 +- src/components/landing/Industries.tsx | 8 ++--- 6 files changed, 29 insertions(+), 42 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index e373a4b..4ad0123 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -65,7 +65,6 @@ export const viewport = { themeColor: '#0c0a09', width: 'device-width', initialScale: 1, - maximumScale: 1, }; import { SessionProvider } from '@/components/providers/session-provider'; diff --git a/src/components/landing/FAQ.tsx b/src/components/landing/FAQ.tsx index 343fbe4..53e6bd4 100644 --- a/src/components/landing/FAQ.tsx +++ b/src/components/landing/FAQ.tsx @@ -52,7 +52,7 @@ export function FAQ() {

{item.q}

-

{item.a}

+

{item.a}

))}
diff --git a/src/components/landing/Features.tsx b/src/components/landing/Features.tsx index 42dea10..c1008cb 100644 --- a/src/components/landing/Features.tsx +++ b/src/components/landing/Features.tsx @@ -47,7 +47,7 @@ export function Features() {

Keputusan berbasis data untuk rantai pasokan Anda.

-

+

Dapatkan visibilitas di mana produk Anda dipindai. Deteksi aktivitas mencurigakan secara real-time.

@@ -81,7 +81,7 @@ export function Features() {

Cukup arahkan dan scan.

-

+

Scanner berbasis web kami bekerja langsung di browser, memastikan tingkat adopsi yang tinggi tanpa hambatan.

@@ -156,7 +156,7 @@ export function Features() {

Catatan permanen dan anti-rusak.

-

+

Setiap tag produk dicetak sebagai aset digital di blockchain, menciptakan catatan provenance yang tidak dapat dipalsukan.

@@ -166,13 +166,13 @@ export function Features() {
99.9%
-
Uptime
+
Uptime
<1dtk
-
+
Verifikasi
diff --git a/src/components/landing/Footer.tsx b/src/components/landing/Footer.tsx index 5f58771..eebacf7 100644 --- a/src/components/landing/Footer.tsx +++ b/src/components/landing/Footer.tsx @@ -1,15 +1,10 @@ -'use client'; - import Link from 'next/link'; import Image from 'next/image'; -import { motion } from 'framer-motion'; import { Box, Globe } from 'lucide-react'; -const MotionDiv = motion.div; - export function Footer() { return ( -