+58
-396
@@ -1,386 +1,11 @@
|
||||
import type { Project, ProjectProgram, ProjectSector } from '@/types';
|
||||
|
||||
export type { Project, ProjectProgram, ProjectSector } from '@/types';
|
||||
|
||||
/**
|
||||
* PAJ's IT project track record. Project and client names are official
|
||||
* Indonesian names, so they are shown as-is in both languages.
|
||||
* Portfolio helpers. The projects themselves are managed in the admin panel
|
||||
* and arrive as a page prop, already sorted newest first.
|
||||
*/
|
||||
export type ProjectSector = 'government' | 'private' | 'soe';
|
||||
|
||||
/** Long-running programs highlighted as featured case studies. */
|
||||
export type ProjectProgram = 'price-monitoring' | 'investment' | 'erp';
|
||||
|
||||
export type Project = {
|
||||
title: string;
|
||||
client: string;
|
||||
year: number;
|
||||
sector: ProjectSector;
|
||||
program?: ProjectProgram;
|
||||
/** Optional detail of what the project covered. */
|
||||
scope?: string;
|
||||
};
|
||||
|
||||
const government: Omit<Project, 'sector'>[] = [
|
||||
{
|
||||
title: 'Penyusunan dan Pembuatan SOP Direktorat Data dan Informasi',
|
||||
client: 'Kementerian Investasi / Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2025,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Perencanaan Peta Jalan Direktorat Data dan Informasi TA 2024',
|
||||
client: 'Kementerian Investasi / Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2024,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Modul Pelayanan Metrologi Legal Submodul Verifikasi (Sistem Informasi Ketertelusuran Standar (SIKS))',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2024,
|
||||
},
|
||||
{
|
||||
title: 'Penyediaan Data Harga dan Pasokan Cabe dan Bawang di Pasar Induk Wilayah Barat',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2024,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pemeliharaan Sistem Pelaporan Harga (SP2KP), Pusat Data dan Sistem Informasi',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2023,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Penyediaan Data Harga dan Pasokan Cabe dan Bawang di Pasar Induk Wilayah Barat',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2023,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pembangunan Aplikasi Sertifikasi Prasarana Perkeretaapian Dengan Memanfaatkan Teknologi Informasi',
|
||||
client: 'Kementerian Perhubungan',
|
||||
year: 2022,
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Aplikasi LDH',
|
||||
client: 'Badan Informasi Geospasial (BIG)',
|
||||
year: 2022,
|
||||
program: 'erp',
|
||||
scope: 'OpenERP Community: manajemen dokumen dan custom development',
|
||||
},
|
||||
{
|
||||
title: 'Perawatan Sistem Pelaporan Harga',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2022,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Aplikasi Sistem Informasi Ketertelusuran Standar',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2021,
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Modul Master Data Aplikasi SIREBEKA (Sistem Informasi Remunerasi Berbasis Kinerja)',
|
||||
client: 'Kementerian Perhubungan',
|
||||
year: 2021,
|
||||
},
|
||||
{
|
||||
title: 'Pengelolaan Sistem Pelaporan Harga',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2020,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pengadaan Metrologi Aplikasi Mobile: Pendataan dan Pemetaan Kondisi UTTP dan BDKT dalam Kerangka Pengawasan Kemetrologian',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2020,
|
||||
},
|
||||
{
|
||||
title: 'Penyediaan Data Harga dan Pasokan Cabe dan Bawang di Pasar Induk Wilayah Barat',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2020,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Penyediaan Data Harga dan Pasokan Cabe dan Bawang di Pasar Induk Wilayah Timur',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2020,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Perawatan Sistem Pelaporan Harga',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2020,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Perancangan Antar Muka Sistem Informasi Ketertelusuran Standar',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2019,
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan dan Pemeliharaan Portal NSWI TA 2019',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2019,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Aplikasi Website Intranet',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2018,
|
||||
},
|
||||
{
|
||||
title: 'Pemantauan Harga Bapok 34 Ibukota Provinsi pada Sabtu atau Minggu, Libur Nasional dan HBKN, Pasar Kab/Kota, Daerah TTT dan Pasar Ritel Modern Tahun 2018',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2018,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Business Intelligence (BI) TA 2018',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2018,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Dashboard Produk Wisata MICE',
|
||||
client: 'Kementerian Pariwisata',
|
||||
year: 2017,
|
||||
},
|
||||
{
|
||||
title: 'Pembuatan Sistem Informasi Manajemen Harga dan Pasokan',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2017,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Penerapan Model Pembangunan dan Revitalisasi Pasar Rakyat Dengan Pendekatan Teknologi Informasi Berbasis Mobile',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2017,
|
||||
},
|
||||
{
|
||||
title: 'Penyusunan Pemutakhiran (Updating) Cetak Biru Pengembangan Sistem Pelayanan Informasi dan Perizinan',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2017,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Pemantauan Stok dan Pasokan Barang Kebutuhan Pokok 100 Titik di Pasar Rakyat (Tradisional), Pasar Induk dan Sentra Produksi',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2017,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Verifikasi Pelaporan Harga Barang Pokok pada SP2KP',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2016,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Program Aplikasi Harga Kabupaten Kota',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2016,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Updating Program Penilaian Pasar',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2016,
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Sistem Aplikasi Jaringan Informasi Dokumentasi Hukum',
|
||||
client: 'Badan Informasi Geospasial (BIG)',
|
||||
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)',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2016,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pekerjaan Pengembangan Program Aplikasi Harga Kabupaten Kota',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2016,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pembuatan Software pada Kegiatan Penguatan Regional Climate Change Center',
|
||||
client: 'Badan Meteorologi Klimatologi dan Geofisika (BMKG)',
|
||||
year: 2015,
|
||||
},
|
||||
{
|
||||
title: 'Kajian Tata Kelola Teknologi Informasi BKPM TA 2014',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2014,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Sistem Informasi Monitoring Updating Harga dan Pasokan Bawang Merah',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2014,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pemetaan Indikasi dan Variabel Penentu Kenaikan Harga Bahan Pokok (Komoditas Cabe Merah, Bawang Merah dan Beras)',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2014,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pembangunan Sistem Informasi Pelayanan Dokumen Hukum',
|
||||
client: 'Badan Informasi Geospasial (BIG)',
|
||||
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)',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2013,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Pengadaan Jasa Konsultasi Pekerjaan Pembangunan Sub Sistem Bidang Ketahanan Lembaga Usaha Ekonomi',
|
||||
client: 'Kementerian Perdagangan',
|
||||
year: 2012,
|
||||
},
|
||||
{
|
||||
title: 'Pendampingan Helpdesk Implementasi Sistem Pelayanan Informasi dan Perizinan Investasi Secara Elektronik (SPIPISE)',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2012,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Pembangunan Aplikasi Jaringan Dokumentasi dan Informasi Hukum',
|
||||
client: 'Badan Informasi Geospasial (BIG)',
|
||||
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',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2010,
|
||||
program: 'investment',
|
||||
},
|
||||
{
|
||||
title: 'Pembuatan Database Eksportir Importir, Perusahaan, Asosiasi dan Pelaku Industri Kreatif serta Lembaga Pendidikan Formal/Non Formal',
|
||||
client: 'Departemen Perdagangan Republik Indonesia',
|
||||
year: 2009,
|
||||
},
|
||||
{
|
||||
title: 'Pembangunan Sistem Informasi Tracking Promosi Investasi Tahun Anggaran 2006',
|
||||
client: 'Badan Koordinasi Penanaman Modal (BKPM)',
|
||||
year: 2006,
|
||||
program: 'investment',
|
||||
},
|
||||
];
|
||||
|
||||
const privateSector: Omit<Project, 'sector'>[] = [
|
||||
{
|
||||
title: 'Implementasi Odoo ERP',
|
||||
client: 'Marawah Beach Club',
|
||||
year: 2022,
|
||||
program: 'erp',
|
||||
scope: 'Odoo Enterprise: POS, event, pembelian, penjualan, website, dan custom development',
|
||||
},
|
||||
{
|
||||
title: 'Enhancement Manajemen Sistem',
|
||||
client: 'PT Cipta Kridatama',
|
||||
year: 2022,
|
||||
},
|
||||
{
|
||||
title: 'Implementasi OpenERP Manufacturing System',
|
||||
client: 'CV Mujur Jaya Abadi',
|
||||
year: 2015,
|
||||
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)',
|
||||
client: 'PT LAPI ITB (Bapokstra)',
|
||||
year: 2013,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Aplikasi GIS Pelaporan Online Harga',
|
||||
client: 'PT DKN',
|
||||
year: 2011,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Portal Ekonomi Kreatif Indonesia (www.indonesiakreatif.net)',
|
||||
client: 'CV Multi Sarana Putra',
|
||||
year: 2010,
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Cetak Biru Teknologi Informasi Pusat Pengendalian Online Harga dan Stok',
|
||||
client: 'PT Pranala Nitisala',
|
||||
year: 2010,
|
||||
program: 'price-monitoring',
|
||||
},
|
||||
{
|
||||
title: 'Pembuatan Sistem Informasi Monitoring Penerimaan dan Pengeluaran BBM di Setiap Fasilitas Rantai Pasok BBM',
|
||||
client: 'KSO LAPI – Pranala',
|
||||
year: 2008,
|
||||
},
|
||||
{
|
||||
title: 'Validasi dan Koreksi Data Akunting',
|
||||
client: 'PT Lautan Berlian Utama Motor',
|
||||
year: 2008,
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan, Pemutakhiran dan Pemeliharaan Website Tahun Anggaran 2007',
|
||||
client: 'CV Multi Sarana Putra',
|
||||
year: 2007,
|
||||
},
|
||||
{
|
||||
title: 'Pembuatan Compact Disc (CD) Profil Wilayah, Sektor dan Komoditi',
|
||||
client: 'PT Qualita Prima Pariwara',
|
||||
year: 2007,
|
||||
},
|
||||
{
|
||||
title: 'Pengembangan Aplikasi Titis Sampurna Accounting Information System',
|
||||
client: 'PT Titis Sampurna',
|
||||
year: 2006,
|
||||
program: 'erp',
|
||||
},
|
||||
{
|
||||
title: 'Jasa Konsultasi Pengembangan Sistem Informasi Eksekutif Keuangan',
|
||||
client: 'CV Multi Sarana Putra',
|
||||
year: 2006,
|
||||
},
|
||||
{
|
||||
title: 'Desain Sistem Informasi Museum Bank Indonesia',
|
||||
client: 'PT Global Media Inline',
|
||||
year: 2006,
|
||||
},
|
||||
];
|
||||
|
||||
const soe: Omit<Project, 'sector'>[] = [
|
||||
{
|
||||
title: 'Pembangunan Sistem Aplikasi',
|
||||
client: 'PT Sucofindo (Persero)',
|
||||
year: 2015,
|
||||
},
|
||||
{
|
||||
title: 'Jasa Pemeliharaan Sistem Merpati Operation System Infrastructure (MOSI), Mobile Flight Log (MFL), Schedule Messaging System (SMS)',
|
||||
client: 'PT Merpati Nusantara Airlines',
|
||||
year: 2006,
|
||||
},
|
||||
];
|
||||
|
||||
const newestFirst = (a: Project, b: Project) => b.year - a.year;
|
||||
|
||||
export const projects: Project[] = [
|
||||
...government.map((p) => ({ ...p, sector: 'government' as const })),
|
||||
...privateSector.map((p) => ({ ...p, sector: 'private' as const })),
|
||||
...soe.map((p) => ({ ...p, sector: 'soe' as const })),
|
||||
].sort(newestFirst);
|
||||
|
||||
/** Different names used over the years for the same institution. */
|
||||
const clientAliases: Record<string, string> = {
|
||||
@@ -392,11 +17,8 @@ const clientAliases: Record<string, string> = {
|
||||
const clientName = (project: Project) =>
|
||||
clientAliases[project.client] ?? project.client;
|
||||
|
||||
/** Number of distinct clients across all projects. */
|
||||
export const clientCount = new Set(projects.map(clientName)).size;
|
||||
|
||||
/** Distinct clients, most frequent first. */
|
||||
const rankClients = (items: Project[]) => {
|
||||
export const rankClients = (items: Project[]) => {
|
||||
const counts = new Map<string, number>();
|
||||
|
||||
items.forEach((project) => {
|
||||
@@ -409,24 +31,64 @@ const rankClients = (items: Project[]) => {
|
||||
.map(([name]) => name);
|
||||
};
|
||||
|
||||
export const clientsInSector = (sector: ProjectSector) =>
|
||||
rankClients(projects.filter((project) => project.sector === sector));
|
||||
export const bySector = (items: Project[], sector: ProjectSector) =>
|
||||
items.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) =>
|
||||
projects.filter((project) => project.sector === sector);
|
||||
|
||||
export const projectsInProgram = (program: ProjectProgram) =>
|
||||
projects.filter((project) => project.program === program);
|
||||
export const inProgram = (items: Project[], program: ProjectProgram) =>
|
||||
items.filter((project) => project.program === program);
|
||||
|
||||
/** e.g. "2006 – 2025", or a single year when all projects share it. */
|
||||
export const yearRange = (items: Project[]) => {
|
||||
if (items.length === 0) {
|
||||
return '–';
|
||||
}
|
||||
|
||||
const years = items.map((project) => project.year);
|
||||
const first = Math.min(...years);
|
||||
const last = Math.max(...years);
|
||||
|
||||
return first === last ? `${first}` : `${first} – ${last}`;
|
||||
};
|
||||
|
||||
/** All portfolio numbers and lists derived from one set of projects. */
|
||||
export const portfolio = (projects: Project[]) => ({
|
||||
projects,
|
||||
projectCount: projects.length,
|
||||
clientCount: rankClients(projects).length,
|
||||
projectsBySector: (sector: ProjectSector) => bySector(projects, sector),
|
||||
projectsInProgram: (program: ProjectProgram) =>
|
||||
inProgram(projects, program),
|
||||
clientsInSector: (sector: ProjectSector) =>
|
||||
rankClients(bySector(projects, sector)),
|
||||
topClients: (limit: number) => rankClients(projects).slice(0, limit),
|
||||
});
|
||||
|
||||
export type Portfolio = ReturnType<typeof portfolio>;
|
||||
|
||||
/** Fills `{projects}` and `{clients}` placeholders in content strings. */
|
||||
export const withCounts = (text: string, stats: Portfolio) =>
|
||||
text
|
||||
.replaceAll('{projects}', String(stats.projectCount))
|
||||
.replaceAll('{clients}', String(stats.clientCount));
|
||||
|
||||
/** Applies `withCounts` to every string in a content object. */
|
||||
export function fillCounts<T>(value: T, stats: Portfolio): T {
|
||||
if (typeof value === 'string') {
|
||||
return withCounts(value, stats) as T;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item: unknown) => fillCounts(item, stats)) as T;
|
||||
}
|
||||
|
||||
if (value && typeof value === 'object') {
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).map(([key, item]) => [
|
||||
key,
|
||||
fillCounts(item, stats),
|
||||
]),
|
||||
) as T;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user