Rename ssr to website, website to spa, add spa nginx config
This commit is contained in:
1 parent
fc6bf0218e
commit
8514342c2f
103 files changed
+801
-768
No files matched your search
@@ -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'
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user