2. เมื่อได้ jwt token ให้ fetch:
fetch('api/auth.php', { method: 'POST', body: JSON.stringify({ token: jwtToken }) })
*/
setUser({ name: 'สมาชิกระบบ (ทดสอบ)', email: 'user@gmail.com' });
resetUpload();
setShowRegisterModal(false);
}
};
// ==========================================
// UI Logic Functions
// ==========================================
const handleUserFramePhotoUpload = (e) => {
const file = e.target.files[0];
if (file && file.type.startsWith('image/')) {
setUserFramePhoto(URL.createObjectURL(file));
setFrameImagePos({ x: 50, y: 50 });
}
};
const onDragOver = (e) => e.preventDefault();
const onDrop = (e) => {
e.preventDefault();
if (!policyAccepted) { alert(t.alertPolicy); return; }
if (e.dataTransfer.files) handleFiles(e.dataTransfer.files);
};
const handleCopy = (text, id) => {
const textArea = document.createElement("textarea"); textArea.value = text; document.body.appendChild(textArea); textArea.select();
try { document.execCommand("copy"); setCopiedId(id); setTimeout(() => setCopiedId(null), 2000); } catch (err) {}
document.body.removeChild(textArea);
};
const resetUpload = () => {
setUploadedFiles([]); setGalleryId(null); setCopiedId(null); setViewingGallery(false); setSelectedImage(null);
if (fileInputRef.current) fileInputRef.current.value = '';
};
const getSingleLinkFormats = (f) => [
{ id: 'link', label: t.webLink, value: f.pageUrl },
{ id: 'direct', label: t.directLink, value: f.directUrl },
{ id: 'bbcode', label: t.bbcode, value: `[url=${f.pageUrl}][img]${f.directUrl}[/img][/url]` }
];
const scrollSlider = (ref, dir) => {
if (ref.current) { ref.current.scrollBy({ left: dir === 'left' ? -300 : 300, behavior: 'smooth' }); }
};
const openSubCategoryModal = (type, category) => {
setSelectedMainCategory({ type, ...category });
const initialSubCategoryList = getSubCategories(category.titleTh);
setSelectedSubCategory(initialSubCategoryList[0]);
setUserFramePhoto(null);
};
const handleItemAction = async (item, type) => {
if (type === 'frame') {
if (item.tier === 'paid' && !user) { setShowRegisterModal(true); return; }
if (item.tier === 'paid' && user) { setShowConstruction(true); return; }
if (item.tier === 'member' && !user) { setShowRegisterModal(true); return; }
setSelectedFrameToEdit(item);
setUserFramePhoto(null);
setFrameImagePos({ x: 50, y: 50 });
} else {
if (item.tier === 'free') alert('ดาวน์โหลดรูปฟรีสำเร็จ!');
else if (item.tier === 'member') { if (!user) setShowRegisterModal(true); else alert('สิทธิสมาชิก: ดาวน์โหลดสำเร็จ!'); }
else if (item.tier === 'paid') {
if (!user) { setShowRegisterModal(true); return; }
// ตัวอย่างการเรียกใช้ buy_item.php (ต้องมีระบบจ่ายเงินจริงมาครอบ)
setShowConstruction(true);
}
}
};
const startDrag = (e) => {
setIsFrameDragging(true);
const clientX = e.clientX || (e.touches && e.touches[0].clientX);
const clientY = e.clientY || (e.touches && e.touches[0].clientY);
dragStartRef.current = { x: clientX, y: clientY, panX: frameImagePos.x, panY: frameImagePos.y };
};
const onDrag = (e) => {
if (!isFrameDragging) return;
const clientX = e.clientX || (e.touches && e.touches[0].clientX);
const clientY = e.clientY || (e.touches && e.touches[0].clientY);
const deltaX = clientX - dragStartRef.current.x;
const deltaY = clientY - dragStartRef.current.y;
const sensitivity = 0.3;
setFrameImagePos({
x: Math.max(0, Math.min(100, dragStartRef.current.panX - (deltaX * sensitivity))),
y: Math.max(0, Math.min(100, dragStartRef.current.panY - (deltaY * sensitivity)))
});
};
const endDrag = () => setIsFrameDragging(false);
if (viewingGallery) {
return (
{t.yourGallery}
{uploadedFiles.map((file) => (
setSelectedImage(file)}>
))}
{selectedImage && (
setSelectedImage(null)}>

e.stopPropagation()} />
)}
);
}
return (
{/* Header */}
{/* Main Content */}
{uploadedFiles.length === 0 ? (
{t.heroTitle}
{user ? t.heroSubMem : t.heroSubGuest}
{user ?
{t.statusMem} {memberCount}/100 {t.imgCount} • {t.imgDel3} :
{t.statusGuest} {guestCount}/3 {t.imgCount} • {t.imgDel1}}
{isUploading ? (
) : (
<>
{t.dragDrop}
{t.or}
handleFiles(e.target.files)} accept="image/*" multiple={!!user} />
>
)}
{!user && (
{t.promoTitle}
- {t.promo1}
- {t.promo2}
- {t.promo3}
)}
) : (
{t.uploadSuccess} ({uploadedFiles.length} {t.imgCount})
{t.autoDelIn} {user ? t.days3 : t.days1}
{galleryId && (
)}
{uploadedFiles.map((file, idx) => (
{ if(galleryId) setSelectedImage(file); }}>

{galleryId &&
}
{file.filename}
{t.linkForImg} {idx+1}
{getSingleLinkFormats(file).map(fmt => (
))}
))}
)}
{/* Free Avatar Categories */}
{t.exploreMore}
{mainAvatarCategories.map((category) => (
openSubCategoryModal('avatar', category)} className="flex-shrink-0 w-32 h-32 md:w-36 md:h-36 bg-white hover:bg-blue-50 rounded-2xl cursor-pointer transition-all snap-center flex flex-col items-center justify-center border border-slate-200 shadow-sm hover:shadow-md hover:border-blue-200 group/box">
{category.icon}
{lang === 'th' ? category.titleTh : category.titleEn}
))}
{/* Free Frame Categories */}
{t.freeFrames}
{mainFrameCategories.map((category) => (
openSubCategoryModal('frame', category)} className="flex-shrink-0 w-32 h-32 md:w-36 md:h-36 bg-white hover:bg-orange-50 rounded-2xl cursor-pointer transition-all snap-center flex flex-col items-center justify-center border border-slate-200 shadow-sm hover:shadow-md hover:border-orange-200 group/box">
{category.icon}
{lang === 'th' ? category.titleTh : category.titleEn}
))}
{/* Main Modal Popup */}
{selectedMainCategory && (
{selectedMainCategory.icon}
{lang === 'th' ? selectedMainCategory.titleTh : selectedMainCategory.titleEn}
{t.selectSubCat}
{selectedMainCategory.type === 'avatar' ? t.selectSubCat : 'เลือกลวดลายกรอบรูป'}
{getSubCategories(selectedMainCategory.titleTh).map((subTitle, index) => {
const isSelected = selectedSubCategory === subTitle;
const themeColor = selectedMainCategory.type === 'avatar' ? 'blue' : 'orange';
return (
setSelectedSubCategory(subTitle)} className={`flex-shrink-0 w-28 md:w-32 rounded-xl cursor-pointer transition-all snap-start flex flex-col border-2 overflow-hidden ${isSelected ? `border-${themeColor}-500 bg-${themeColor}-50 ring-2 ring-${themeColor}-200` : 'border-slate-100 bg-white hover:border-slate-200'}`}>
{selectedMainCategory.type === 'avatar' ? : }
);
})}
{storeItems.length > 0 ? (
{/* ส่วนแจกฟรี */}
{t.tierFree}
{storeItems.filter(i => i.tier === 'free').map(item => (
{!item.file_url && (selectedMainCategory.type === 'avatar' ? : )}
{item.name}
))}
{/* ส่วนสมาชิก */}
{t.tierMember} {!user && }
{storeItems.filter(i => i.tier === 'member').map(item => {
const isLocked = !user; const themeColor = selectedMainCategory.type === 'avatar' ? 'blue' : 'orange';
return (
{!item.file_url && (selectedMainCategory.type === 'avatar' ?
:
)}{isLocked &&
}
{item.name}
);
})}
{/* ส่วนพรีเมียม */}
{t.tierPaid} {!user && }
{storeItems.filter(i => i.tier === 'paid').map(item => {
const isLocked = !user; return (
{!item.file_url && (selectedMainCategory.type === 'avatar' ?
:
)}{isLocked &&
}
{item.name}
);
})}
) : (
{t.emptyCategory}
ยังไม่มีไอเทมในหมวดหมู่นี้ หรือรอเพิ่มข้อมูลลงในระบบฐานข้อมูล Database
)}
)}
{/* Frame Editor Modal */}
{selectedFrameToEdit && (
แต่งรูปภาพ (Frame Editor)
ตกแต่งรูปภาพของคุณด้วยลวดลาย "{selectedFrameToEdit.name}"
สลับลวดลายกรอบรูปคอลเลกชันนี้:
{storeItems.map((frame) => {
const isSelected = selectedFrameToEdit.id === frame.id;
const isLocked = frame.tier === 'paid' || (frame.tier === 'member' && !user);
return (
{ if (isLocked) { if (!user) setShowRegisterModal(true); else setShowConstruction(true); } else { setSelectedFrameToEdit(frame); } }} className={`shrink-0 w-20 h-20 border-2 rounded-xl flex flex-col items-center justify-center cursor-pointer transition-all snap-start relative overflow-hidden bg-cover bg-center ${isSelected ? 'border-orange-500 bg-orange-50 ring-2 ring-orange-200' : 'border-slate-200 bg-slate-50 hover:border-orange-300'}`} style={frame.file_url ? {backgroundImage: `url(${frame.file_url})`} : {}}>
{!frame.file_url &&
}
{!frame.file_url &&
{frame.name}}
{isLocked &&
}
);
})}
{userFramePhoto ? (

) : (
)}
{!selectedFrameToEdit.file_url && (
{selectedFrameToEdit.name}
)}
{userFramePhoto && (
)}
{t.uploadUserImg}
{userFramePhoto && (
)}
)}
{/* Modals ย่อย */}
{showRegisterModal && (
{t.quotaFull}
{t.guestLimit}
{t.perksTitle}
- {t.perk1}
- {t.perk2}
- {t.perk3}
- {t.perk4}
)}
{showPolicyModal && (
{t.tosTitle}
1. การปฏิเสธความรับผิดชอบ: บริการนี้เป็นเพียงที่เก็บไฟล์ชั่วคราว ไม่รับผิดชอบลิขสิทธิ์
2. ความรับผิดชอบผู้ใช้: ผู้ใช้อัปโหลดต้องเป็นเจ้าของลิขสิทธิ์หรือได้รับอนุญาต
)}
{showConstruction && (
{t.underConstructionTitle}
{t.underConstructionDesc}
)}
);
}
const root = createRoot(document.getElementById('root'));
root.render();