Compare commits
No commits in common. "42206afc88529951bcf398928657ef34cb4c3c36" and "f86097a00aa349364d0209667cafc5f5d45a2dfe" have entirely different histories.
42206afc88
...
f86097a00a
36
index.html
36
index.html
@ -1,41 +1,26 @@
|
||||
<?php // index.php — Simple ChatGPT-like UI in a single PHP file (Bootstrap 5)
|
||||
require_once __DIR__."/backend.php"; ?>
|
||||
<!doctype html>
|
||||
<html lang="en" data-theme="<?= $theme ?>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>FMF GPT</title>
|
||||
<title>Mini ChatGPT (PHP + Bootstrap)</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/main.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container py-4 chat-wrap">
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark rounded mb-3 px-3">
|
||||
<a class="navbar-brand" href="#">FMF GPT</a>
|
||||
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#topNav" aria-controls="topNav"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="topNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#chat">Chat</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#systemAcc">System</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="d-flex">
|
||||
<button id="resetBtn" class="btn btn-sm btn-outline-light me-2">Reset</button>
|
||||
<button id="themeToggle" class="btn btn-sm btn-outline-light" aria-pressed="false">
|
||||
<div class="d-flex align-items-center mb-3 text-white">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2"><path d="M12 20h9"/><path d="M16 4h-3a2 2 0 0 0-2 2v14"/><path d="M18 14h-8"/><path d="M7 8h8"/></svg>
|
||||
<h1 class="h4 m-0">Mini ChatGPT</h1>
|
||||
<div class="ms-auto">
|
||||
<button id="resetBtn" class="btn btn-sm btn-outline-light">Reset</button>
|
||||
</div>
|
||||
<button id="themeToggle" class="btn btn-sm btn-outline-light ms-2" aria-pressed="false">
|
||||
Toggle Theme
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="accordion mb-3" id="systemAcc">
|
||||
<div class="accordion-item">
|
||||
@ -85,6 +70,7 @@
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<button id="sendBtn" type="submit" class="btn btn-primary">Send</button>
|
||||
<button id="saveSysBtn" type="button" class="btn btn-outline-secondary">Save System Prompt</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
83
main.css
83
main.css
@ -13,7 +13,7 @@
|
||||
|
||||
html[data-theme="light"] {
|
||||
/* Light theme (WhatsApp-like) */
|
||||
--wa-bg: #e9ecef;
|
||||
--wa-bg: #ece5dd;
|
||||
--wa-panel: #ffffff;
|
||||
--wa-incoming: #ffffff; /* assistant (other person) */
|
||||
--wa-outgoing: #dcf8c6; /* user (me) */
|
||||
@ -128,84 +128,3 @@ html[data-theme="light"] #themeToggle.btn-outline-light:hover {
|
||||
background-color: var(--muted);
|
||||
color: #fff;
|
||||
}
|
||||
/* --- Light theme: make the navbar truly light --- */
|
||||
html[data-theme="light"] .navbar {
|
||||
background-color: #f8f9fa !important; /* light bg (like .bg-light) */
|
||||
/* override Bootstrap navbar-dark CSS variables to dark text */
|
||||
--bs-navbar-color: rgba(0,0,0,.65);
|
||||
--bs-navbar-hover-color: rgba(0,0,0,.85);
|
||||
--bs-navbar-active-color: rgba(0,0,0,1);
|
||||
--bs-navbar-brand-color: rgba(0,0,0,.9);
|
||||
--bs-navbar-toggler-border-color: rgba(0,0,0,.15);
|
||||
/* dark “hamburger” icon on light bg */
|
||||
--bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(0,0,0,0.7)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
/* Optional: tighten brand + links for light theme (keeps consistency) */
|
||||
html[data-theme="light"] .navbar .navbar-brand,
|
||||
html[data-theme="light"] .navbar .nav-link {
|
||||
color: var(--bs-navbar-color) !important;
|
||||
}
|
||||
html[data-theme="light"] .navbar .nav-link.active,
|
||||
html[data-theme="light"] .navbar .nav-link:focus,
|
||||
html[data-theme="light"] .navbar .nav-link:hover {
|
||||
color: var(--bs-navbar-hover-color) !important;
|
||||
}
|
||||
|
||||
|
||||
/* --- Dark theme fixes for Bootstrap panels (card + accordion) --- */
|
||||
html:not([data-theme="light"]) .card,
|
||||
html:not([data-theme="light"]) .accordion,
|
||||
html:not([data-theme="light"]) .accordion-item {
|
||||
background-color: var(--wa-panel) !important;
|
||||
color: var(--wa-text) !important;
|
||||
border: 1px solid rgba(255,255,255,0.06) !important;
|
||||
}
|
||||
|
||||
/* Accordion header button */
|
||||
html:not([data-theme="light"]) .accordion-button {
|
||||
background-color: var(--wa-panel) !important;
|
||||
color: var(--wa-text) !important;
|
||||
box-shadow: none !important;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06) !important;
|
||||
}
|
||||
|
||||
/* Collapsed state keeps same colors (Bootstrap otherwise goes light) */
|
||||
html:not([data-theme="light"]) .accordion-button.collapsed {
|
||||
background-color: var(--wa-panel) !important;
|
||||
color: var(--wa-text) !important;
|
||||
border-bottom-color: rgba(255,255,255,0.06) !important;
|
||||
}
|
||||
|
||||
/* Accordion body */
|
||||
html:not([data-theme="light"]) .accordion-body {
|
||||
background-color: var(--wa-panel) !important;
|
||||
color: var(--wa-text) !important;
|
||||
}
|
||||
|
||||
/* The chevron icon (SVG background-image) needs contrast */
|
||||
html:not([data-theme="light"]) .accordion-button::after {
|
||||
filter: invert(1) opacity(0.7);
|
||||
}
|
||||
|
||||
/* Inputs inside the card/accordion */
|
||||
html:not([data-theme="light"]) .form-control {
|
||||
background-color: var(--wa-incoming) !important;
|
||||
color: var(--wa-text) !important;
|
||||
border-color: rgba(255,255,255,0.08) !important;
|
||||
}
|
||||
html:not([data-theme="light"]) .form-control::placeholder {
|
||||
color: var(--wa-muted) !important;
|
||||
}
|
||||
html:not([data-theme="light"]) .form-text {
|
||||
color: var(--wa-muted) !important;
|
||||
}
|
||||
|
||||
/* Outline buttons in dark context */
|
||||
html:not([data-theme="light"]) .btn-outline-light {
|
||||
color: var(--wa-text) !important;
|
||||
border-color: rgba(255,255,255,0.25) !important;
|
||||
}
|
||||
html:not([data-theme="light"]) .btn-outline-light:hover {
|
||||
background-color: rgba(255,255,255,0.12) !important;
|
||||
}
|
||||
|
||||
10
main.js
10
main.js
@ -74,6 +74,16 @@ formEl?.addEventListener('submit', async (e) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Save system prompt
|
||||
qs('#saveSysBtn')?.addEventListener('click', async () => {
|
||||
const message = '';
|
||||
const system = sysInput ? sysInput.value.trim() : '';
|
||||
if (!system) return;
|
||||
// Use a no-op message to persist system prompt? Better: do nothing and let backend save on 'chat'
|
||||
// Here we just show a toast-like confirmation:
|
||||
appendAssistantHtml('<em>System prompt saved for next messages.</em>');
|
||||
});
|
||||
|
||||
// Reset chat
|
||||
resetBtn?.addEventListener('click', async () => {
|
||||
const res = await post('reset', {});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user