https://docs.google.com/spreadsheets/d/1kTa9kzd1ah2D563XtigCw9Wsu1SrbXWXWBLIwJJCHgw/edit?gid=0#gid=0
Code.gs
// ===============================
// CONFIG
// ===============================
const SPREADSHEET_ID = "ISI_SPREADSHEET_ID";
const SHEET_NAME = "ISI_NAMA_SHEET";
// ===============================
// ENTRY POINT (SPA)
// ===============================
function doGet(e) {
const page = e.parameter.page || "home";
return HtmlService
.createHtmlOutput(htmlGenerate(page))
.setTitle("SPA Spreadsheet App")
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
// ===============================
// HTML GENERATOR
// ===============================
function htmlGenerate(page) {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SPA Spreadsheet</title>
<style>
body {
margin:0;
font-family: Arial, sans-serif;
background:#f4f6f9;
}
header {
background:#2c3e50;
color:white;
padding:15px;
display:flex;
justify-content:space-between;
}
nav a {
color:white;
margin-left:15px;
text-decoration:none;
}
.container {
padding:20px;
max-width:1200px;
margin:auto;
}
.card {
background:white;
padding:20px;
border-radius:10px;
box-shadow:0 4px 10px rgba(0,0,0,0.1);
}
.grid {
display:grid;
grid-template-columns: repeat(auto-fit,minmax(250px,1fr));
gap:20px;
}
table {
width:100%;
border-collapse:collapse;
}
th,td {
padding:10px;
border-bottom:1px solid #ddd;
}
th {
background:#2c3e50;
color:white;
}
.loading {
text-align:center;
padding:20px;
}
.error {
color:red;
text-align:center;
}
</style>
</head>
<body>
<header>
<div>Spreadsheet SPA</div>
<nav>
<a href="#" onclick="navigate('home')">Home</a>
<a href="#" onclick="navigate('table')">Table</a>
<a href="#" onclick="navigate('cards')">Cards</a>
</nav>
</header>
<div class="container">
<div id="app"></div>
</div>
<script>
// ===============================
// SPA ROUTER
// ===============================
function navigate(page){
history.pushState({}, "", "?page=" + page);
renderPage(page);
}
window.onpopstate = function(){
const params = new URLSearchParams(window.location.search);
const page = params.get("page") || "home";
renderPage(page);
};
// ===============================
// INITIAL LOAD
// ===============================
document.addEventListener("DOMContentLoaded", function(){
const params = new URLSearchParams(window.location.search);
const page = params.get("page") || "${page}";
renderPage(page);
});
// ===============================
// RENDER PAGE
// ===============================
function renderPage(page){
const app = document.getElementById("app");
if(page === "home"){
app.innerHTML = \`
<div class="card">
<h2>Welcome</h2>
<p>Aplikasi SPA berbasis Google Spreadsheet.</p>
</div>
\`;
}
if(page === "table"){
app.innerHTML = '<div class="loading">Loading...</div>';
loadData("table");
}
if(page === "cards"){
app.innerHTML = '<div class="loading">Loading...</div>';
loadData("cards");
}
}
// ===============================
// FETCH DATA
// ===============================
function loadData(viewType){
google.script.run
.withSuccessHandler(function(response){
if(response.status !== "success"){
showError(response.message);
return;
}
if(viewType === "table"){
renderTable(response.data);
} else {
renderCards(response.data);
}
})
.withFailureHandler(function(error){
showError(error.message);
})
.getData();
}
function showError(message){
document.getElementById("app").innerHTML =
'<div class="error">Error: '+ message +'</div>';
}
// ===============================
// TABLE VIEW
// ===============================
function renderTable(data){
if(data.length === 0){
document.getElementById("app").innerHTML = "No Data";
return;
}
const headers = Object.keys(data[0]);
let html = '<div class="card"><table><thead><tr>';
headers.forEach(h => html += '<th>'+h+'</th>');
html += '</tr></thead><tbody>';
data.forEach(row => {
html += '<tr>';
headers.forEach(h => html += '<td>'+row[h]+'</td>');
html += '</tr>';
});
html += '</tbody></table></div>';
document.getElementById("app").innerHTML = html;
}
// ===============================
// CARD VIEW
// ===============================
function renderCards(data){
let html = '<div class="grid">';
data.forEach(row => {
html += '<div class="card">';
for(let key in row){
html += '<p><strong>'+key+':</strong> '+row[key]+'</p>';
}
html += '</div>';
});
html += '</div>';
document.getElementById("app").innerHTML = html;
}
</script>
</body>
</html>
`;
}
// ===============================
// API METHOD
// ===============================
function getData(){
try{
const sheet = SpreadsheetApp
.openById(SPREADSHEET_ID)
.getSheetByName(SHEET_NAME);
const values = sheet.getDataRange().getValues();
const headers = values.shift();
const data = values.map(row => {
let obj = {};
headers.forEach((h,i)=> obj[h] = row[i]);
return obj;
});
return { status:"success", data:data };
} catch(err){
return { status:"error", message: err.toString() };
}
}

Tidak ada komentar:
Posting Komentar