Fix dynamic API base path for server deployment
This commit is contained in:
+27
-18
@@ -5,10 +5,12 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>TPU Survey - Admin Dashboard</title>
|
||||
<meta name="description" content="แดชบอร์ดผู้ดูแลระบบ สำหรับจัดการแบบสอบถามและผู้ใช้ คณะนวัตกรรมดิจิทัลเทคโนโลยี มหาวิทยาลัยตาปี">
|
||||
<meta name="description"
|
||||
content="แดชบอร์ดผู้ดูแลระบบ สำหรับจัดการแบบสอบถามและผู้ใช้ คณะนวัตกรรมดิจิทัลเทคโนโลยี มหาวิทยาลัยตาปี">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@300;400;500;600;700;800;900&display=swap"
|
||||
rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
@@ -37,11 +39,10 @@
|
||||
<!-- Sidebar -->
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<img src="pic/logo.png" alt="TPU Logo" class="sidebar-logo-img"
|
||||
onerror="this.style.display='none'">
|
||||
<img src="pic/logo.png" alt="TPU Logo" class="sidebar-logo-img" onerror="this.style.display='none'">
|
||||
<div>
|
||||
<h2 class="text-white font-bold text-sm leading-tight">คณะนวัตกรรมดิจิทัลเทคโนโลยี</h2>
|
||||
<span class="text-yellow-300 text-xs font-medium">มหาวิทยาลัยตาปี</span>
|
||||
|
||||
<span class="text-white font-bold text-sm leading-tight">มหาวิทยาลัยตาปี</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -157,8 +158,8 @@
|
||||
<div class="status-chart-row">
|
||||
<div class="status-chart-label">📝 ร่าง</div>
|
||||
<div class="status-chart-bar-track">
|
||||
<div class="status-chart-bar-fill draft" id="chartDraft"
|
||||
style="width: 0%"></div>
|
||||
<div class="status-chart-bar-fill draft" id="chartDraft" style="width: 0%">
|
||||
</div>
|
||||
</div>
|
||||
<div class="status-chart-count" id="chartDraftCount">0</div>
|
||||
</div>
|
||||
@@ -233,9 +234,8 @@
|
||||
<button class="filter-tab" data-filter="active"
|
||||
onclick="filterSurveys('active', this)">🟢 เปิด <span class="tab-count"
|
||||
id="countActive">0</span></button>
|
||||
<button class="filter-tab" data-filter="draft"
|
||||
onclick="filterSurveys('draft', this)">📝 ร่าง <span class="tab-count"
|
||||
id="countDraft">0</span></button>
|
||||
<button class="filter-tab" data-filter="draft" onclick="filterSurveys('draft', this)">📝
|
||||
ร่าง <span class="tab-count" id="countDraft">0</span></button>
|
||||
<button class="filter-tab" data-filter="closed"
|
||||
onclick="filterSurveys('closed', this)">🔴 ปิด <span class="tab-count"
|
||||
id="countClosed">0</span></button>
|
||||
@@ -247,8 +247,11 @@
|
||||
<input type="text" id="surveySearchInput" placeholder="ค้นหาแบบสอบถาม..."
|
||||
oninput="filterSurveysBySearch()">
|
||||
</div>
|
||||
<button class="btn btn-primary btn-sm" onclick="showCreateSurveyModal()">➕ สร้างแบบสอบถาม</button>
|
||||
<button class="btn btn-primary btn-sm" style="background-color:#16a34a;border-color:#16a34a;" onclick="showImportGoogleFormModal()">📥 นำเข้าจาก Google Forms</button>
|
||||
<button class="btn btn-primary btn-sm" onclick="showCreateSurveyModal()">➕
|
||||
สร้างแบบสอบถาม</button>
|
||||
<button class="btn btn-primary btn-sm"
|
||||
style="background-color:#16a34a;border-color:#16a34a;"
|
||||
onclick="showImportGoogleFormModal()">📥 นำเข้าจาก Google Forms</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -277,7 +280,9 @@
|
||||
<!-- Profile Card -->
|
||||
<div class="card" style="text-align:center;">
|
||||
<div class="card-body" style="padding:32px 24px;">
|
||||
<div id="profileAvatar" style="width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,#1e3a8a,#2563eb);color:#fff;font-size:36px;font-weight:700;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">A</div>
|
||||
<div id="profileAvatar"
|
||||
style="width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,#1e3a8a,#2563eb);color:#fff;font-size:36px;font-weight:700;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">
|
||||
A</div>
|
||||
<h3 id="profileDisplayName" style="margin-bottom:4px;">—</h3>
|
||||
<span class="text-muted text-sm" id="profileDisplayRole">ผู้ดูแลระบบ</span>
|
||||
<div style="margin-top:12px;">
|
||||
@@ -285,7 +290,8 @@
|
||||
</div>
|
||||
<hr style="border-color:var(--border-color);margin:20px 0;">
|
||||
<div class="text-sm text-muted">🆔 รหัสบุคลากร</div>
|
||||
<div style="font-size:18px;font-weight:600;margin-top:4px;" id="profilePersonnelCode">—</div>
|
||||
<div style="font-size:18px;font-weight:600;margin-top:4px;" id="profilePersonnelCode">—
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -300,7 +306,8 @@
|
||||
<label class="form-label">รหัสบุคลากร</label>
|
||||
<input type="text" class="form-input" id="profileCode" disabled
|
||||
style="background:var(--bg-secondary);cursor:not-allowed;opacity:0.7;">
|
||||
<small class="text-muted" style="display:block;margin-top:4px;">🔒 ไม่สามารถแก้ไขได้ — ติดต่อผู้ดูแลระบบ</small>
|
||||
<small class="text-muted" style="display:block;margin-top:4px;">🔒
|
||||
ไม่สามารถแก้ไขได้ — ติดต่อผู้ดูแลระบบ</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">ชื่อ-นามสกุล *</label>
|
||||
@@ -335,8 +342,10 @@
|
||||
placeholder="พิมพ์รหัสผ่านใหม่อีกครั้ง">
|
||||
</div>
|
||||
<div style="display:flex;gap:12px;justify-content:flex-end;margin-top:24px;">
|
||||
<button type="button" class="btn btn-secondary" onclick="loadProfile()">🔄 รีเซ็ต</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveProfile()">💾 บันทึกข้อมูล</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="loadProfile()">🔄
|
||||
รีเซ็ต</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveProfile()">💾
|
||||
บันทึกข้อมูล</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
+9
-6
@@ -5,10 +5,11 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>TPU Survey - ระบบประเมินความพึงพอใจ</title>
|
||||
<meta name="description" content="ระบบแบบสอบถามประเมินผลโครงการ คณะนวัตกรรมดิจิทัลเทคโนโลยี มหาวิทยาลัยตาปี">
|
||||
<meta name="description" content="ระบบแบบสอบถามประเมินผล มหาวิทยาลัยตาปี">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@300;400;500;600;700;800;900&display=swap"
|
||||
rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
@@ -33,13 +34,14 @@
|
||||
<div class="login-page">
|
||||
<div class="login-card glass-card relative overflow-hidden">
|
||||
<!-- Accent Gold Line -->
|
||||
<div class="h-1.5 bg-gradient-to-r from-yellow-300 via-yellow-400 to-yellow-500 absolute top-0 left-0 right-0"></div>
|
||||
<div
|
||||
class="h-1.5 bg-gradient-to-r from-yellow-300 via-yellow-400 to-yellow-500 absolute top-0 left-0 right-0">
|
||||
</div>
|
||||
|
||||
<div class="login-logo">
|
||||
<img src="pic/logo.png" alt="TPU Logo" class="h-28 w-auto mx-auto mb-4 drop-shadow-md">
|
||||
<h1 style="color: #1e3a8a; font-size: 2rem; font-weight: 800; margin-bottom: 4px;">TPU Survey</h1>
|
||||
<p class="text-blue-900 font-bold text-sm">คณะนวัตกรรมดิจิทัลเทคโนโลยี</p>
|
||||
<p class="text-gray-500 text-xs mt-0.5">มหาวิทยาลัยตาปี (Tapi University)</p>
|
||||
<p class="text-gray-500 text-xs mt-0.5">มหาวิทยาลัยตาปี (Tapee University)</p>
|
||||
</div>
|
||||
|
||||
<form id="loginForm" onsubmit="handleLogin(event)">
|
||||
@@ -60,7 +62,8 @@
|
||||
|
||||
<div id="loginError" class="text-danger text-sm mb-16" style="display:none;"></div>
|
||||
|
||||
<button type="submit" id="loginBtn" class="btn btn-primary btn-block btn-lg shadow-lg hover:shadow-xl transition-all">
|
||||
<button type="submit" id="loginBtn"
|
||||
class="btn btn-primary btn-block btn-lg shadow-lg hover:shadow-xl transition-all">
|
||||
<i class="fas fa-sign-in-alt mr-2"></i> เข้าสู่ระบบ
|
||||
</button>
|
||||
</form>
|
||||
|
||||
+2
-1
@@ -798,7 +798,8 @@ async function changeStatus(id, status) {
|
||||
async function generateLink(id) {
|
||||
try {
|
||||
const data = await API.post('surveys.php?action=generateLink', { id });
|
||||
const fullUrl = data.full_url || `${window.location.origin}/survey/respond.php?link=${data.unique_link}`;
|
||||
const basePath = window.location.pathname.includes('/survey') ? '/survey' : '';
|
||||
const fullUrl = data.full_url || `${window.location.origin}${basePath}/respond.php?link=${data.unique_link}`;
|
||||
|
||||
// Find survey title
|
||||
const survey = surveysList.find(s => s.id == id);
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
* API communication, Auth state, Toast notifications, Theme
|
||||
*/
|
||||
|
||||
const getAppBasePath = () => {
|
||||
return window.location.pathname.includes('/survey') ? '/survey' : '';
|
||||
};
|
||||
|
||||
const API = {
|
||||
base: '/survey/api',
|
||||
base: `${getAppBasePath()}/api`,
|
||||
|
||||
async request(endpoint, options = {}) {
|
||||
const url = `${this.base}/${endpoint}`;
|
||||
@@ -66,7 +70,7 @@ const Auth = {
|
||||
async logout() {
|
||||
await API.post('auth.php?action=logout', {});
|
||||
this.user = null;
|
||||
window.location.href = '/survey/index.html';
|
||||
window.location.href = `${getAppBasePath()}/index.html`;
|
||||
},
|
||||
|
||||
isAdmin() { return this.user?.role === 'admin'; },
|
||||
|
||||
+4
-3
@@ -76,7 +76,7 @@ function renderEditor() {
|
||||
<input type="hidden" id="edit-survey-cert-template-path" value="${escapeHtml(currentSurvey.certificate_template || '')}">
|
||||
|
||||
<div id="cert-preview-wrapper" style="margin-top:12px; display:${currentSurvey.certificate_template ? 'block' : 'none'};">
|
||||
<img id="cert-template-preview" src="${currentSurvey.certificate_template ? '/survey/' + currentSurvey.certificate_template : ''}" style="max-height:140px; width:auto; border-radius:8px; border:1px solid var(--border-color); box-shadow:var(--shadow-sm);">
|
||||
<img id="cert-template-preview" src="${currentSurvey.certificate_template ? (window.location.pathname.includes('/survey') ? '/survey/' : '/') + currentSurvey.certificate_template : ''}" style="max-height:140px; width:auto; border-radius:8px; border:1px solid var(--border-color); box-shadow:var(--shadow-sm);">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -486,7 +486,8 @@ async function uploadCertTemplate(input) {
|
||||
formData.append('template_image', file);
|
||||
|
||||
try {
|
||||
const res = await fetch('/survey/api/surveys.php?action=uploadTemplate', {
|
||||
const basePath = window.location.pathname.includes('/survey') ? '/survey' : '';
|
||||
const res = await fetch(`${basePath}/api/surveys.php?action=uploadTemplate`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
@@ -501,7 +502,7 @@ async function uploadCertTemplate(input) {
|
||||
// Update preview
|
||||
const previewImg = document.getElementById('cert-template-preview');
|
||||
const previewWrapper = document.getElementById('cert-preview-wrapper');
|
||||
previewImg.src = '/survey/' + data.template_path;
|
||||
previewImg.src = (basePath ? `${basePath}/` : '/') + data.template_path;
|
||||
previewWrapper.style.display = 'block';
|
||||
|
||||
// Add dynamic delete button if it doesn't exist
|
||||
|
||||
+4
-2
@@ -15,7 +15,8 @@ async function initSurvey() {
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await fetch(`/survey/api/surveys.php?action=getByLink&link=${encodeURIComponent(link)}`).then(r => r.json());
|
||||
const basePath = window.location.pathname.includes('/survey') ? '/survey' : '';
|
||||
const data = await fetch(`${basePath}/api/surveys.php?action=getByLink&link=${encodeURIComponent(link)}`).then(r => r.json());
|
||||
|
||||
if (data.error) {
|
||||
showError(data.error);
|
||||
@@ -249,7 +250,8 @@ async function submitSurveyResponse(e) {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
try {
|
||||
const res = await fetch('/survey/api/responses.php?action=submit', {
|
||||
const basePath = window.location.pathname.includes('/survey') ? '/survey' : '';
|
||||
const res = await fetch(`${basePath}/api/responses.php?action=submit`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
|
||||
+2
-1
@@ -374,7 +374,8 @@ async function teacherDuplicateSurvey(id) {
|
||||
async function teacherGenerateLink(id) {
|
||||
try {
|
||||
const data = await API.post('surveys.php?action=generateLink', { id });
|
||||
const fullUrl = data.full_url || `${window.location.origin}/survey/respond.php?link=${data.unique_link}`;
|
||||
const basePath = window.location.pathname.includes('/survey') ? '/survey' : '';
|
||||
const fullUrl = data.full_url || `${window.location.origin}${basePath}/respond.php?link=${data.unique_link}`;
|
||||
|
||||
// Find survey title
|
||||
const survey = teacherSurveys.find(s => s.id == id);
|
||||
|
||||
Executable
+175
@@ -0,0 +1,175 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# Automated Server Setup Script for TPU Survey (survey.tapee.ac.th)
|
||||
# Compatible with Ubuntu 20.04 / 22.04 / 24.04 and Debian 11 / 12
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration Variables
|
||||
DOMAIN="survey.tapee.ac.th"
|
||||
WEB_ROOT="/var/www/survey"
|
||||
DB_NAME="tpu_survey_v2"
|
||||
DB_USER="survey_user"
|
||||
DB_PASS="SurveyTPU2026!Secure" # Change this if needed
|
||||
GIT_REPO="https://git.tapee.ac.th/pongpon/survey.git"
|
||||
|
||||
echo "=========================================================="
|
||||
echo " Starting Setup for ${DOMAIN} on VM 110"
|
||||
echo "=========================================================="
|
||||
|
||||
# 1. Update system packages
|
||||
echo "[1/6] Updating system packages..."
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -y && apt-get upgrade -y
|
||||
|
||||
# 2. Install Web Server, PHP, and MariaDB
|
||||
echo "[2/6] Installing Apache, PHP, MariaDB, and utilities..."
|
||||
apt-get install -y \
|
||||
apache2 \
|
||||
mariadb-server \
|
||||
mariadb-client \
|
||||
git \
|
||||
curl \
|
||||
unzip \
|
||||
certbot \
|
||||
python3-certbot-apache \
|
||||
php \
|
||||
php-cli \
|
||||
php-fpm \
|
||||
php-mysql \
|
||||
php-mbstring \
|
||||
php-xml \
|
||||
php-curl \
|
||||
php-gd \
|
||||
php-zip \
|
||||
php-intl \
|
||||
libapache2-mod-php
|
||||
|
||||
# Enable Apache Modules
|
||||
a2enmod rewrite ssl headers
|
||||
|
||||
# 3. Setup MariaDB Database
|
||||
echo "[3/6] Configuring Database (${DB_NAME})..."
|
||||
systemctl start mariadb
|
||||
systemctl enable mariadb
|
||||
|
||||
mysql -u root <<EOF
|
||||
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
|
||||
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
echo "Database and User created successfully."
|
||||
|
||||
# 4. Deploy Project Source Code
|
||||
echo "[4/6] Setting up project files at ${WEB_ROOT}..."
|
||||
if [ -d "${WEB_ROOT}/.git" ]; then
|
||||
echo "Updating existing repository..."
|
||||
cd "${WEB_ROOT}"
|
||||
git pull origin main || true
|
||||
else
|
||||
mkdir -p "${WEB_ROOT}"
|
||||
if [ -f "./tpu_survey_v2.sql" ]; then
|
||||
echo "Copying local files to ${WEB_ROOT}..."
|
||||
cp -r ./* "${WEB_ROOT}/"
|
||||
else
|
||||
echo "Cloning from Git repository..."
|
||||
git clone "${GIT_REPO}" "${WEB_ROOT}" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Import Database Schema if SQL file exists
|
||||
if [ -f "${WEB_ROOT}/tpu_survey_v2.sql" ]; then
|
||||
echo "Importing database schema from tpu_survey_v2.sql..."
|
||||
mysql -u root "${DB_NAME}" < "${WEB_ROOT}/tpu_survey_v2.sql" || echo "Note: Initial import completed or tables exist."
|
||||
fi
|
||||
|
||||
# Update config/database.php with the server credentials
|
||||
cat <<EOF > "${WEB_ROOT}/config/database.php"
|
||||
<?php
|
||||
/**
|
||||
* Database Configuration
|
||||
* TPU Survey System
|
||||
*/
|
||||
|
||||
define('DB_HOST', 'localhost');
|
||||
define('DB_NAME', '${DB_NAME}');
|
||||
define('DB_USER', '${DB_USER}');
|
||||
define('DB_PASS', '${DB_PASS}');
|
||||
define('DB_CHARSET', 'utf8mb4');
|
||||
|
||||
function getDB() {
|
||||
static \$pdo = null;
|
||||
if (\$pdo === null) {
|
||||
try {
|
||||
\$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
|
||||
\$pdo = new PDO(\$dsn, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false
|
||||
]);
|
||||
} catch (PDOException \$e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Database connection failed: ' . \$e->getMessage()]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
return \$pdo;
|
||||
}
|
||||
|
||||
function jsonResponse(\$data, \$code = 200) {
|
||||
http_response_code(\$code);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode(\$data, JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
function getInput() {
|
||||
\$json = file_get_contents('php://input');
|
||||
return json_decode(\$json, true) ?: [];
|
||||
}
|
||||
EOF
|
||||
|
||||
# Set proper permissions
|
||||
mkdir -p "${WEB_ROOT}/uploads" "${WEB_ROOT}/temp_certificates"
|
||||
chown -R www-data:www-data "${WEB_ROOT}"
|
||||
chmod -R 755 "${WEB_ROOT}"
|
||||
chmod -R 775 "${WEB_ROOT}/uploads" "${WEB_ROOT}/temp_certificates"
|
||||
|
||||
# 5. Configure Apache VirtualHost
|
||||
echo "[5/6] Creating Apache VirtualHost for ${DOMAIN}..."
|
||||
cat <<EOF > /etc/apache2/sites-available/${DOMAIN}.conf
|
||||
<VirtualHost *:80>
|
||||
ServerName ${DOMAIN}
|
||||
ServerAlias www.${DOMAIN}
|
||||
DocumentRoot ${WEB_ROOT}
|
||||
|
||||
<Directory ${WEB_ROOT}>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}_error.log
|
||||
CustomLog \${APACHE_LOG_DIR}/${DOMAIN}_access.log combined
|
||||
</VirtualHost>
|
||||
EOF
|
||||
|
||||
a2dissite 000-default.conf || true
|
||||
a2ensite ${DOMAIN}.conf
|
||||
systemctl restart apache2
|
||||
|
||||
# 6. Summary & SSL Instructions
|
||||
echo "=========================================================="
|
||||
echo " SETUP COMPLETED SUCCESSFULLY!"
|
||||
echo "=========================================================="
|
||||
echo "1. Web Root: ${WEB_ROOT}"
|
||||
echo "2. Database Name: ${DB_NAME}"
|
||||
echo "3. Database User: ${DB_USER}"
|
||||
echo "4. VirtualHost: http://${DOMAIN}"
|
||||
echo ""
|
||||
echo "To enable HTTPS (SSL Certificate via Let's Encrypt), run:"
|
||||
echo " certbot --apache -d ${DOMAIN}"
|
||||
echo "=========================================================="
|
||||
+27
-13
@@ -5,10 +5,12 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>TPU Survey - อาจารย์/เจ้าของโครงการ</title>
|
||||
<meta name="description" content="หน้าจัดการแบบสอบถามสำหรับอาจารย์และเจ้าของโครงการ คณะนวัตกรรมดิจิทัลเทคโนโลยี มหาวิทยาลัยตาปี">
|
||||
<meta name="description"
|
||||
content="หน้าจัดการแบบสอบถามสำหรับอาจารย์และเจ้าของโครงการ คณะนวัตกรรมดิจิทัลเทคโนโลยี มหาวิทยาลัยตาปี">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@300;400;500;600;700;800;900&display=swap"
|
||||
rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
@@ -37,8 +39,8 @@
|
||||
<div class="sidebar-header">
|
||||
<img src="pic/logo.png" alt="TPU Logo" class="sidebar-logo-img">
|
||||
<div>
|
||||
<h2 class="text-white font-bold text-sm leading-tight">คณะนวัตกรรมดิจิทัลเทคโนโลยี</h2>
|
||||
<small class="text-yellow-300 font-medium">มหาวิทยาลัยตาปี</small>
|
||||
|
||||
<span class="text-white font-bold text-sm leading-tight">มหาวิทยาลัยตาปี</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -83,14 +85,20 @@
|
||||
<div id="view-mySurveys" class="view-section space-y-4">
|
||||
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 mb-4">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-blue-900"><i class="fas fa-tasks mr-2 text-yellow-500"></i>แบบสอบถามของฉัน</h2>
|
||||
<p class="text-xs text-gray-500 font-medium">จัดการและตรวจสอบแบบสอบถามประเมินผลโครงการในระบบ</p>
|
||||
<h2 class="text-xl font-bold text-blue-900"><i
|
||||
class="fas fa-tasks mr-2 text-yellow-500"></i>แบบสอบถามของฉัน</h2>
|
||||
<p class="text-xs text-gray-500 font-medium">จัดการและตรวจสอบแบบสอบถามประเมินผลโครงการในระบบ
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button class="btn-yellow px-4 py-2 rounded text-xs font-bold shadow-sm flex items-center gap-1.5 transition-all" onclick="showTeacherCreateModal()">
|
||||
<button
|
||||
class="btn-yellow px-4 py-2 rounded text-xs font-bold shadow-sm flex items-center gap-1.5 transition-all"
|
||||
onclick="showTeacherCreateModal()">
|
||||
<i class="fas fa-plus"></i> สร้างแบบสอบถาม
|
||||
</button>
|
||||
<button class="bg-green-600 hover:bg-green-700 text-white border border-black px-4 py-2 rounded text-xs font-bold shadow-sm flex items-center gap-1.5 transition-all" onclick="showImportGoogleFormModal()">
|
||||
<button
|
||||
class="bg-green-600 hover:bg-green-700 text-white border border-black px-4 py-2 rounded text-xs font-bold shadow-sm flex items-center gap-1.5 transition-all"
|
||||
onclick="showImportGoogleFormModal()">
|
||||
<i class="fas fa-file-import"></i> นำเข้าจาก Google Forms
|
||||
</button>
|
||||
</div>
|
||||
@@ -116,7 +124,9 @@
|
||||
<!-- Profile Card -->
|
||||
<div class="card" style="text-align:center;">
|
||||
<div class="card-body" style="padding:32px 24px;">
|
||||
<div id="profileAvatar" style="width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,#e8a838,#f0c040);color:#fff;font-size:36px;font-weight:700;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">T</div>
|
||||
<div id="profileAvatar"
|
||||
style="width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,#e8a838,#f0c040);color:#fff;font-size:36px;font-weight:700;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">
|
||||
T</div>
|
||||
<h3 id="profileDisplayName" style="margin-bottom:4px;">—</h3>
|
||||
<span class="text-muted text-sm" id="profileDisplayRole">อาจารย์</span>
|
||||
<div style="margin-top:12px;">
|
||||
@@ -124,7 +134,8 @@
|
||||
</div>
|
||||
<hr style="border-color:var(--border-color);margin:20px 0;">
|
||||
<div class="text-sm text-muted">🆔 รหัสบุคลากร</div>
|
||||
<div style="font-size:18px;font-weight:600;margin-top:4px;" id="profilePersonnelCode">—</div>
|
||||
<div style="font-size:18px;font-weight:600;margin-top:4px;" id="profilePersonnelCode">—
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -139,7 +150,8 @@
|
||||
<label class="form-label">รหัสบุคลากร</label>
|
||||
<input type="text" class="form-input" id="profileCode" disabled
|
||||
style="background:var(--bg-secondary);cursor:not-allowed;opacity:0.7;">
|
||||
<small class="text-muted" style="display:block;margin-top:4px;">🔒 ไม่สามารถแก้ไขได้ — ติดต่อผู้ดูแลระบบ</small>
|
||||
<small class="text-muted" style="display:block;margin-top:4px;">🔒
|
||||
ไม่สามารถแก้ไขได้ — ติดต่อผู้ดูแลระบบ</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">ชื่อ-นามสกุล *</label>
|
||||
@@ -174,8 +186,10 @@
|
||||
placeholder="พิมพ์รหัสผ่านใหม่อีกครั้ง">
|
||||
</div>
|
||||
<div style="display:flex;gap:12px;justify-content:flex-end;margin-top:24px;">
|
||||
<button type="button" class="btn btn-secondary" onclick="loadProfile()">🔄 รีเซ็ต</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveProfile()">💾 บันทึกข้อมูล</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="loadProfile()">🔄
|
||||
รีเซ็ต</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveProfile()">💾
|
||||
บันทึกข้อมูล</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user