Tutorial Praktis
Tutorial HR & Payroll Service Account
Bangun aplikasi manajemen HR enterprise yang aman dan privat menggunakan kredensial Service Account.
Pelajari cara mengakses Google Sheets privat yang tidak dibagikan publik secara aman untuk catatan HR dan penggajian enterprise.
1. Setup Kredensial Service Account
- Di GCP Console, buat sebuah Service Account (misal
hr-bot@project.iam.gserviceaccount.com). - Buat dan unduh File Kunci JSON.
- Buka Google Sheet privat kamu -> Bagikan dengan
hr-bot@project.iam.gserviceaccount.comsebagai Editor. - Konfigurasikan file
.env:
.env
GSHEET_SPREADSHEET_ID=spreadsheet-id-privat-kamu
GSHEET_CLIENT_EMAIL=hr-bot@project.iam.gserviceaccount.com
GSHEET_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC...\n-----END PRIVATE KEY-----\n"
2. Implementasi Komponen Vue (Read & Write)
pages/hr/employees.vue
<script setup lang="ts">
interface Employee {
empId: string
name: string
department: string
salary: string
}
// 1. Read Data Secara Aman dari Server-Side
const { data: employees, pending, refresh } = await useGSheetAsObject<Employee[]>('A1:D50', {
sheet: 'payroll'
})
// 2. Operasi Write Privat
const { append } = useGSheetWrite({ sheet: 'payroll' })
const name = ref('')
const department = ref('Engineering')
const salary = ref('85000')
const addEmployee = async () => {
if (!name.value) return
await append('A1:D1', [
[`EMP-${Date.now()}`, name.value, department.value, salary.value]
])
name.value = ''
await refresh()
}
</script>
<template>
<div class="hr-portal">
<h1>Portal Enterprise HR & Payroll</h1>
<form @submit.prevent="addEmployee">
<input
v-model="name"
placeholder="Nama Karyawan"
required
>
<select v-model="department">
<option value="Engineering">
Engineering
</option>
<option value="Marketing">
Marketing
</option>
</select>
<input
v-model="salary"
placeholder="Gaji"
required
>
<button type="submit">
Tambah Karyawan
</button>
</form>
<div v-if="pending">
Mengkautentikasi JWT & memuat data privat...
</div>
<table v-else>
<thead>
<tr>
<th>ID</th>
<th>Nama</th>
<th>Departemen</th>
<th>Gaji</th>
</tr>
</thead>
<tbody>
<tr
v-for="emp in employees"
:key="emp.empId"
>
<td>{{ emp.empId }}</td>
<td>{{ emp.name }}</td>
<td>{{ emp.department }}</td>
<td>${{ emp.salary }}</td>
</tr>
</tbody>
</table>
</div>
</template>