{"id":37,"date":"2026-05-23T06:04:44","date_gmt":"2026-05-23T06:04:44","guid":{"rendered":"https:\/\/tinbamien.com\/?page_id=37"},"modified":"2026-05-23T06:16:00","modified_gmt":"2026-05-23T06:16:00","slug":"37-2","status":"publish","type":"page","link":"https:\/\/tinbamien.com\/?page_id=37","title":{"rendered":""},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"vi\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Cloud Data Pro<\/title>\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <style>\n        body { background: #f1f5f9; font-family: 'Inter', system-ui, sans-serif; }\n        .card { background: white; border-radius: 1rem; border: 1px solid #e2e8f0; box-shadow: 0 4px 6px -1px rgb(0 0 0 \/ 0.1); }\n        .btn-primary { background: #2563eb; transition: all 0.2s; }\n        .btn-primary:active { transform: scale(0.98); }\n        textarea { width: 100%; height: 250px; padding: 1rem; border: 1px solid #e2e8f0; border-radius: 0.75rem; outline: none; transition: border-color 0.2s; }\n        textarea:focus { border-color: #2563eb; ring: 2px solid #dbeafe; }\n        .toast { transition: opacity 0.3s, transform 0.3s; }\n    <\/style>\n<\/head>\n<body class=\"p-4 md:p-8\">\n\n    <div class=\"max-w-md mx-auto\">\n        <div class=\"flex justify-between items-center mb-4\">\n            <span class=\"text-xs font-bold text-slate-500 uppercase tracking-widest flex items-center gap-2\">\n                <span class=\"w-2 h-2 rounded-full bg-emerald-500 animate-pulse\"><\/span>\n                Cloud Sync: <span id=\"sync-status\">\u0110ang t\u1ea3i&#8230;<\/span>\n            <\/span>\n            <span id=\"item-count\" class=\"text-xs font-bold bg-slate-200 px-2 py-1 rounded\">0 m\u1ee5c<\/span>\n        <\/div>\n\n        <div class=\"card p-4 mb-4\">\n            <textarea id=\"input-list\" placeholder=\"Nh\u1eadp d\u1eef li\u1ec7u:\n1. N\u1ed9i dung... | M\u00e3\n2. N\u1ed9i dung... | M\u00e3\"><\/textarea>\n            <button id=\"next-btn\" class=\"w-full mt-3 text-white font-bold py-3 rounded-lg btn-primary hover:bg-blue-700\">TR\u00cdCH XU\u1ea4T NG\u1eaaU NHI\u00caN<\/button>\n        <\/div>\n\n        <div id=\"result-area\" class=\"card p-5 hidden\">\n            \n            <!-- Thanh c\u00f4ng c\u1ee5 ch\u1ee9a 2 n\u00fat copy -->\n            <div class=\"flex gap-2 mb-6\">\n                <button onclick=\"copyContent()\" class=\"bg-slate-800 hover:bg-slate-900 text-white font-bold px-4 py-2 rounded-lg text-[10px] transition\">COPY 1<\/button>\n                <button onclick=\"copyCode()\" class=\"bg-emerald-600 hover:bg-emerald-700 text-white font-bold px-4 py-2 rounded-lg text-[10px] transition\">COPY 2<\/button>\n            <\/div>\n\n            <!-- Ph\u1ea7n N\u1ed9i dung -->\n            <div class=\"mb-6\">\n                <p class=\"text-[10px] text-slate-400 font-bold uppercase mb-2\">N\u1ed9i dung:<\/p>\n                <div id=\"content-display\" class=\"text-sm font-medium text-slate-800 whitespace-pre-wrap break-words bg-slate-50 p-3 rounded-lg border border-slate-100\"><\/div>\n            <\/div>\n            \n            <!-- Ph\u1ea7n M\u00e3 -->\n            <div>\n                <p class=\"text-[10px] text-slate-400 font-bold uppercase mb-2\">M\u00e3:<\/p>\n                <div id=\"code-display\" class=\"text-lg font-black text-emerald-600 bg-emerald-50 p-3 rounded-lg break-all border border-emerald-100\"><\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script type=\"module\">\n        import { initializeApp } from \"https:\/\/www.gstatic.com\/firebasejs\/11.0.1\/firebase-app.js\";\n        import { getFirestore, doc, setDoc, onSnapshot } from \"https:\/\/www.gstatic.com\/firebasejs\/11.0.1\/firebase-firestore.js\";\n\n        const firebaseConfig = {\n            apiKey: \"AIzaSyAJpoRBDXNKOdP2oxzIH1W52hvipCEQdn4\",\n            projectId: \"nams-10e14\",\n            storageBucket: \"nams-10e14.firebasestorage.app\",\n            messagingSenderId: \"153250500161\",\n            appId: \"1:153250500161:web:cb98d359d10c2a873840c0\"\n        };\n\n        const app = initializeApp(firebaseConfig);\n        const db = getFirestore(app);\n        const APP_ID = 'data-manager-nams-v2';\n\n        const textarea = document.getElementById('input-list');\n        const countEl = document.getElementById('item-count');\n        const syncStatus = document.getElementById('sync-status');\n\n        \/\/ Helper: Toast notification\n        const showToast = (message) => {\n            const toast = document.createElement('div');\n            toast.className = \"fixed bottom-5 left-1\/2 -translate-x-1\/2 bg-slate-800 text-white px-4 py-2 rounded-full text-xs font-bold shadow-lg z-50 animate-fade-in\";\n            toast.innerText = message;\n            document.body.appendChild(toast);\n            setTimeout(() => {\n                toast.style.opacity = '0';\n                setTimeout(() => toast.remove(), 300);\n            }, 2000);\n        };\n\n        \/\/ Logic: Parsing data from textarea\n        const parseData = () => {\n            const text = textarea.value;\n            const regex = \/\\d+\\.\\s*([\\s\\S]*?)\\|([\\s\\S]*?)(?=\\n\\s*\\d+\\.|$)\/g;\n            return [...text.matchAll(regex)];\n        };\n\n        const updateCount = () => {\n            const matches = parseData();\n            countEl.innerText = `${matches.length} m\u1ee5c`;\n        };\n\n        \/\/ Firebase Sync\n        onSnapshot(doc(db, 'data', APP_ID), (snap) => {\n            if (snap.exists() && document.activeElement !== textarea) {\n                textarea.value = snap.data().text || '';\n                updateCount();\n                syncStatus.innerText = '\u0110\u00e3 \u0111\u1ed3ng b\u1ed9';\n            }\n        });\n\n        textarea.oninput = () => {\n            updateCount();\n            syncStatus.innerText = '\u0110ang l\u01b0u...';\n            setDoc(doc(db, 'data', APP_ID), { text: textarea.value }, { merge: true })\n                .then(() => syncStatus.innerText = '\u0110\u00e3 \u0111\u1ed3ng b\u1ed9');\n        };\n\n        \/\/ UI Handlers\n        document.getElementById('next-btn').onclick = () => {\n            const matches = parseData();\n            if (matches.length === 0) return showToast(\"Vui l\u00f2ng nh\u1eadp \u0111\u00fang \u0111\u1ecbnh d\u1ea1ng!\");\n\n            const randomMatch = matches[Math.floor(Math.random() * matches.length)];\n            const resArea = document.getElementById('result-area');\n            \n            document.getElementById('content-display').innerText = randomMatch[1].trim();\n            document.getElementById('code-display').innerText = randomMatch[2].trim();\n            \n            resArea.classList.remove('hidden');\n            resArea.scrollIntoView({ behavior: 'smooth' });\n        };\n\n        \/\/ Helper: Fallback for clipboard\n        const copyToClipboard = (text) => {\n            const textarea = document.createElement(\"textarea\");\n            textarea.value = text;\n            textarea.style.position = \"fixed\"; \/\/ Avoid scrolling to bottom\n            textarea.style.left = \"-9999px\";\n            document.body.appendChild(textarea);\n            textarea.select();\n            try {\n                document.execCommand('copy');\n                return true;\n            } catch (err) {\n                return false;\n            } finally {\n                document.body.removeChild(textarea);\n            }\n        };\n\n        window.copyContent = () => {\n            const content = document.getElementById('content-display').innerText;\n            if (copyToClipboard(content)) {\n                showToast(\"\u0110\u00e3 ch\u00e9p n\u1ed9i dung!\");\n            } else {\n                showToast(\"L\u1ed7i ch\u00e9p n\u1ed9i dung!\");\n            }\n        };\n\n        window.copyCode = () => {\n            const code = document.getElementById('code-display').innerText;\n            if (copyToClipboard(code)) {\n                showToast(\"\u0110\u00e3 ch\u00e9p m\u00e3!\");\n            } else {\n                showToast(\"L\u1ed7i ch\u00e9p m\u00e3!\");\n            }\n        };\n    <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>Cloud Data Pro Cloud Sync: \u0110ang t\u1ea3i&#8230; 0 m\u1ee5c TR\u00cdCH XU\u1ea4T NG\u1eaaU NHI\u00caN COPY 1 COPY 2 N\u1ed9i dung: M\u00e3:<\/p>\n<\/div>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-37","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/tinbamien.com\/index.php?rest_route=\/wp\/v2\/pages\/37","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tinbamien.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tinbamien.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tinbamien.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tinbamien.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=37"}],"version-history":[{"count":4,"href":"https:\/\/tinbamien.com\/index.php?rest_route=\/wp\/v2\/pages\/37\/revisions"}],"predecessor-version":[{"id":41,"href":"https:\/\/tinbamien.com\/index.php?rest_route=\/wp\/v2\/pages\/37\/revisions\/41"}],"wp:attachment":[{"href":"https:\/\/tinbamien.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=37"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}