Update Logo Odoo & Client, remove testimoni
tests / ci (push) Canceled after 0s

This commit is contained in:
2026-09-29 11:37:08 +07:00
parent 26675424a2
commit 04fbddba13
11 changed files with 172 additions and 156 deletions
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

@@ -0,0 +1,16 @@
import { cn } from '@/lib/utils';
/** Official "Odoo Learning Partner" badge artwork. Size it with `className`. */
export default function OdooPartnerBadge({
className,
}: {
className?: string;
}) {
return (
<img
src="/images/probindo/odoo-learning-partner.svg"
alt="Odoo Learning Partner"
className={cn('h-14 w-auto object-contain', className)}
/>
);
}
+6 -8
View File
@@ -43,7 +43,7 @@ const id = {
icon: 'domain', icon: 'domain',
title: 'Awal Berdiri & Fondasi Industri', title: 'Awal Berdiri & Fondasi Industri',
description: description:
'Didirikan di Jakarta oleh Notaris Joenoes E. Maogimon, SH. Berawal dari aktivitas trading terkemuka di sektor Oil & Gas dan Industri Baja (Steel).', 'PT Probindo Artika Jaya didirikan di Jakarta pada tahun 1985 di hadapan Notaris Joenoes E. Maogimon, SH. Pada masa awal, perusahaan bergerak sebagai perusahaan trading terkemuka yang melayani sektor Oil & Gas dan Industri Baja (Steel). Pengalaman berhubungan langsung dengan operasional klien inilah yang kelak menjadi bekal kami dalam memahami proses bisnis.',
note: { note: {
icon: 'oil_barrel', icon: 'oil_barrel',
label: 'Oil & Gas • Steel Procurement', label: 'Oil & Gas • Steel Procurement',
@@ -54,8 +54,7 @@ const id = {
year: '2002', year: '2002',
icon: 'precision_manufacturing', icon: 'precision_manufacturing',
title: 'Evolusi Teknologi Informasi (TI)', title: 'Evolusi Teknologi Informasi (TI)',
description: description: `Pada tahun 2002 perusahaan bertransformasi menjadi konsultan Sistem Informasi dan Teknologi Informasi, dengan fokus pada perancangan, pembangunan, dan implementasi aplikasi bisnis. Sejak itu PAJ telah menangani ${projects.length} proyek untuk ${clientCount} klien pemerintahan, BUMN, dan swasta — mulai dari sistem pemantauan harga Kementerian Perdagangan hingga layanan perizinan investasi BKPM.`,
'Bertransformasi menjadi konsultan Sistem Informasi dan TI, memusatkan fokus pada perancangan, pembangunan, dan implementasi aplikasi bisnis otomatis.',
note: { note: {
icon: 'data_object', icon: 'data_object',
label: 'Automated Business Applications', label: 'Automated Business Applications',
@@ -67,7 +66,7 @@ const id = {
icon: 'handshake', icon: 'handshake',
title: 'Kemitraan Resmi dengan Odoo', title: 'Kemitraan Resmi dengan Odoo',
description: description:
'Tetap berfokus sebagai konsultan IT, PAJ kini juga menjadi mitra resmi Odoo untuk menghadirkan implementasi ERP yang disesuaikan dengan kebutuhan klien.', 'Meski baru resmi bermitra dengan Odoo pada 2026, pengalaman kami dengan platform ini sudah terbangun sejak masih bernama OpenERP: implementasi OpenERP Community di Badan Informasi Geospasial (2014–2022) dan CV Mujur Jaya Abadi (2015), lalu Odoo Enterprise di Marawah Beach Club setelah OpenERP bertransformasi menjadi Odoo.',
note: { note: {
icon: 'verified', icon: 'verified',
label: 'Official Odoo Learning Partner', label: 'Official Odoo Learning Partner',
@@ -234,7 +233,7 @@ const en: typeof id = {
icon: 'domain', icon: 'domain',
title: 'Founding & Industrial Roots', title: 'Founding & Industrial Roots',
description: description:
'Founded in Jakarta before Notary Joenoes E. Maogimon, SH. It began as a leading trading company in the Oil & Gas and Steel industries.', 'PT Probindo Artika Jaya was founded in Jakarta in 1985 before Notary Joenoes E. Maogimon, SH. In its early years, it operated as a leading trading company serving the Oil & Gas and Steel industries. Working closely with clients’ operations during this period later became the foundation for how we understand business processes.',
note: { note: {
icon: 'oil_barrel', icon: 'oil_barrel',
label: 'Oil & Gas • Steel Procurement', label: 'Oil & Gas • Steel Procurement',
@@ -245,8 +244,7 @@ const en: typeof id = {
year: '2002', year: '2002',
icon: 'precision_manufacturing', icon: 'precision_manufacturing',
title: 'Evolution into Information Technology', title: 'Evolution into Information Technology',
description: description: `In 2002, the company transformed into an Information Systems and Information Technology consultant, focused on designing, building, and implementing business applications. Since then, PAJ has delivered ${projects.length} projects for ${clientCount} government, state-owned, and private clients — from the Ministry of Trade’s price monitoring systems to BKPM’s investment licensing services.`,
'Transformed into an Information Systems and IT consultant, focused on designing, building, and implementing automated business applications.',
note: { note: {
icon: 'data_object', icon: 'data_object',
label: 'Automated Business Applications', label: 'Automated Business Applications',
@@ -258,7 +256,7 @@ const en: typeof id = {
icon: 'handshake', icon: 'handshake',
title: 'Official Partnership with Odoo', title: 'Official Partnership with Odoo',
description: description:
'While remaining focused as an IT consultant, PAJ is now also an official Odoo partner, delivering ERP implementations tailored to each client’s needs.', 'Although our official Odoo partnership began in 2026, our experience with the platform goes back to when it was still called OpenERP: OpenERP Community implementations at the Geospatial Information Agency (2014–2022) and CV Mujur Jaya Abadi (2015), followed by Odoo Enterprise at Marawah Beach Club after OpenERP became Odoo.',
note: { note: {
icon: 'verified', icon: 'verified',
label: 'Official Odoo Learning Partner', label: 'Official Odoo Learning Partner',
+16 -44
View File
@@ -86,9 +86,9 @@ const id = {
program: 'erp', program: 'erp',
icon: 'hub', icon: 'hub',
title: 'Implementasi & Pengembangan Sistem ERP', title: 'Implementasi & Pengembangan Sistem ERP',
client: 'Marawah Beach Club & PT Cipta Kridatama', client: 'BIG, CV Mujur Jaya Abadi, PT Titis Sampurna & Marawah Beach Club',
summary: summary:
'Implementasi Odoo ERP serta enhancement sistem manajemen perusahaan sesuai proses bisnis klien.', 'Pengembangan dan implementasi sistem ERP untuk instansi pemerintahan dan perusahaan swasta — OpenERP Community untuk manajemen dokumen di BIG serta akunting, manufaktur, dan inventory di CV Mujur Jaya Abadi, Odoo Enterprise untuk POS, event, dan website di Marawah Beach Club, hingga sistem informasi akuntansi PT Titis Sampurna, lengkap dengan custom development.',
}, },
] as { ] as {
program: ProjectProgram; program: ProjectProgram;
@@ -136,26 +136,12 @@ const id = {
description: description:
'Apresiasi nyata atas komitmen tanpa henti dari tim konsultan teknis PT Probindo Artika Jaya.', 'Apresiasi nyata atas komitmen tanpa henti dari tim konsultan teknis PT Probindo Artika Jaya.',
rating: 'Rating 5 dari 5', rating: 'Rating 5 dari 5',
items: [ items: [] as {
{ initials: string;
initials: 'DO', quote: string;
quote: 'Keahlian teknis tim PAJ dalam memahami proses rolling baja dan pemetaan sertifikat heat treatment sangat luar biasa. Sistem berjalan stabil tanpa kendala berarti selama lebih dari 6 tahun operasional.', role: string;
role: 'Direktur Operasional', organization: string;
organization: 'Manufaktur Baja & Fabrikasi Logam', }[],
},
{
initials: 'HI',
quote: 'Integrasi Odoo dengan bridging DJP Faktur memangkas beban kerja departemen akuntansi kami secara drastis. Yang paling berharga adalah transparansi arsitekturnya, tidak ada ketergantungan yang menyulitkan.',
role: 'Head of Enterprise IT',
organization: 'Holding Korporasi & Ritel Nasional',
},
{
initials: 'ML',
quote: 'Di industri migas, keandalan sistem material tracing adalah penentu keselamatan kerja rig. PAJ merancang alur verifikasi logistik yang sangat presisi dan mampu bertahan di koneksi satelit minim.',
role: 'Manajer Logistik & Rantai Pasok',
organization: 'Konsorsium Migas Lepas Pantai',
},
],
}, },
reliability: { reliability: {
eyebrow: 'Reliability Index & Audit Trail', eyebrow: 'Reliability Index & Audit Trail',
@@ -273,9 +259,9 @@ const en: typeof id = {
program: 'erp', program: 'erp',
icon: 'hub', icon: 'hub',
title: 'ERP Implementation & Development', title: 'ERP Implementation & Development',
client: 'Marawah Beach Club & PT Cipta Kridatama', client: 'BIG, CV Mujur Jaya Abadi, PT Titis Sampurna & Marawah Beach Club',
summary: summary:
'Odoo ERP implementation and enhancement of company management systems to fit each client’s business processes.', 'ERP development and implementation for government institutions and private companies — OpenERP Community for document management at BIG and for accounting, manufacturing, and inventory at CV Mujur Jaya Abadi, Odoo Enterprise for POS, events, and website at Marawah Beach Club, and an accounting information system for PT Titis Sampurna, all with custom development.',
}, },
], ],
}, },
@@ -317,26 +303,12 @@ const en: typeof id = {
description: description:
'Genuine appreciation for the unwavering commitment of PT Probindo Artika Jaya’s technical consultants.', 'Genuine appreciation for the unwavering commitment of PT Probindo Artika Jaya’s technical consultants.',
rating: 'Rated 5 out of 5', rating: 'Rated 5 out of 5',
items: [ items: [] as {
{ initials: string;
initials: 'DO', quote: string;
quote: 'The PAJ team’s technical expertise in steel rolling processes and heat treatment certificate mapping is outstanding. The system has run stably, without significant issues, for more than 6 years of operation.', role: string;
role: 'Director of Operations', organization: string;
organization: 'Steel Manufacturing & Metal Fabrication', }[],
},
{
initials: 'HI',
quote: 'Integrating Odoo with a DJP Faktur bridge drastically cut our accounting department’s workload. Most valuable of all is the transparent architecture — no dependencies that hold us back.',
role: 'Head of Enterprise IT',
organization: 'National Corporate & Retail Holding',
},
{
initials: 'ML',
quote: 'In oil & gas, reliable material tracing determines rig safety. PAJ designed a highly precise logistics verification flow that holds up even on minimal satellite connections.',
role: 'Logistics & Supply Chain Manager',
organization: 'Offshore Oil & Gas Consortium',
},
],
}, },
reliability: { reliability: {
eyebrow: 'Reliability Index & Audit Trail', eyebrow: 'Reliability Index & Audit Trail',
+14 -28
View File
@@ -7,9 +7,9 @@ const id = {
badge: 'Est. 2002 • IT & Automated Systems Consultant', badge: 'Est. 2002 • IT & Automated Systems Consultant',
title: 'Empowering Enterprise Through ==Custom Software== & Automated Systems', title: 'Empowering Enterprise Through ==Custom Software== & Automated Systems',
description: description:
'PT Probindo Artika Jaya merancang, membangun, dan mengimplementasikan aplikasi bisnis **tailor-fit** serta sistem otomasi proses bisnis berstandar enterprise — dipercaya oleh industri berat, perminyakan, dan manufaktur Indonesia sejak 2002.', 'PT Probindo Artika Jaya merancang, membangun, dan mengimplementasikan aplikasi bisnis **tailor-fit** serta sistem otomasi proses bisnis berstandar enterprise — dipercaya oleh instansi pemerintahan, BUMN, dan perusahaan swasta sejak 2002.',
primaryAction: 'Jadwalkan Audit Sistem', primaryAction: 'Jadwalkan Konsultasi',
secondaryAction: 'Eksplorasi 8 Jasa Resmi', secondaryAction: 'Lihat Layanan Kami',
trustBefore: 'Dipercaya oleh', trustBefore: 'Dipercaya oleh',
trustLink: `${clientCount} klien`, trustLink: `${clientCount} klien`,
trustAfter: 'dari instansi pemerintahan, BUMN, dan perusahaan swasta.', trustAfter: 'dari instansi pemerintahan, BUMN, dan perusahaan swasta.',
@@ -79,17 +79,11 @@ const id = {
}, },
], ],
sectors: { sectors: {
eyebrow: 'Sektor Strategis & Rekam Jejak Industri', eyebrow: 'Klien & Rekam Jejak Proyek',
description: description:
'Mitra Terpercaya Solusi Bisnis & Sistem Otomasi Terintegrasi untuk Sektor Strategis Nasional', 'Dipercaya instansi pemerintahan, BUMN, dan perusahaan swasta untuk membangun dan memelihara sistem informasinya.',
since: 'KONSULTAN IT SEJAK 2002', since: `${projects.length} PROYEK • ${clientCount} KLIEN • SEJAK 2002`,
items: [ more: 'Lihat semua klien & proyek',
'Industri Minyak & Gas Bumi (Oil & Gas)',
'Industri Fabrikasi & Pengolahan Baja',
'Perusahaan Manufaktur & Logistik',
'Korporasi Swasta & BUMN Nasional',
'Institusi Layanan & Komersial',
],
}, },
profile: { profile: {
eyebrow: 'Profil & Rekam Jejak Perusahaan', eyebrow: 'Profil & Rekam Jejak Perusahaan',
@@ -119,7 +113,6 @@ const id = {
'Siklus lengkap dukungan enterprise — mulai dari analisis pra-pengembangan, implementasi, alih pengetahuan user, hingga evaluasi kapasitas berkala.', 'Siklus lengkap dukungan enterprise — mulai dari analisis pra-pengembangan, implementasi, alih pengetahuan user, hingga evaluasi kapasitas berkala.',
}, },
odoo: { odoo: {
badge: 'OFFICIAL ODOO LEARNING PARTNER',
title: 'Implementasi Odoo ERP', title: 'Implementasi Odoo ERP',
subtitle: 'Modular & Disesuaikan dengan Kebutuhan Anda', subtitle: 'Modular & Disesuaikan dengan Kebutuhan Anda',
description: description:
@@ -150,9 +143,9 @@ const en: typeof id = {
badge: 'Est. 2002 • IT & Automated Systems Consultant', badge: 'Est. 2002 • IT & Automated Systems Consultant',
title: 'Empowering Enterprise Through ==Custom Software== & Automated Systems', title: 'Empowering Enterprise Through ==Custom Software== & Automated Systems',
description: description:
'PT Probindo Artika Jaya designs, builds, and implements **tailor-fit** business applications and enterprise-grade business process automation — trusted by Indonesia’s heavy industry, oil & gas, and manufacturing sectors since 2002.', 'PT Probindo Artika Jaya designs, builds, and implements **tailor-fit** business applications and enterprise-grade business process automation — trusted by government institutions, state-owned enterprises, and private companies since 2002.',
primaryAction: 'Schedule a System Audit', primaryAction: 'Schedule a Consultation',
secondaryAction: 'Explore Our 8 Official Services', secondaryAction: 'Explore Our Services',
trustBefore: 'Trusted by', trustBefore: 'Trusted by',
trustLink: `${clientCount} clients`, trustLink: `${clientCount} clients`,
trustAfter: trustAfter:
@@ -223,17 +216,11 @@ const en: typeof id = {
}, },
], ],
sectors: { sectors: {
eyebrow: 'Strategic Sectors & Industry Track Record', eyebrow: 'Clients & Project Track Record',
description: description:
'A Trusted Partner for Business Solutions & Integrated Automation in National Strategic Sectors', 'Trusted by government institutions, state-owned enterprises, and private companies to build and maintain their information systems.',
since: 'IT CONSULTANT SINCE 2002', since: `${projects.length} PROJECTS • ${clientCount} CLIENTS • SINCE 2002`,
items: [ more: 'See all clients & projects',
'Oil & Gas Industry',
'Steel Fabrication & Processing',
'Manufacturing & Logistics Companies',
'Private Corporations & State-Owned Enterprises',
'Service & Commercial Institutions',
],
}, },
profile: { profile: {
eyebrow: 'Company Profile & Track Record', eyebrow: 'Company Profile & Track Record',
@@ -263,7 +250,6 @@ const en: typeof id = {
'A complete cycle of enterprise support — from pre-development analysis and implementation to user knowledge transfer and periodic capacity evaluation.', 'A complete cycle of enterprise support — from pre-development analysis and implementation to user knowledge transfer and periodic capacity evaluation.',
}, },
odoo: { odoo: {
badge: 'OFFICIAL ODOO LEARNING PARTNER',
title: 'Odoo ERP Implementation', title: 'Odoo ERP Implementation',
subtitle: 'Modular & Tailored to Your Needs', subtitle: 'Modular & Tailored to Your Needs',
description: description:
-2
View File
@@ -25,7 +25,6 @@ const id = {
badge: 'STANDAR PROBINDO ARTIKA JAYA', badge: 'STANDAR PROBINDO ARTIKA JAYA',
}, },
odoo: { odoo: {
badge: 'OFFICIAL ODOO LEARNING PARTNER',
title: 'Implementasi Odoo ERP Sesuai Kebutuhan Bisnis Anda', title: 'Implementasi Odoo ERP Sesuai Kebutuhan Bisnis Anda',
description: description:
'Menghadirkan ekosistem Enterprise Resource Planning kelas dunia yang dikonfigurasi mengikuti proses bisnis Anda. Kami hanya mengimplementasikan modul yang benar-benar dibutuhkan — dari keuangan, rantai pasok, hingga manufaktur — sehingga sistem tetap ramping dan mudah diadopsi.', 'Menghadirkan ekosistem Enterprise Resource Planning kelas dunia yang dikonfigurasi mengikuti proses bisnis Anda. Kami hanya mengimplementasikan modul yang benar-benar dibutuhkan — dari keuangan, rantai pasok, hingga manufaktur — sehingga sistem tetap ramping dan mudah diadopsi.',
@@ -154,7 +153,6 @@ const en: typeof id = {
badge: 'PROBINDO ARTIKA JAYA STANDARD', badge: 'PROBINDO ARTIKA JAYA STANDARD',
}, },
odoo: { odoo: {
badge: 'OFFICIAL ODOO LEARNING PARTNER',
title: 'Odoo ERP Implementation Tailored to Your Business', title: 'Odoo ERP Implementation Tailored to Your Business',
description: description:
'A world-class Enterprise Resource Planning ecosystem, configured around your business processes. We implement only the modules you actually need — from finance and supply chain to manufacturing — so the system stays lean and easy to adopt.', 'A world-class Enterprise Resource Planning ecosystem, configured around your business processes. We implement only the modules you actually need — from finance and supply chain to manufacturing — so the system stays lean and easy to adopt.',
+34 -6
View File
@@ -13,6 +13,8 @@ export type Project = {
year: number; year: number;
sector: ProjectSector; sector: ProjectSector;
program?: ProjectProgram; program?: ProjectProgram;
/** Optional detail of what the project covered. */
scope?: string;
}; };
const government: Omit<Project, 'sector'>[] = [ const government: Omit<Project, 'sector'>[] = [
@@ -60,6 +62,8 @@ const government: Omit<Project, 'sector'>[] = [
title: 'Pengembangan Aplikasi LDH', title: 'Pengembangan Aplikasi LDH',
client: 'Badan Informasi Geospasial (BIG)', client: 'Badan Informasi Geospasial (BIG)',
year: 2022, year: 2022,
program: 'erp',
scope: 'OpenERP Community: manajemen dokumen dan custom development',
}, },
{ {
title: 'Perawatan Sistem Pelaporan Harga', title: 'Perawatan Sistem Pelaporan Harga',
@@ -183,6 +187,8 @@ const government: Omit<Project, 'sector'>[] = [
title: 'Pengembangan Sistem Aplikasi Jaringan Informasi Dokumentasi Hukum', title: 'Pengembangan Sistem Aplikasi Jaringan Informasi Dokumentasi Hukum',
client: 'Badan Informasi Geospasial (BIG)', client: 'Badan Informasi Geospasial (BIG)',
year: 2016, year: 2016,
program: 'erp',
scope: 'OpenERP Community: manajemen dokumen dan custom development',
}, },
{ {
title: 'Verifikasi Pelaporan Harga Barang Pokok pada Sistem Pemantauan Pasar Kebutuhan Pokok (SP2KP)', title: 'Verifikasi Pelaporan Harga Barang Pokok pada Sistem Pemantauan Pasar Kebutuhan Pokok (SP2KP)',
@@ -199,7 +205,7 @@ const government: Omit<Project, 'sector'>[] = [
{ {
title: 'Pembuatan Software pada Kegiatan Penguatan Regional Climate Change Center', title: 'Pembuatan Software pada Kegiatan Penguatan Regional Climate Change Center',
client: 'Badan Meteorologi Klimatologi dan Geofisika (BMKG)', client: 'Badan Meteorologi Klimatologi dan Geofisika (BMKG)',
year: 2025, year: 2015,
}, },
{ {
title: 'Kajian Tata Kelola Teknologi Informasi BKPM TA 2014', title: 'Kajian Tata Kelola Teknologi Informasi BKPM TA 2014',
@@ -223,6 +229,8 @@ const government: Omit<Project, 'sector'>[] = [
title: 'Pembangunan Sistem Informasi Pelayanan Dokumen Hukum', title: 'Pembangunan Sistem Informasi Pelayanan Dokumen Hukum',
client: 'Badan Informasi Geospasial (BIG)', client: 'Badan Informasi Geospasial (BIG)',
year: 2014, year: 2014,
program: 'erp',
scope: 'OpenERP Community: manajemen dokumen dan custom development',
}, },
{ {
title: 'Pendampingan Helpdesk Implementasi Sistem Pelayanan Informasi dan Perizinan Investasi Secara Elektronik (SPIPISE)', title: 'Pendampingan Helpdesk Implementasi Sistem Pelayanan Informasi dan Perizinan Investasi Secara Elektronik (SPIPISE)',
@@ -245,6 +253,8 @@ const government: Omit<Project, 'sector'>[] = [
title: 'Pembangunan Aplikasi Jaringan Dokumentasi dan Informasi Hukum', title: 'Pembangunan Aplikasi Jaringan Dokumentasi dan Informasi Hukum',
client: 'Badan Informasi Geospasial (BIG)', client: 'Badan Informasi Geospasial (BIG)',
year: 2012, year: 2012,
program: 'erp',
scope: 'OpenERP Community: manajemen dokumen dan custom development',
}, },
{ {
title: 'Pengembangan Portal National Single Window for Investment (NSWI) untuk Mendukung SPIPISE BKPM', title: 'Pengembangan Portal National Single Window for Investment (NSWI) untuk Mendukung SPIPISE BKPM',
@@ -271,12 +281,24 @@ const privateSector: Omit<Project, 'sector'>[] = [
client: 'Marawah Beach Club', client: 'Marawah Beach Club',
year: 2022, year: 2022,
program: 'erp', program: 'erp',
scope: 'Odoo Enterprise: POS, event, pembelian, penjualan, website, dan custom development',
}, },
{ {
title: 'Enhancement Manajemen Sistem', title: 'Enhancement Manajemen Sistem',
client: 'PT Cipta Kridatama', client: 'PT Cipta Kridatama',
year: 2022, year: 2022,
},
{
title: 'Implementasi OpenERP Manufacturing System',
client: 'CV Mujur Jaya Abadi',
year: 2015,
program: 'erp', program: 'erp',
scope: 'OpenERP Community: akunting, manufaktur, pembelian, penjualan, inventory, dan custom development',
},
{
title: 'Pengembangan Reswara Integrated Management System',
client: 'PT Reswara Minergi Hartama',
year: 2013,
}, },
{ {
title: 'Kegiatan Pengembangan dan Operasionalisasi Sistem Pemantauan Pasar Kebutuhan Pokok (SP2KP)', title: 'Kegiatan Pengembangan dan Operasionalisasi Sistem Pemantauan Pasar Kebutuhan Pokok (SP2KP)',
@@ -325,6 +347,7 @@ const privateSector: Omit<Project, 'sector'>[] = [
title: 'Pengembangan Aplikasi Titis Sampurna Accounting Information System', title: 'Pengembangan Aplikasi Titis Sampurna Accounting Information System',
client: 'PT Titis Sampurna', client: 'PT Titis Sampurna',
year: 2006, year: 2006,
program: 'erp',
}, },
{ {
title: 'Jasa Konsultasi Pengembangan Sistem Informasi Eksekutif Keuangan', title: 'Jasa Konsultasi Pengembangan Sistem Informasi Eksekutif Keuangan',
@@ -372,13 +395,11 @@ const clientName = (project: Project) =>
/** Number of distinct clients across all projects. */ /** Number of distinct clients across all projects. */
export const clientCount = new Set(projects.map(clientName)).size; export const clientCount = new Set(projects.map(clientName)).size;
/** Distinct clients in a sector, most frequent first. */ /** Distinct clients, most frequent first. */
export const clientsInSector = (sector: ProjectSector) => { const rankClients = (items: Project[]) => {
const counts = new Map<string, number>(); const counts = new Map<string, number>();
projects items.forEach((project) => {
.filter((project) => project.sector === sector)
.forEach((project) => {
const name = clientName(project); const name = clientName(project);
counts.set(name, (counts.get(name) ?? 0) + 1); counts.set(name, (counts.get(name) ?? 0) + 1);
}); });
@@ -388,6 +409,13 @@ export const clientsInSector = (sector: ProjectSector) => {
.map(([name]) => name); .map(([name]) => name);
}; };
export const clientsInSector = (sector: ProjectSector) =>
rankClients(projects.filter((project) => project.sector === sector));
/** Clients with the most projects across every sector. */
export const topClients = (limit: number) =>
rankClients(projects).slice(0, limit);
export const projectsBySector = (sector: ProjectSector) => export const projectsBySector = (sector: ProjectSector) =>
projects.filter((project) => project.sector === sector); projects.filter((project) => project.sector === sector);
+3 -10
View File
@@ -6,6 +6,7 @@ import Glow from '@/components/site/glow';
import Icon from '@/components/site/icon'; import Icon from '@/components/site/icon';
import IconTile from '@/components/site/icon-tile'; import IconTile from '@/components/site/icon-tile';
import ImageCard from '@/components/site/image-card'; import ImageCard from '@/components/site/image-card';
import OdooPartnerBadge from '@/components/site/odoo-partner-badge';
import PageHero from '@/components/site/page-hero'; import PageHero from '@/components/site/page-hero';
import RichText from '@/components/site/rich-text'; import RichText from '@/components/site/rich-text';
import Section from '@/components/site/section'; import Section from '@/components/site/section';
@@ -40,16 +41,8 @@ export default function About() {
{t.hero.stats.map((stat) => ( {t.hero.stats.map((stat) => (
<StatCard key={stat.label} {...stat} /> <StatCard key={stat.label} {...stat} />
))} ))}
<Card className="col-span-2 flex items-center justify-between lg:col-span-1"> <Card className="col-span-2 flex items-center justify-center lg:col-span-1">
<div className="flex flex-col"> <OdooPartnerBadge className="h-16" />
<span className="font-display text-on-surface text-3xl font-bold">
Official
</span>
<span className="text-primary font-mono text-xs font-semibold tracking-wider uppercase">
Odoo Partner
</span>
</div>
<IconTile icon="verified_user" size="md" />
</Card> </Card>
</div> </div>
</div> </div>
+61 -45
View File
@@ -118,51 +118,7 @@ export default function Clients() {
</div> </div>
</Section> </Section>
<Section> <Testimonials t={t} />
<div className="flex flex-col gap-12">
<SectionHeader
align="split"
eyebrow={t.testimonials.eyebrow}
title={t.testimonials.title}
description={t.testimonials.description}
/>
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
{t.testimonials.items.map((testimonial) => (
<Card
key={testimonial.initials}
className="flex flex-col justify-between gap-6"
>
<div className="space-y-4">
<div
className="text-primary flex"
aria-label={t.testimonials.rating}
>
{Array.from({ length: 5 }, (_, i) => (
<Icon key={i} name="star" filled />
))}
</div>
<blockquote className="text-on-surface text-base italic">
“{testimonial.quote}”
</blockquote>
</div>
<div className="flex items-center gap-3">
<div className="bg-surface-container text-primary flex h-10 w-10 items-center justify-center rounded-full font-mono font-bold">
{testimonial.initials}
</div>
<div>
<div className="text-on-surface text-sm font-bold">
{testimonial.role}
</div>
<span className="text-on-surface-variant text-sm">
{testimonial.organization}
</span>
</div>
</div>
</Card>
))}
</div>
</div>
</Section>
<Section tone="muted"> <Section tone="muted">
<Card <Card
@@ -358,6 +314,11 @@ function SectorPortfolio({ t }: { t: Content }) {
<span className="text-on-surface font-semibold"> <span className="text-on-surface font-semibold">
{project.title} {project.title}
</span> </span>
{project.scope && (
<span className="text-on-surface-variant text-sm">
{project.scope}
</span>
)}
<span className="text-on-surface-variant flex items-center gap-1.5 text-sm"> <span className="text-on-surface-variant flex items-center gap-1.5 text-sm">
<Icon <Icon
name="apartment" name="apartment"
@@ -495,6 +456,61 @@ function FeaturedPrograms({ t }: { t: Content }) {
); );
} }
/** Hidden until real client testimonials are added to the content file. */
function Testimonials({ t }: { t: Content }) {
if (t.testimonials.items.length === 0) {
return null;
}
return (
<Section>
<div className="flex flex-col gap-12">
<SectionHeader
align="split"
eyebrow={t.testimonials.eyebrow}
title={t.testimonials.title}
description={t.testimonials.description}
/>
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
{t.testimonials.items.map((testimonial) => (
<Card
key={testimonial.initials}
className="flex flex-col justify-between gap-6"
>
<div className="space-y-4">
<div
className="text-primary flex"
aria-label={t.testimonials.rating}
>
{Array.from({ length: 5 }, (_, i) => (
<Icon key={i} name="star" filled />
))}
</div>
<blockquote className="text-on-surface text-base italic">
“{testimonial.quote}”
</blockquote>
</div>
<div className="flex items-center gap-3">
<div className="bg-surface-container text-primary flex h-10 w-10 items-center justify-center rounded-full font-mono font-bold">
{testimonial.initials}
</div>
<div>
<div className="text-on-surface text-sm font-bold">
{testimonial.role}
</div>
<span className="text-on-surface-variant text-sm">
{testimonial.organization}
</span>
</div>
</div>
</Card>
))}
</div>
</div>
</Section>
);
}
function RetentionGauge({ t }: { t: Content }) { function RetentionGauge({ t }: { t: Content }) {
return ( return (
<div className="bg-surface-container flex w-full flex-col items-center justify-center rounded-xl p-6 lg:w-96"> <div className="bg-surface-container flex w-full flex-col items-center justify-center rounded-xl p-6 lg:w-96">
+16 -7
View File
@@ -5,6 +5,7 @@ import Eyebrow from '@/components/site/eyebrow';
import Glow, { GridPattern } from '@/components/site/glow'; import Glow, { GridPattern } from '@/components/site/glow';
import Icon from '@/components/site/icon'; import Icon from '@/components/site/icon';
import IconTile from '@/components/site/icon-tile'; import IconTile from '@/components/site/icon-tile';
import OdooPartnerBadge from '@/components/site/odoo-partner-badge';
import Pill from '@/components/site/pill'; import Pill from '@/components/site/pill';
import RichText from '@/components/site/rich-text'; import RichText from '@/components/site/rich-text';
import Section from '@/components/site/section'; import Section from '@/components/site/section';
@@ -13,6 +14,7 @@ import ConsultationSection from '@/components/site/sections/consultation-section
import ServiceGrid from '@/components/site/sections/service-grid'; import ServiceGrid from '@/components/site/sections/service-grid';
import StatCard from '@/components/site/stat-card'; import StatCard from '@/components/site/stat-card';
import { homeContent } from '@/content/home'; import { homeContent } from '@/content/home';
import { topClients } from '@/data/projects';
import { useContent } from '@/hooks/use-locale'; import { useContent } from '@/hooks/use-locale';
import { about, clients, services } from '@/routes'; import { about, clients, services } from '@/routes';
@@ -46,15 +48,24 @@ export default function Home() {
</span> </span>
</div> </div>
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-5"> <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-5">
{t.sectors.items.map((sector) => ( {topClients(10).map((client) => (
<div <div
key={sector} key={client}
className="border-outline-variant/40 bg-surface-container text-on-surface hover:border-primary/50 hover:bg-surface-container-high flex h-16 items-center justify-center rounded-xl border px-4 text-center font-mono text-xs font-medium transition-all" className="border-outline-variant/40 bg-surface-container text-on-surface hover:border-primary/50 hover:bg-surface-container-high flex min-h-16 items-center justify-center rounded-xl border px-4 py-3 text-center font-mono text-xs font-medium transition-all"
> >
{sector} {client}
</div> </div>
))} ))}
</div> </div>
<ButtonLink
href={clients()}
variant="ghost"
size="inline"
trailingIcon="arrow_forward"
className="self-start"
>
{t.sectors.more}
</ButtonLink>
</div> </div>
</div> </div>
</Section> </Section>
@@ -328,9 +339,7 @@ function OdooSpotlight({ t }: { t: Content }) {
<Glow className="-top-24 -right-24 h-80 w-80 blur-3xl" /> <Glow className="-top-24 -right-24 h-80 w-80 blur-3xl" />
<div className="relative grid grid-cols-1 items-center gap-8 lg:grid-cols-12"> <div className="relative grid grid-cols-1 items-center gap-8 lg:grid-cols-12">
<div className="flex flex-col gap-4 lg:col-span-8"> <div className="flex flex-col gap-4 lg:col-span-8">
<Pill tone="brand" icon="verified"> <OdooPartnerBadge className="self-start" />
{t.odoo.badge}
</Pill>
<h3 className="font-display text-on-surface text-2xl font-extrabold lg:text-3xl"> <h3 className="font-display text-on-surface text-2xl font-extrabold lg:text-3xl">
{t.odoo.title} {t.odoo.title}
<span className="text-on-surface-variant mt-1 block font-sans text-xl font-normal lg:text-2xl"> <span className="text-on-surface-variant mt-1 block font-sans text-xl font-normal lg:text-2xl">
+2 -3
View File
@@ -4,6 +4,7 @@ import Card from '@/components/site/card';
import FeatureCard from '@/components/site/feature-card'; import FeatureCard from '@/components/site/feature-card';
import Glow from '@/components/site/glow'; import Glow from '@/components/site/glow';
import IconTile from '@/components/site/icon-tile'; import IconTile from '@/components/site/icon-tile';
import OdooPartnerBadge from '@/components/site/odoo-partner-badge';
import PageHero from '@/components/site/page-hero'; import PageHero from '@/components/site/page-hero';
import Pill from '@/components/site/pill'; import Pill from '@/components/site/pill';
import RichText from '@/components/site/rich-text'; import RichText from '@/components/site/rich-text';
@@ -83,9 +84,7 @@ export default function Services() {
> >
<div className="grid grid-cols-1 items-center gap-10 lg:grid-cols-12"> <div className="grid grid-cols-1 items-center gap-10 lg:grid-cols-12">
<div className="flex flex-col gap-5 lg:col-span-5"> <div className="flex flex-col gap-5 lg:col-span-5">
<Pill tone="brand" icon="verified"> <OdooPartnerBadge className="self-start" />
{t.odoo.badge}
</Pill>
<h2 className="font-display text-on-surface lg:text-headline-xl text-3xl font-extrabold tracking-tight"> <h2 className="font-display text-on-surface lg:text-headline-xl text-3xl font-extrabold tracking-tight">
{t.odoo.title} {t.odoo.title}
</h2> </h2>