nicer q page

This commit is contained in:
Peter Howell 2025-08-13 10:54:55 -07:00
parent e4b164718a
commit f86629f9be
1 changed files with 177 additions and 45 deletions

170
q.php
View File

@ -4,15 +4,132 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Execute Query</title> <title>Execute Query</title>
<style>
:root {
--bg: #f6f7fb;
--card: #fff;
--border: #e5e7eb;
--text: #0f172a;
--muted: #64748b;
--accent: #2563eb;
}
html, body {
background: var(--bg);
color: var(--text);
font: 14px/1.5 system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
margin: 0;
}
.page {
max-width: 1100px;
margin: 28px auto; /* page margin */
padding: 0 18px;
}
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,.04);
padding: 16px;
}
h2, h3 { margin: 0 0 12px; }
/* Query area layout */
.query-wrap { display: grid; gap: 12px; }
.toolbar {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 12px;
justify-content: space-between; /* left/right split */
}
.toolbar-left { display: flex; align-items: center; gap: 12px; }
.toolbar-right { display: flex; align-items: center; gap: 10px; }
textarea#query {
width: 100%;
min-height: 160px;
resize: vertical;
box-sizing: border-box;
padding: 12px 14px;
border: 1px solid var(--border);
border-radius: 10px;
background: #fff;
font: 13px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.btn {
display: inline-block;
padding: 8px 14px;
border-radius: 10px;
border: 1px solid var(--border);
background: var(--accent);
color: #fff;
cursor: pointer;
}
.btn.secondary {
background: #fff;
color: var(--text);
}
label.small { color: var(--muted); font-size: 13px; user-select: none; }
/* Saved queries */
.query-select {
width: 100%;
box-sizing: border-box;
padding: 10px 12px;
border: 1px solid var(--border);
border-radius: 10px;
background: #fff;
font-size: 14px;
}
/* Results */
.results { margin-top: 16px; }
.results-header {
display: flex; align-items: center; justify-content: space-between;
margin: 4px 0 12px;
}
.results-meta { color: var(--muted); font-size: 13px; }
table {
width: 100%;
border-collapse: collapse;
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
background: #fff;
font-size: 13px;
}
th, td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; }
th { background: #f2f4f7; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.csv-box {
width: 100%; height: 360px; resize: vertical;
white-space: pre; overflow: auto;
font: 12px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
background: #0b1020; color: #e5e7eb;
border: 1px solid #111827; border-radius: 10px; padding: 12px;
}
</style>
<script> <script>
// JavaScript function to populate the textarea with the clicked query // JavaScript function to populate the textarea with the clicked query
function populateQuery(query) { function populateQuery(query) {
document.getElementById('query').value = query; document.getElementById('query').value = query;
} }
function copyCsv(id) {
const ta = document.getElementById(id);
ta.focus();
ta.select();
document.execCommand('copy');
}
</script> </script>
<style>
table { border: 1px solid grey; border-collapse: collapse; }
</style>
</head> </head>
<body> <body>
@ -20,6 +137,7 @@
// Allowed IP address // Allowed IP address
$allowed_ip1 = '47.45.92.162'; $allowed_ip1 = '47.45.92.162';
$ip2 = '207.62.201.30'; $ip2 = '207.62.201.30';
$ip3 = '192.168.1.70';
function get_client_ip() { function get_client_ip() {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
@ -40,48 +158,55 @@
$client_ip = get_client_ip(); $client_ip = get_client_ip();
// Check if the incoming IP address matches the allowed IP // Check if the incoming IP address matches the allowed IP
if ($client_ip !== $allowed_ip1 && $client_ip !== $ip2) { if ($client_ip !== $allowed_ip1 && $client_ip !== $ip2 && $client_ip !== $ip3) {
die("Access denied. Unauthorized IP address."); die("Access denied. Unauthorized IP address.");
} }
?> ?>
<div class="page">
<div class="card">
<h2>Execute Query</h2> <h2>Execute Query</h2>
<form method="post" action="">
<textarea id="query" name="query" rows="4" cols="50" placeholder="Enter your MySQL query here"><?php
echo isset($_POST['query']) ? htmlspecialchars($_POST['query']) : '';
?></textarea><br><br>
<label> <form method="post" action="" class="query-wrap">
<textarea id="query" name="query" placeholder="Enter your MySQL query here"><?php
echo isset($_POST['query']) ? htmlspecialchars($_POST['query']) : '';
?></textarea>
<div class="toolbar">
<div class="toolbar-left">
<label class="small">
<input type="checkbox" name="csv_output" value="1" <?php <input type="checkbox" name="csv_output" value="1" <?php
echo !empty($_POST['csv_output']) ? 'checked' : ''; echo !empty($_POST['csv_output']) ? 'checked' : '';
?>> ?>> CSV output
CSV output
</label> </label>
<br><br> </div>
<button type="submit" name="submit">Execute Query</button> <div class="toolbar-right">
<button type="submit" name="submit" class="btn">Execute Query</button>
</div>
</div>
</form> </form>
</div>
<div class="card" style="margin-top:16px;">
<h3>Available Queries</h3> <h3>Available Queries</h3>
<ul>
<?php <?php
$file = 'queries.txt'; $file = 'queries.txt';
if (file_exists($file)) { if (file_exists($file)) {
$queries = file($file, FILE_IGNORE_NEW_LINES); $queries = file($file, FILE_IGNORE_NEW_LINES);
echo '<select id="querySelect" onchange="populateQuery(this.value)">'; echo '<select id="querySelect" class="query-select" onchange="populateQuery(this.value)">';
echo '<option value="">Select a query...</option>'; echo '<option value="">Select a query...</option>';
foreach ($queries as $line) { foreach ($queries as $line) {
list($label, $query) = explode('|', $line, 2); list($label, $q) = explode('|', $line, 2);
echo '<option value="' . htmlspecialchars($query) . '">' . htmlspecialchars($label) . '</option>'; echo '<option value="' . htmlspecialchars($q) . '">' . htmlspecialchars($label) . '</option>';
} }
echo '</select>'; echo '</select>';
} else { } else {
echo "<p>{$file} file not found.</p>"; echo "<p>{$file} file not found.</p>";
} }
?> ?>
</ul>
<div class="results">
<?php <?php
if (isset($_POST['submit'])) { if (isset($_POST['submit'])) {
// Connection parameters (adjust for your MySQL server) // Connection parameters (adjust for your MySQL server)
@ -179,5 +304,12 @@ if (isset($_POST['submit'])) {
$conn->close(); $conn->close();
} }
?> ?>
</div>
</div>
</div>
<script>
function populateQuery(q) { document.getElementById('query').value = q; }
</script>
</body> </body>
</html> </html>