{"id":1815,"date":"2026-08-17T12:58:31","date_gmt":"2026-08-17T12:58:31","guid":{"rendered":"http:\/\/ipcphiladelphiadubai.com\/loaves\/?page_id=1815"},"modified":"2026-08-17T12:59:43","modified_gmt":"2026-08-17T12:59:43","slug":"uncle-philly-admin","status":"publish","type":"page","link":"http:\/\/ipcphiladelphiadubai.com\/loaves\/uncle-philly-admin\/","title":{"rendered":"uncle Philly Admin"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1815\" class=\"elementor elementor-1815\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b36fa55 e-con-full e-flex wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"b36fa55\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-e691de7 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-child\" data-id=\"e691de7\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8b82a7b elementor-widget elementor-widget-heading\" data-id=\"8b82a7b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Get answers from <br> Uncle Philly<\/h2>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-109a4eb20 elementor-section-boxed elementor-section-height-default elementor-section-height-default wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no\" data-id=\"109a4eb20\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-2817c690\" data-id=\"2817c690\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-104018f1 elementor-widget elementor-widget-heading\" data-id=\"104018f1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Admin Page - Uncle Philly<\/h2>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t<div class=\"elementor-element elementor-element-9db15bf e-con-full e-flex wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"9db15bf\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-24f7c08 elementor-widget elementor-widget-html\" data-id=\"24f7c08\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<!-- ============================================================\n     UNCLE PHILLY \u2014 TEAM ADMIN PANEL (keep this link private)\n     Host this as a hidden page, or open the file directly in a\n     browser. Team members sign in with the email + password you\n     create in Firebase Authentication (Step 4 of the setup guide).\n     Fill in the same firebaseConfig as the public widget.\n     ============================================================ -->\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta name=\"robots\" content=\"noindex, nofollow\">\n<title>Uncle Philly \u2014 Answer Desk<\/title>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Baloo+2:wght@700;800&family=Nunito:wght@400;600;700&display=swap\" rel=\"stylesheet\">\n<style>\n  :root { --ink:#2b3a4a; --sky:#eef6f9; --sun:#ffd45e; --leaf:#3f7d4e;\n    --cloud:#fff; --line:#d5e4ea; --red:#b3403a; }\n  * { box-sizing:border-box; }\n  body { margin:0; font-family:'Nunito',system-ui,sans-serif;\n    background:var(--sky); color:var(--ink); }\n  header { background:var(--sun); padding:14px 20px; display:flex;\n    align-items:center; justify-content:space-between; }\n  header h1 { font-family:'Baloo 2',cursive; font-size:1.2rem; margin:0; }\n  main { max-width:760px; margin:24px auto; padding:0 16px; }\n  .card { background:var(--cloud); border:1px solid var(--line);\n    border-radius:16px; padding:16px 18px; margin-bottom:14px; }\n  .muted { color:#6b7b8a; font-size:.82rem; }\n  .qtext { font-size:1rem; margin:8px 0 10px; white-space:pre-wrap; }\n  textarea { width:100%; border:1.5px solid var(--line); border-radius:12px;\n    padding:10px 12px; font-family:inherit; font-size:.95rem; resize:vertical;\n    min-height:70px; }\n  textarea:focus, input:focus { outline:2px solid var(--sun); }\n  button { border:none; border-radius:12px; padding:9px 16px;\n    font-family:inherit; font-weight:700; font-size:.9rem; cursor:pointer; }\n  .btn-publish { background:var(--leaf); color:#fff; }\n  .btn-danger { background:#f4dcdb; color:var(--red); }\n  .btn-plain { background:#e8eef2; color:var(--ink); }\n  .row { display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; }\n  .tabs { display:flex; gap:8px; margin-bottom:16px; }\n  .tab { background:#e8eef2; border-radius:999px; padding:8px 18px;\n    font-weight:700; cursor:pointer; border:none; font-size:.9rem; }\n  .tab.active { background:var(--ink); color:#fff; }\n  .count { display:inline-block; background:var(--sun); border-radius:999px;\n    padding:0 8px; margin-left:6px; font-size:.8rem; }\n  #login { max-width:380px; margin:60px auto; }\n  #login input { width:100%; border:1.5px solid var(--line);\n    border-radius:12px; padding:10px 12px; font-family:inherit;\n    font-size:.95rem; margin-bottom:10px; }\n  .error { color:var(--red); font-size:.85rem; min-height:1.2em; }\n  .pill { font-size:.72rem; font-weight:700; background:#e8eef2;\n    border-radius:999px; padding:2px 10px; }\n  .answered { background:#e9f4e5; }\n<\/style>\n<\/head>\n<body>\n<header>\n  <h1>\ud83e\udde2 Uncle Philly \u2014 Answer Desk<\/h1>\n  <button class=\"btn-plain\" id=\"signout\" style=\"display:none\">Sign out<\/button>\n<\/header>\n\n<main>\n  <div id=\"login\" class=\"card\">\n    <h2 style=\"font-family:'Baloo 2',cursive; margin-top:0\">Team sign in<\/h2>\n    <input id=\"email\" type=\"email\" placeholder=\"Email\" autocomplete=\"username\">\n    <input id=\"password\" type=\"password\" placeholder=\"Password\" autocomplete=\"current-password\">\n    <div class=\"error\" id=\"login-error\"><\/div>\n    <button class=\"btn-publish\" id=\"login-btn\">Sign in<\/button>\n  <\/div>\n\n  <div id=\"desk\" style=\"display:none\">\n    <div class=\"tabs\">\n      <button class=\"tab active\" id=\"tab-pending\">Waiting for answers<span class=\"count\" id=\"pending-count\">0<\/span><\/button>\n      <button class=\"tab\" id=\"tab-published\">Published<span class=\"count\" id=\"published-count\">0<\/span><\/button>\n    <\/div>\n    <div id=\"list\"><\/div>\n  <\/div>\n<\/main>\n\n<script type=\"module\">\n  import { initializeApp } from \"https:\/\/www.gstatic.com\/firebasejs\/10.12.2\/firebase-app.js\";\n  import { getAuth, signInWithEmailAndPassword, onAuthStateChanged, signOut }\n    from \"https:\/\/www.gstatic.com\/firebasejs\/10.12.2\/firebase-auth.js\";\n  import { getFirestore, collection, query, where, onSnapshot, doc,\n           updateDoc, deleteDoc, serverTimestamp }\n    from \"https:\/\/www.gstatic.com\/firebasejs\/10.12.2\/firebase-firestore.js\";\n\n  \/* \u2500\u2500 Paste the SAME Firebase config used in the public widget \u2500\u2500 *\/\n  const firebaseConfig = {\n    apiKey: \"AIzaSyCbP9rC-TLRmSOHySINUKj7jz90RTjbMMU\",\n    authDomain: \"uncle-philly.firebaseapp.com\",\n    projectId: \"uncle-philly\",\n    storageBucket: \"uncle-philly.firebasestorage.app\",\n    messagingSenderId: \"618762632809\",\n    appId: \"1:618762632809:web:4a8ae36b29a62a09432cf8\"\n  };\n\n  const app = initializeApp(firebaseConfig);\n  const auth = getAuth(app);\n  const db = getFirestore(app);\n\n  const loginBox = document.getElementById(\"login\");\n  const desk = document.getElementById(\"desk\");\n  const list = document.getElementById(\"list\");\n  const loginErr = document.getElementById(\"login-error\");\n  const signoutBtn = document.getElementById(\"signout\");\n  const tabPending = document.getElementById(\"tab-pending\");\n  const tabPublished = document.getElementById(\"tab-published\");\n\n  let view = \"pending\";\n  let pendingDocs = [], publishedDocs = [];\n  let unsubPending = null, unsubPublished = null;\n\n  document.getElementById(\"login-btn\").addEventListener(\"click\", async () => {\n    loginErr.textContent = \"\";\n    try {\n      await signInWithEmailAndPassword(auth,\n        document.getElementById(\"email\").value.trim(),\n        document.getElementById(\"password\").value);\n    } catch {\n      loginErr.textContent = \"Sign in didn't work \u2014 check the email and password.\";\n    }\n  });\n  document.getElementById(\"password\").addEventListener(\"keydown\", e => {\n    if (e.key === \"Enter\") document.getElementById(\"login-btn\").click();\n  });\n  signoutBtn.addEventListener(\"click\", () => signOut(auth));\n\n  onAuthStateChanged(auth, user => {\n    const on = !!user;\n    loginBox.style.display = on ? \"none\" : \"block\";\n    desk.style.display = on ? \"block\" : \"none\";\n    signoutBtn.style.display = on ? \"inline-block\" : \"none\";\n    if (on) listen(); else stopListening();\n  });\n\n  function listen() {\n    stopListening();\n    unsubPending = onSnapshot(\n      query(collection(db, \"questions\"), where(\"status\", \"==\", \"pending\")),\n      snap => { pendingDocs = sortDocs(snap); render(); });\n    unsubPublished = onSnapshot(\n      query(collection(db, \"questions\"), where(\"status\", \"==\", \"approved\")),\n      snap => { publishedDocs = sortDocs(snap); render(); });\n  }\n  function stopListening() {\n    if (unsubPending) unsubPending(); if (unsubPublished) unsubPublished();\n    unsubPending = unsubPublished = null;\n  }\n  const sortDocs = snap => snap.docs\n    .map(d => ({ id: d.id, ...d.data() }))\n    .sort((a, b) => (b.createdAt?.seconds || 0) - (a.createdAt?.seconds || 0));\n\n  tabPending.addEventListener(\"click\", () => { view = \"pending\"; render(); });\n  tabPublished.addEventListener(\"click\", () => { view = \"published\"; render(); });\n\n  function render() {\n    document.getElementById(\"pending-count\").textContent = pendingDocs.length;\n    document.getElementById(\"published-count\").textContent = publishedDocs.length;\n    tabPending.classList.toggle(\"active\", view === \"pending\");\n    tabPublished.classList.toggle(\"active\", view === \"published\");\n    list.innerHTML = \"\";\n    const docs = view === \"pending\" ? pendingDocs : publishedDocs;\n    if (!docs.length) {\n      const p = document.createElement(\"p\");\n      p.className = \"muted\";\n      p.textContent = view === \"pending\"\n        ? \"All caught up \u2014 no questions waiting. \ud83c\udf89\"\n        : \"Nothing published yet.\";\n      list.append(p);\n      return;\n    }\n    for (const q of docs) list.append(card(q));\n  }\n\n  function card(q) {\n    const el = document.createElement(\"div\");\n    el.className = \"card\" + (view === \"published\" ? \" answered\" : \"\");\n\n    const meta = document.createElement(\"div\");\n    meta.className = \"muted\";\n    const when = q.createdAt?.seconds\n      ? new Date(q.createdAt.seconds * 1000).toLocaleString() : \"\";\n    meta.textContent = `Anonymous question \u00b7 ${when}`;\n    el.append(meta);\n\n    const text = document.createElement(\"div\");\n    text.className = \"qtext\";\n    text.textContent = q.question || \"\";\n    el.append(text);\n\n    const ta = document.createElement(\"textarea\");\n    ta.placeholder = \"Type Uncle Philly's answer\u2026\";\n    ta.value = q.answer || \"\";\n    el.append(ta);\n\n    const row = document.createElement(\"div\");\n    row.className = \"row\";\n\n    const publish = document.createElement(\"button\");\n    publish.className = \"btn-publish\";\n    publish.textContent = view === \"pending\" ? \"Publish answer\" : \"Update answer\";\n    publish.addEventListener(\"click\", async () => {\n      const answer = ta.value.trim();\n      if (!answer) { ta.focus(); return; }\n      publish.disabled = true;\n      await updateDoc(doc(db, \"questions\", q.id),\n        { answer, status: \"approved\", answeredAt: serverTimestamp() });\n    });\n    row.append(publish);\n\n    if (view === \"published\") {\n      const hide = document.createElement(\"button\");\n      hide.className = \"btn-plain\";\n      hide.textContent = \"Unpublish\";\n      hide.addEventListener(\"click\", () =>\n        updateDoc(doc(db, \"questions\", q.id), { status: \"pending\" }));\n      row.append(hide);\n    }\n\n    const del = document.createElement(\"button\");\n    del.className = \"btn-danger\";\n    del.textContent = \"Delete\";\n    del.addEventListener(\"click\", () => {\n      if (confirm(\"Delete this question completely?\"))\n        deleteDoc(doc(db, \"questions\", q.id));\n    });\n    row.append(del);\n\n    el.append(row);\n    return el;\n  }\n<\/script>\n<\/body>\n<\/html>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Get answers from Uncle Philly Admin Page &#8211; Uncle Philly Uncle Philly \u2014 Answer Desk \ud83e\udde2 Uncle Philly \u2014 Answer Desk Sign out Team sign in Sign in Waiting for answers0 Published0<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-1815","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/pages\/1815","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/comments?post=1815"}],"version-history":[{"count":4,"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/pages\/1815\/revisions"}],"predecessor-version":[{"id":1819,"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/pages\/1815\/revisions\/1819"}],"wp:attachment":[{"href":"http:\/\/ipcphiladelphiadubai.com\/loaves\/wp-json\/wp\/v2\/media?parent=1815"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}