Initial commit

This commit is contained in:
Porawit Dongwang
2026-09-16 23:20:08 +07:00
commit 0041668dbb
32577 changed files with 3687927 additions and 0 deletions
@@ -0,0 +1,154 @@
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0 text-gray-800">ตั้งค่า Google Sheets Sync</h1>
<a href="<?= BASE_URL ?>/settings" class="btn btn-outline-secondary shadow-sm"><i class="fa-solid fa-arrow-left me-1"></i> กลับ</a>
</div>
<div class="row">
<div class="col-lg-8">
<div class="card shadow-sm border-0 rounded-4 mb-4 overflow-hidden">
<div class="card-header bg-white py-3">
<h6 class="m-0 font-weight-bold text-success"><i class="fa-solid fa-plug me-2"></i>รายละเอียดการเชื่อมต่อ</h6>
</div>
<div class="card-body">
<form action="<?= BASE_URL ?>/settings/google-sheets/save" method="POST">
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>">
<div class="mb-3">
<label class="form-label fw-bold">รูปแบบการเชื่อมต่อ (Connection Type)</label>
<div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="connection_type" id="connAPI" value="API" <?= ($setting['connection_type'] ?? 'API') === 'API' ? 'checked' : '' ?>>
<label class="form-check-label" for="connAPI">ใช้ Google API Key (มาตรฐาน)</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="connection_type" id="connPublic" value="Public" <?= ($setting['connection_type'] ?? '') === 'Public' ? 'checked' : '' ?>>
<label class="form-check-label" for="connPublic">ดึงจากไฟล์ Public (ไม่ต้องใช้ API Key)</label>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label fw-bold">Spreadsheet ID</label>
<input type="text" class="form-control" name="spreadsheet_id" value="<?= htmlspecialchars($setting['spreadsheet_id'] ?? '') ?>" placeholder="เช่น 1BxiMVs0XRYFgwnTE...">
<div class="form-text">รหัส 44 ตัวอักษรที่อยู่ใน URL ของ Google Sheets</div>
</div>
<div class="mb-3" id="apiKeyContainer">
<label class="form-label fw-bold">Google API Key</label>
<input type="text" class="form-control" name="api_key" value="<?= htmlspecialchars($setting['api_key'] ?? '') ?>" placeholder="เช่น AIzaSyC...">
<div class="form-text">รหัส API Key จาก Google Cloud Console (จำเป็นสำหรับการดึงข้อมูลจริง)</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label fw-bold">Sheet Name</label>
<input type="text" class="form-control" name="sheet_name" value="<?= htmlspecialchars($setting['sheet_name'] ?? 'Sheet1') ?>" placeholder="เช่น Sheet1">
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Sync Range</label>
<input type="text" class="form-control" name="sync_range" value="<?= htmlspecialchars($setting['sync_range'] ?? 'A2:B') ?>" placeholder="เช่น A2:B">
</div>
</div>
<div class="mb-4">
<label class="form-label fw-bold">Column Mapping (JSON)</label>
<textarea class="form-control text-monospace" name="column_mapping" rows="4"><?= htmlspecialchars($setting['column_mapping'] ?? '{"1": "doc_number", "4": "doc_no", "5": "title", "10": "doc_date", "11": "doc_link"}') ?></textarea>
<div class="form-text">รูปแบบ JSON เพื่อแมปคอลัมน์จาก Sheet (Index 0) เข้าสู่ฐานข้อมูล</div>
</div>
<button type="submit" class="btn btn-success"><i class="fa-solid fa-save me-1"></i> บันทึกการตั้งค่า</button>
<button type="button" class="btn btn-outline-primary ms-2" id="testSyncBtn"><i class="fa-solid fa-rotate me-1"></i> ทดสอบดึงข้อมูล</button>
</form>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow-sm border-0 rounded-4 bg-success text-white overflow-hidden">
<div class="card-body p-4 text-center">
<i class="fa-solid fa-cloud-arrow-down fa-3x mb-3 opacity-75"></i>
<h5>สถานะการเชื่อมต่อ</h5>
<p class="mb-0">
<?php if(!empty($setting['last_synced_at'])): ?>
<span class="badge bg-light text-success mb-2">ทำงานปกติ</span><br>
<small>ดึงข้อมูลล่าสุด: <?= date('d/m/Y H:i', strtotime($setting['last_synced_at'])) ?></small>
<?php else: ?>
<span class="badge bg-warning text-dark mb-2">ยังไม่เคยดึงข้อมูล</span>
<?php endif; ?>
</p>
</div>
</div>
<div class="card shadow-sm border-0 rounded-4 mt-4 overflow-hidden">
<div class="card-body">
<h6 class="fw-bold"><i class="fa-solid fa-circle-info text-info me-2"></i>ข้อควรระวัง</h6>
<ul class="small text-muted ps-3 mb-0">
<li class="mb-1">ต้องแชร์ Spreadsheet ให้อ่านได้ (Anyone with the link) หรือผ่าน Service Account</li>
<li class="mb-1">วันที่ใน Google Sheets ควรใช้ Format `YYYY-MM-DD` เพื่อง่ายต่อการนำเข้า MySQL</li>
<li>หากต้องการดึงอัตโนมัติ ต้องตั้ง Cron Job เรียกใช้ API Endpoint ของระบบ</li>
</ul>
</div>
</div>
</div>
</div>
<?php
$extraScripts = '
<script>
document.addEventListener("DOMContentLoaded", function() {
const connAPI = document.getElementById("connAPI");
const connPublic = document.getElementById("connPublic");
const apiKeyContainer = document.getElementById("apiKeyContainer");
function toggleApiKey() {
if (connAPI.checked) {
apiKeyContainer.style.display = "block";
} else {
apiKeyContainer.style.display = "none";
}
}
connAPI.addEventListener("change", toggleApiKey);
connPublic.addEventListener("change", toggleApiKey);
toggleApiKey(); // Initial check
});
document.getElementById("testSyncBtn").addEventListener("click", function() {
const btn = this;
btn.disabled = true;
btn.innerHTML = \'<i class="fa-solid fa-spinner fa-spin me-1"></i> กำลังทดสอบ...\';
fetch("' . BASE_URL . '/settings/google-sheets/test", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "csrf_token=' . $csrf_token . '"
})
.then(async res => {
const text = await res.text();
try {
return JSON.parse(text);
} catch (e) {
// คืนค่า Text ดิบๆ ไปเลยเพื่อให้ User เห็นว่า Server ฟ้องว่าอะไร
throw new Error("Server ไม่ได้ตอบกลับเป็น JSON: " + text.substring(0, 100));
}
})
.then(data => {
btn.disabled = false;
btn.innerHTML = \'<i class="fa-solid fa-rotate me-1"></i> ทดสอบดึงข้อมูล\';
if (data.status === "success") {
alert("เชื่อมต่อสำเร็จ! พบข้อมูล " + data.rows + " แถว\\nตัวอย่างรายการแรก: " + JSON.stringify(data.preview));
} else {
alert("เกิดข้อผิดพลาด: " + data.message);
}
})
.catch(err => {
btn.disabled = false;
btn.innerHTML = \'<i class="fa-solid fa-rotate me-1"></i> ทดสอบดึงข้อมูล\';
alert("Error: " + err.message);
});
});
</script>
';
?>