added current time(yellow ring) enhancement
follow server time instead of user computer local time.
This commit is contained in:
@@ -59,6 +59,22 @@ async function startServer() {
|
|||||||
|
|
||||||
app.use(cors(corsOptions));
|
app.use(cors(corsOptions));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
// --- Public server time endpoints (no auth, no cache) ---
|
||||||
|
const timeHandler = (req, res) => {
|
||||||
|
const now = new Date();
|
||||||
|
const ymdKL = new Intl.DateTimeFormat('en-CA', {
|
||||||
|
timeZone: 'Asia/Kuala_Lumpur',
|
||||||
|
year: 'numeric', month: '2-digit', day: '2-digit'
|
||||||
|
}).format(now); // "YYYY-MM-DD"
|
||||||
|
|
||||||
|
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
||||||
|
res.set('Pragma', 'no-cache');
|
||||||
|
res.set('Expires', '0');
|
||||||
|
|
||||||
|
res.json({ nowIso: now.toISOString(), tz: 'Asia/Kuala_Lumpur', ymdKL });
|
||||||
|
};
|
||||||
|
app.get('/time', timeHandler); // public path
|
||||||
|
app.get('/api/time', timeHandler); // also under /api
|
||||||
|
|
||||||
app.use('/api/managers', managerRoutes(db));
|
app.use('/api/managers', managerRoutes(db));
|
||||||
app.use('/api', workerRoutes(db));
|
app.use('/api', workerRoutes(db));
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed, onUnmounted } from 'vue';
|
||||||
import { apiFetch } from '@/api.js';
|
import { apiFetch } from '@/api.js';
|
||||||
import { useToast } from '@/composables/useToast';
|
import { useToast } from '@/composables/useToast';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
@@ -73,7 +73,46 @@ const { t: $t } = useI18n();
|
|||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const viewDate = ref(new Date());
|
const viewDate = ref(new Date());
|
||||||
const todayStr = new Date().toISOString().slice(0, 10);
|
// Server-driven KL date for the yellow ring (updates every 60s)
|
||||||
|
const todayStr = ref(null);
|
||||||
|
|
||||||
|
const TZ = 'Asia/Kuala_Lumpur';
|
||||||
|
|
||||||
|
// Helper: format YYYY-MM-DD in a given TZ
|
||||||
|
const ymdInTZ = (tz, d = new Date()) =>
|
||||||
|
new Intl.DateTimeFormat('en-CA', {
|
||||||
|
timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit'
|
||||||
|
}).format(d);
|
||||||
|
|
||||||
|
// Pull today from server; try /api/time then /time; fallback to client KL
|
||||||
|
async function getServerDate() {
|
||||||
|
const parse = (data) => {
|
||||||
|
if (typeof data?.ymdKL === 'string') return data.ymdKL;
|
||||||
|
if (data?.nowIso) return ymdInTZ(TZ, new Date(data.nowIso));
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const path of ['/api/time', '/time']) {
|
||||||
|
try {
|
||||||
|
const d = await apiFetch(`${path}?_t=${Date.now()}`);
|
||||||
|
const y = parse(d);
|
||||||
|
if (y) return y;
|
||||||
|
} catch (_err) {
|
||||||
|
continue; // try next endpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn('Server time unavailable; using client KL time.');
|
||||||
|
return ymdInTZ(TZ, new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
let _intervalId;
|
||||||
|
onMounted(async () => {
|
||||||
|
const update = async () => { todayStr.value = await getServerDate(); };
|
||||||
|
await update();
|
||||||
|
_intervalId = setInterval(update, 60_000);
|
||||||
|
});
|
||||||
|
onUnmounted(() => { if (_intervalId) clearInterval(_intervalId); });
|
||||||
|
|
||||||
const originalEnabledDates = ref(new Set());
|
const originalEnabledDates = ref(new Set());
|
||||||
const datesToEnable = ref(new Set());
|
const datesToEnable = ref(new Set());
|
||||||
@@ -129,7 +168,7 @@ const getDayClasses = (day) => {
|
|||||||
classes.push('bg-white', 'dark:bg-gray-800', 'hover:bg-gray-100', 'dark:hover:bg-gray-700');
|
classes.push('bg-white', 'dark:bg-gray-800', 'hover:bg-gray-100', 'dark:hover:bg-gray-700');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dateStr === todayStr) {
|
if (todayStr.value && dateStr === todayStr.value) {
|
||||||
classes.push('ring-2', 'ring-yellow-400', 'dark:ring-yellow-500');
|
classes.push('ring-2', 'ring-yellow-400', 'dark:ring-yellow-500');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user