Rename ssr to website, website to spa, add spa nginx config

This commit is contained in:
Your Name committed 2026-06-03 09:38:15 +07:00
1 parent fc6bf0218e
commit 8514342c2f
103 files changed
+801 -768

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
/**
* Central API base URL resolver.
*
* Priority:
* 1. NEXT_PUBLIC_API_URL — ตั้งค่าใน .env / .env.production (Client + Server)
* 2. INTERNAL_API_URL — ตั้งค่าใน .env สำหรับ Server-side เท่านั้น
* ใช้เมื่อ Server fetch ภายใน network เดียวกัน
* 3. Fallback dev — http://localhost:3000/api
*
* Dev: NEXT_PUBLIC_API_URL=http://localhost:3000/api
* Production: NEXT_PUBLIC_API_URL=https://api.irelaxaroma.shop/api
*/
export const API_BASE =
process.env.NEXT_PUBLIC_API_URL ||
process.env.INTERNAL_API_URL ||
'http://localhost:3000/api'
+27
View File
@@ -0,0 +1,27 @@
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import enTranslation from '../locales/en/translation.json'
import thTranslation from '../locales/th/translation.json'
// Ensure we only access localStorage on the client side
const savedLang = typeof window !== 'undefined' ? (localStorage.getItem('irelax_lang') || 'th') : 'th'
// Check if it's already initialized to prevent re-initialization on HMR
if (!i18n.isInitialized) {
i18n
.use(initReactI18next)
.init({
resources: {
en: { translation: enTranslation },
th: { translation: thTranslation },
},
lng: savedLang, // default language
fallbackLng: 'en',
interpolation: {
escapeValue: false, // react already safes from xss
},
})
}
export default i18n
-63
View File
@@ -1,63 +0,0 @@
import liff from "@line/liff";
import { useAuthStore } from "../store/authStore";
const API_URL = import.meta.env.VITE_API_URL || "http://localhost:3000/api";
export const initLiff = async (liffId: string) => {
try {
await liff.init({ liffId });
useAuthStore.getState().setLiffInitialized(true);
if (liff.isLoggedIn()) {
const profile = await liff.getProfile();
await authenticateWithBackend(profile);
} else if (liff.isInClient()) {
// เปิดเว็บผ่านเบราว์เซอร์ของ LINE (In-App Browser) แต่ยังไม่ได้ล็อกอิน
// ส่ง redirectUri: window.location.href เพื่อให้หลัง login แล้วกลับมาที่หน้าเดิม
liff.login({ redirectUri: window.location.href });
}
} catch (error) {
console.error("LIFF Initialization failed", error);
}
};
const authenticateWithBackend = async (profile: any) => {
try {
const response = await fetch(`${API_URL}/auth/line`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
lineUserId: profile.userId,
displayName: profile.displayName,
pictureUrl: profile.pictureUrl,
}),
});
if (response.ok) {
const data = await response.json();
if (data.success && data.token) {
useAuthStore.getState().setAuth(data.token, data.customer);
}
} else {
console.error("Backend authentication failed");
}
} catch (error) {
console.error("Error authenticating with backend", error);
}
};
export const loginLiff = () => {
if (!liff.isLoggedIn()) {
// ส่ง redirectUri เพื่อกลับมาที่หน้าเดิมหลัง login
liff.login({ redirectUri: window.location.href });
}
};
export const logoutLiff = () => {
if (liff.isLoggedIn()) {
liff.logout();
useAuthStore.getState().logout();
}
};