Skip to content

Commit bab70ab

Browse files
authored
initial commit
1 parent f840270 commit bab70ab

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

meta/gh-edit.html

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Narwhal Bot Console</title>
7+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8+
<style>
9+
:root { --bg: #0d1117; --card: #161b22; --border: #30363d; --text: #c9d1d9; --accent: #238636; }
10+
body { background: var(--bg); color: var(--text); font-family: sans-serif; margin: 0; display: flex; height: 100vh; }
11+
#sidebar { width: 300px; border-right: 1px solid var(--border); background: var(--card); padding: 20px; }
12+
#main { flex: 1; padding: 40px; }
13+
.hidden { display: none !important; }
14+
button { background: var(--accent); color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; }
15+
#console { background: #000; color: #7ee787; padding: 15px; height: 200px; overflow-y: auto; font-family: monospace; border-radius: 6px; margin-top: 20px; }
16+
input, textarea { width: 100%; background: #0d1117; border: 1px solid var(--border); color: white; padding: 10px; margin: 10px 0; border-radius: 4px; }
17+
</style>
18+
</head>
19+
<body>
20+
21+
<div id="auth-screen" style="position:fixed; inset:0; background:var(--bg); z-index:100; display:flex; flex-direction:column; align-items:center; justify-content:center;">
22+
<h1>HouseLearning Admin</h1>
23+
<button onclick="login()">Login with Google</button>
24+
</div>
25+
26+
<div id="sidebar">
27+
<h3>Repositories</h3>
28+
<div id="repo-list">Loading...</div>
29+
</div>
30+
31+
<div id="main">
32+
<h2 id="active-repo">Select a Repository</h2>
33+
<div id="controls" class="hidden">
34+
<input type="text" id="filePath" placeholder="path/to/file.md">
35+
<textarea id="fileContent" rows="10" placeholder="Content..."></textarea>
36+
<button onclick="sendCommit()">Commit as neilthenarwhal-bot</button>
37+
</div>
38+
<div id="console">System Ready.</div>
39+
</div>
40+
41+
<script src="https://www.gstatic.com/firebasejs/10.4.0/firebase-app-compat.js"></script>
42+
<script src="https://www.gstatic.com/firebasejs/10.4.0/firebase-auth-compat.js"></script>
43+
44+
<script>
45+
// --- CONFIGURATION ---
46+
const firebaseConfig = {
47+
apiKey: "AIzaSyDoXSwni65CuY1_32ZE8B1nwfQO_3VNpTw",
48+
authDomain: "contract-center-llc-10.firebaseapp.com",
49+
projectId: "contract-center-llc-10",
50+
storageBucket: "contract-center-llc-10.firebasestorage.app",
51+
messagingSenderId: "323221512767",
52+
appId: "1:323221512767:web:6421260f875997dbf64e8a",
53+
};
54+
const GAS_WEB_APP_URL = "https://script.google.com/macros/s/AKfycbxTfgak4gjvbzARZ3oVtdDd7hD9JJfmgfvwQnAN5XATa2KJ3dmy9bpyql1Lfl8f8T5l/exec";
55+
// ---------------------
56+
57+
firebase.initializeApp(firebaseConfig);
58+
let currentUser = null;
59+
let selectedRepo = null;
60+
61+
function log(msg) {
62+
const c = document.getElementById('console');
63+
c.innerHTML += `<div>> ${msg}</div>`;
64+
c.scrollTop = c.scrollHeight;
65+
}
66+
67+
async function login() {
68+
const provider = new firebase.auth.GoogleAuthProvider();
69+
try {
70+
const result = await firebase.auth().signInWithPopup(provider);
71+
currentUser = result.user;
72+
73+
// Verify Admin Role via GAS
74+
log("Verifying permissions...");
75+
const resp = await callGAS('verifyAdmin', { uid: currentUser.uid });
76+
77+
if (resp.isAdmin) {
78+
document.getElementById('auth-screen').classList.add('hidden');
79+
loadRepos();
80+
} else {
81+
alert("Unauthorized: Admin role required in Firestore.");
82+
}
83+
} catch (e) { log("Auth Error: " + e.message); }
84+
}
85+
86+
async function callGAS(action, params) {
87+
const url = `${GAS_WEB_APP_URL}?action=${action}&uid=${currentUser?.uid || params.uid}`;
88+
const response = await fetch(url, {
89+
method: 'POST',
90+
body: JSON.stringify(params)
91+
});
92+
return await response.json();
93+
}
94+
95+
async function loadRepos() {
96+
const data = await callGAS('getRepos', {});
97+
const list = document.getElementById('repo-list');
98+
list.innerHTML = "";
99+
data.repos.forEach(repo => {
100+
const div = document.createElement('div');
101+
div.style.padding = "5px; cursor:pointer;";
102+
div.innerText = repo.name;
103+
div.onclick = () => {
104+
selectedRepo = repo.name;
105+
document.getElementById('active-repo').innerText = repo.name;
106+
document.getElementById('controls').classList.remove('hidden');
107+
};
108+
list.appendChild(div);
109+
});
110+
}
111+
112+
async function sendCommit() {
113+
const payload = {
114+
repo: selectedRepo,
115+
path: document.getElementById('filePath').value,
116+
content: document.getElementById('fileContent').value
117+
};
118+
log(`Committing to ${selectedRepo}...`);
119+
const res = await callGAS('commit', payload);
120+
log(res.status === "success" ? "Done!" : "Error: " + res.message);
121+
}
122+
</script>
123+
</body>
124+
</html>

0 commit comments

Comments
 (0)