prompt creation & detail page

This commit is contained in:
Isabelle Nachbaur 2026-04-07 23:46:17 +02:00
parent d2d5c0c66c
commit 02b8a75947
15 changed files with 1112 additions and 1 deletions

155
css/create.css Normal file
View File

@ -0,0 +1,155 @@
/* Create page - Form for publishing new AI prompts */
/* Full width layout */
.layout > div[style*="flex:1"] {
margin: 0 !important;
max-width: 100% !important;
padding: 0 !important;
width: 100% !important;
}
.create-main {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 20px 32px;
background: transparent;
}
.create-container {
max-width: 800px;
width: 100%;
background: #fff;
border-radius: 18px;
box-shadow: 0 2px 8px rgba(59,130,246,0.06);
padding: 32px;
transition: box-shadow 0.2s;
}
.create-container:hover {
box-shadow: 0 8px 20px rgba(59,130,246,0.12);
}
/* Header */
.create-header {
text-align: center;
margin-bottom: 32px;
}
.create-header h1 {
font-size: 2rem;
font-weight: 700;
margin-bottom: 8px;
}
.create-header p {
color: #64748b;
font-size: 1rem;
}
/* Form */
.create-form {
display: flex;
flex-direction: column;
gap: 24px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
font-weight: 600;
font-size: 0.95rem;
}
.form-group input,
.form-group textarea,
.form-group select {
width: 100%;
padding: 12px 14px;
border: 1px solid #dbe2ea;
border-radius: 12px;
font-size: 0.95rem;
font-family: inherit;
background: #ffffff;
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
outline: none;
border-color: #7c3aed;
box-shadow: 0 0 0 3px rgba(124,58,237,0.1);
}
.form-hint {
font-size: 0.75rem;
color: #64748b;
}
/* Pricing toggle */
.pricing-group .pricing-toggle {
display: flex;
gap: 12px;
margin-bottom: 12px;
}
.price-option {
background: #f1f5f9;
border: none;
padding: 8px 20px;
border-radius: 30px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
color: #475569;
}
.price-option.active {
background: var(--gradient);
color: white;
}
#priceField {
margin-top: 8px;
}
/* Buttons */
.form-actions {
display: flex;
gap: 16px;
margin-top: 8px;
}
.submit-btn, .cancel-btn {
flex: 1;
border: none;
padding: 12px;
border-radius: 12px;
font-weight: 700;
font-size: 1rem;
cursor: pointer;
transition: opacity 0.2s;
}
.submit-btn {
background: var(--gradient);
color: white;
}
.cancel-btn {
background: #f1f5f9;
color: #475569;
}
.submit-btn:hover, .cancel-btn:hover {
opacity: 0.85;
}
/* Responsive */
@media (max-width: 768px) {
.create-container {
padding: 24px;
}
.create-header h1 {
font-size: 1.6rem;
}
}
@media (max-width: 480px) {
.create-container {
padding: 20px;
}
.form-actions {
flex-direction: column;
}
}

217
css/post-detail.css Normal file
View File

@ -0,0 +1,217 @@
/* Post Detail page - Full prompt view, rating, example output, unlock button */
/* Full width layout */
.layout > div[style*="flex:1"] {
margin: 0 !important;
max-width: 100% !important;
padding: 0 !important;
width: 100% !important;
}
.post-detail-main {
flex: 1;
display: flex;
justify-content: center;
padding: 20px 32px;
background: transparent;
}
.post-detail-container {
max-width: 900px;
width: 100%;
background: #fff;
border-radius: 18px;
box-shadow: 0 2px 8px rgba(59,130,246,0.06);
padding: 32px;
transition: box-shadow 0.2s;
}
.post-detail-container:hover {
box-shadow: 0 8px 20px rgba(59,130,246,0.12);
}
/* Header */
.post-header {
margin-bottom: 28px;
border-bottom: 1px solid #eef2f7;
padding-bottom: 20px;
}
.post-title {
font-size: 2rem;
font-weight: 800;
margin-bottom: 12px;
}
.post-meta {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 12px;
}
.category {
background: #f1f5f9;
padding: 4px 12px;
border-radius: 30px;
font-size: 0.8rem;
font-weight: 600;
color: #3b82f6;
}
.updated {
font-size: 0.85rem;
color: #64748b;
}
.post-stats {
display: flex;
gap: 20px;
font-size: 0.9rem;
color: #475569;
}
.post-stats i {
margin-right: 6px;
}
/* Prompt Section */
.prompt-section {
margin-bottom: 28px;
}
.prompt-section h2 {
font-size: 1.3rem;
font-weight: 700;
margin-bottom: 16px;
letter-spacing: -0.3px;
}
.prompt-content {
background: #f8fafc;
padding: 20px;
border-radius: 16px;
font-size: 1rem;
line-height: 1.5;
color: #1e293b;
}
.prompt-content ul {
margin-top: 12px;
padding-left: 20px;
}
.prompt-content li {
margin-bottom: 6px;
}
/* Rating & Like */
.rating-section {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 16px;
margin-bottom: 28px;
padding-bottom: 20px;
border-bottom: 1px solid #eef2f7;
}
.rating-stars {
display: flex;
gap: 20px;
font-size: 1.1rem;
font-weight: 700;
}
.rating-stars i {
color: #f59e0b;
margin-right: 6px;
}
.like-btn {
background: none;
border: 1px solid #e2e8f0;
padding: 8px 18px;
border-radius: 30px;
font-size: 0.9rem;
font-weight: 600;
color: #475569;
cursor: pointer;
transition: all 0.2s;
}
.like-btn:hover {
background: #f1f5f9;
border-color: #cbd5e1;
}
.like-btn i {
margin-right: 6px;
}
/* Example Output Section */
.example-section {
margin-bottom: 32px;
}
.example-section h2 {
font-size: 1.3rem;
font-weight: 700;
margin-bottom: 16px;
}
.example-content {
background: #ffffff;
border: 1px solid #eef2f7;
border-radius: 16px;
padding: 20px;
}
.example-content h3 {
font-size: 1rem;
font-weight: 700;
margin-bottom: 12px;
color: #3b82f6;
}
.example-output-text {
font-size: 0.95rem;
line-height: 1.5;
color: #334155;
}
.example-output-text p {
margin-bottom: 12px;
}
.example-image {
margin-top: 16px;
}
.example-image img {
max-width: 100%;
border-radius: 12px;
}
/* Unlock Section */
.unlock-section {
text-align: center;
margin-top: 16px;
}
.unlock-btn {
background: var(--gradient);
border: none;
padding: 14px 32px;
border-radius: 40px;
font-size: 1.1rem;
font-weight: 700;
color: white;
cursor: pointer;
transition: opacity 0.2s;
}
.unlock-btn:hover {
opacity: 0.9;
}
/* Responsive */
@media (max-width: 768px) {
.post-detail-main {
padding: 16px;
}
.post-detail-container {
padding: 24px;
}
.post-title {
font-size: 1.6rem;
}
}
@media (max-width: 480px) {
.post-detail-container {
padding: 20px;
}
.rating-section {
flex-direction: column;
align-items: flex-start;
}
.prompt-content {
padding: 16px;
}
}

184
css/settings.css Normal file
View File

@ -0,0 +1,184 @@
/* Settings page - tabs, form styling */
.layout > div[style*="flex:1"] {
margin: 0 !important;
max-width: 100% !important;
padding: 0 !important;
width: 100% !important;
}
.settings-main {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 20px 32px;
background: transparent;
}
.settings-container {
max-width: 700px;
width: 100%;
background: #fff;
border-radius: 18px;
box-shadow: 0 2px 8px rgba(59,130,246,0.06);
padding: 32px;
}
.settings-header {
text-align: center;
margin-bottom: 28px;
}
.settings-header h1 {
font-size: 1.8rem;
font-weight: 700;
margin-bottom: 8px;
}
.settings-header p {
color: #64748b;
font-size: 0.95rem;
}
/* Tabs */
.settings-tabs {
display: flex;
gap: 8px;
border-bottom: 1px solid #eef2f7;
margin-bottom: 28px;
}
.tab-btn {
background: transparent;
border: none;
padding: 10px 20px;
font-size: 1rem;
font-weight: 600;
color: #64748b;
cursor: pointer;
border-bottom: 2px solid transparent;
transition: all 0.2s;
}
.tab-btn.active {
color: #3b82f6;
border-bottom-color: #3b82f6;
}
.tab-btn:hover:not(.active) {
color: #334155;
}
/* Tab content */
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
/* Form elements */
.settings-form {
display: flex;
flex-direction: column;
gap: 24px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
font-weight: 600;
font-size: 0.95rem;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 12px 14px;
border: 1px solid #dbe2ea;
border-radius: 12px;
font-size: 0.95rem;
font-family: inherit;
}
.form-group input:focus,
.form-group textarea:focus {
outline: none;
border-color: #7c3aed;
box-shadow: 0 0 0 3px rgba(124,58,237,0.1);
}
.checkbox-label {
display: flex;
align-items: center;
gap: 10px;
font-weight: normal;
cursor: pointer;
}
.checkbox-label input {
width: auto;
margin: 0;
}
/* Avatar upload */
.avatar-upload {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.settings-avatar {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
}
.upload-btn {
background: #f1f5f9;
border: none;
padding: 8px 16px;
border-radius: 30px;
font-weight: 600;
cursor: pointer;
}
.upload-btn:hover {
background: #e2e8f0;
}
/* Save button */
.save-btn {
background: var(--gradient);
color: white;
border: none;
padding: 12px;
border-radius: 12px;
font-weight: 700;
font-size: 1rem;
cursor: pointer;
width: 100%;
transition: opacity 0.2s;
}
.save-btn:hover {
opacity: 0.85;
}
/* Responsive */
@media (max-width: 768px) {
.settings-container {
padding: 24px;
}
.settings-header h1 {
font-size: 1.5rem;
}
}
@media (max-width: 480px) {
.settings-container {
padding: 20px;
}
.settings-tabs {
gap: 4px;
}
.tab-btn {
padding: 8px 12px;
font-size: 0.9rem;
}
.avatar-upload {
flex-direction: column;
align-items: flex-start;
}
}

View File

@ -47,6 +47,32 @@
font-weight: 400; font-weight: 400;
} }
/* Icons and avatar container */
.topbar-actions {
display: flex;
align-items: center;
gap: 16px;
}
.topbar-icon-btn {
background: transparent;
border: none;
font-size: 1.4rem;
color: #475569;
cursor: pointer;
padding: 8px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: background 0.2s, color 0.2s;
}
.topbar-icon-btn:hover {
background: #f1f5f9;
color: #3b82f6;
}
.topbar-avatar-btn { .topbar-avatar-btn {
border: none; border: none;
background: transparent; background: transparent;
@ -80,6 +106,13 @@
width: 40px; width: 40px;
height: 40px; height: 40px;
} }
.topbar-icon-btn {
font-size: 1.2rem;
padding: 6px;
}
.topbar-actions {
gap: 8px;
}
} }
@media (max-width: 480px) { @media (max-width: 480px) {

View File

@ -1,3 +1,6 @@
<!-- OnlyPrompt - Chats page:
- Direct messaging interface with conversation list and active chat window -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>

View File

@ -1,3 +1,6 @@
<!-- OnlyPrompt - Marketplace page:
- Browse and filter AI prompts with buy/view details buttons and pricing -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>

181
html/create.html Normal file
View File

@ -0,0 +1,181 @@
<!-- OnlyPrompt - Create Prompt page:
- Form to publish new AI prompts with title, description, category, content, example output, image upload, and pricing toggle -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OnlyPrompt - Create New Prompt</title>
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/base.css">
<link rel="stylesheet" href="../css/sidebar.css">
<link rel="stylesheet" href="../css/login.css">
<link rel="stylesheet" href="../css/topbar.css">
<link rel="stylesheet" href="../css/create.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
</head>
<body>
<div class="layout" style="display: flex; min-height: 100vh; background: var(--bg);">
<div id="sidebar-container"></div>
<div style="flex:1; display: flex; flex-direction: column;">
<div id="topbar-container"></div>
<main class="create-main">
<div class="create-container">
<div class="create-header">
<h1>Create AI Prompt</h1>
<p>Design and save custom prompts for your AI workflows.</p>
</div>
<form id="createPromptForm" class="create-form" enctype="multipart/form-data">
<!-- Title -->
<div class="form-group">
<label for="title">Prompt Title *</label>
<input type="text" id="title" name="title" placeholder="e.g., Write an inspiring startup story about innovation" required>
</div>
<!-- Description -->
<div class="form-group">
<label for="description">Description *</label>
<textarea id="description" name="description" rows="2" placeholder="Draft a narrative about a small team overcoming challenges to launch a groundbreaking app" required></textarea>
</div>
<!-- Category -->
<div class="form-group">
<label for="category">Category *</label>
<select id="category" name="category" required>
<option value="creative-writing">Creative Writing</option>
<option value="coding">Coding</option>
<option value="art">Art</option>
<option value="marketing">Marketing</option>
<option value="video">Video</option>
<option value="data">Data</option>
</select>
</div>
<!-- Prompt Content -->
<div class="form-group">
<label for="promptContent">Prompt Content *</label>
<textarea id="promptContent" name="promptContent" rows="6" placeholder="Write your prompt instructions here..." required></textarea>
<small class="form-hint">Use clear, step-by-step instructions for the AI.</small>
</div>
<!-- Example Output (Text) -->
<div class="form-group">
<label for="exampleOutput">Example Output (optional)</label>
<textarea id="exampleOutput" name="exampleOutput" rows="4" placeholder="Show an example of what the AI might generate..."></textarea>
</div>
<!-- Example Image (optional) -->
<div class="form-group">
<label for="exampleImage">Example Image (optional)</label>
<input type="file" id="exampleImage" name="exampleImage" accept="image/png, image/jpeg, image/jpg">
<small class="form-hint">Upload a PNG or JPG preview will appear below.</small>
<div id="imagePreview" style="margin-top: 10px; display: none;">
<img id="previewImg" src="#" alt="Preview" style="max-width: 100%; max-height: 200px; border-radius: 12px;">
</div>
</div>
<!-- Pricing (with toggle) -->
<div class="form-group pricing-group">
<label>Pricing</label>
<div class="pricing-toggle">
<button type="button" id="freeBtn" class="price-option active">Free</button>
<button type="button" id="paidBtn" class="price-option">Paid</button>
</div>
<div id="priceField" style="display: none;">
<input type="number" id="price" name="price" step="0.01" min="0" placeholder="Price in USD (e.g., 19.99)">
</div>
<small class="form-hint">You can set a price later or keep it free.</small>
</div>
<!-- Submit Button -->
<div class="form-actions">
<button type="submit" class="submit-btn">Publish Prompt</button>
<button type="button" class="cancel-btn">Cancel</button>
</div>
</form>
</div>
</main>
</div>
</div>
<script>
// Toggle between free and paid
const freeBtn = document.getElementById('freeBtn');
const paidBtn = document.getElementById('paidBtn');
const priceField = document.getElementById('priceField');
const priceInput = document.getElementById('price');
freeBtn.addEventListener('click', () => {
freeBtn.classList.add('active');
paidBtn.classList.remove('active');
priceField.style.display = 'none';
priceInput.removeAttribute('required');
});
paidBtn.addEventListener('click', () => {
paidBtn.classList.add('active');
freeBtn.classList.remove('active');
priceField.style.display = 'block';
priceInput.setAttribute('required', 'required');
});
// Image preview for example image
const imageInput = document.getElementById('exampleImage');
const imagePreview = document.getElementById('imagePreview');
const previewImg = document.getElementById('previewImg');
if (imageInput) {
imageInput.addEventListener('change', function(event) {
const file = event.target.files[0];
if (file && (file.type === 'image/png' || file.type === 'image/jpeg' || file.type === 'image/jpg')) {
const reader = new FileReader();
reader.onload = function(e) {
previewImg.src = e.target.result;
imagePreview.style.display = 'block';
};
reader.readAsDataURL(file);
} else {
imagePreview.style.display = 'none';
previewImg.src = '#';
if (file) alert('Please upload a PNG or JPG image.');
}
});
}
// Handle form submission (demo only)
document.getElementById('createPromptForm').addEventListener('submit', (e) => {
e.preventDefault();
alert('Prompt published! (Demo)');
// Here you would normally send data to a backend (including the image file)
});
// Cancel button (go back)
document.querySelector('.cancel-btn').addEventListener('click', () => {
window.history.back();
});
// Fetch sidebar and topbar
fetch('../html/sidebar.html')
.then(r => r.text())
.then(data => {
document.getElementById('sidebar-container').innerHTML = data;
// Remove active class from all sidebar links
document.querySelectorAll('#sidebar-container .sidebar a').forEach(link => {
link.classList.remove('active');
});
// Optionally set active on "Create New" if it exists, otherwise keep none
const createLink = document.querySelector('#sidebar-container a[href="create.html"]');
if (createLink) createLink.classList.add('active');
});
fetch('../html/topbar.html')
.then(r => r.text())
.then(data => document.getElementById('topbar-container').innerHTML = data);
</script>
</body>
</html>

View File

@ -1,3 +1,6 @@
<!-- OnlyPrompt - Feed page:
- Social media style post feed with likes, comments, saves, and share actions (following/foryou tabs) -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>

View File

@ -1,3 +1,7 @@
<!-- OnlyPrompt - Login page:
- User authentication form with email/password
- Show/hide password toggle -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">

View File

@ -1,3 +1,6 @@
<!-- OnlyPrompt - Marketplace page:
- Browse and filter AI prompts with buy/view details buttons and pricing -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>

114
html/post-detail.html Normal file
View File

@ -0,0 +1,114 @@
<!-- OnlyPrompt - Settings page:
- User preferences with tabs for profile, security, and notifications -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OnlyPrompt - Post Detail</title>
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/base.css">
<link rel="stylesheet" href="../css/sidebar.css">
<link rel="stylesheet" href="../css/login.css">
<link rel="stylesheet" href="../css/topbar.css">
<link rel="stylesheet" href="../css/post-detail.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
</head>
<body>
<div class="layout" style="display: flex; min-height: 100vh; background: var(--bg);">
<div id="sidebar-container"></div>
<div style="flex:1; display: flex; flex-direction: column;">
<div id="topbar-container"></div>
<main class="post-detail-main">
<div class="post-detail-container">
<!-- Header -->
<div class="post-header">
<h1 class="post-title">Marketing Guru: Campaign Strategist</h1>
<div class="post-meta">
<span class="category">Marketing</span>
<span class="category">Business</span>
<span class="category">Copywriting</span>
<span class="updated">Updated: Oct 26, 2023</span>
</div>
<div class="post-stats">
<span><i class="bi bi-bookmark-star"></i> 2,109 Saves</span>
<span><i class="bi bi-eye"></i> 14.5k Views</span>
</div>
</div>
<!-- Prompt Content Section -->
<div class="prompt-section">
<h2>PROMPT</h2>
<div class="prompt-content">
<p>You are an expert marketing strategist and copywriter. I will provide a product name, target audience, and key benefits. Your goal is to create a comprehensive marketing campaign plan, including:</p>
<ul>
<li>Campaign objectives</li>
<li>Target Audience: [User Input]</li>
<li>Expected Output: A detailed marketing plan with channel strategy, messaging, and sample copy</li>
<li>Budget considerations and KPIs</li>
</ul>
</div>
</div>
<!-- Rating & Like -->
<div class="rating-section">
<div class="rating-stars">
<span><i class="bi bi-star-fill"></i> 4.9</span>
<span><i class="bi bi-star-fill"></i> 4.8 (241 Ratings)</span>
</div>
<button class="like-btn"><i class="bi bi-heart"></i> Like (212)</button>
</div>
<!-- Example Output Section -->
<div class="example-section">
<h2>EXAMPLE OUTPUT</h2>
<div class="example-content">
<h3>Generated Strategy 16px</h3>
<div class="example-output-text">
<p><strong>Output: EcoWare Campaign</strong></p>
<p><strong>Campaign Overview</strong><br>Target Persona: Sarah Jenkins, 28, Eco-conscious</p>
<p><strong>Key Messaging</strong><br>Channel Strategy<br>Sample Copy<br>Social<br>Email</p>
</div>
<!-- Optional example image (if uploaded in create) -->
<div class="example-image" style="display: none;">
<img src="#" alt="Example Output Image">
</div>
</div>
</div>
<!-- Unlock / Buy Section -->
<div class="unlock-section">
<button class="unlock-btn">Unlock Full Prompt • $19.99</button>
</div>
</div>
</main>
</div>
</div>
<script>
// Fetch sidebar and topbar
fetch('../html/sidebar.html')
.then(r => r.text())
.then(data => {
document.getElementById('sidebar-container').innerHTML = data;
// Remove active class from all sidebar links
document.querySelectorAll('#sidebar-container .sidebar a').forEach(link => {
link.classList.remove('active');
});
// Optionally set active on a relevant link (e.g., Marketplace)
const marketplaceLink = document.querySelector('#sidebar-container a[href="marketplace.html"]');
if (marketplaceLink) marketplaceLink.classList.add('active');
});
fetch('../html/topbar.html')
.then(r => r.text())
.then(data => document.getElementById('topbar-container').innerHTML = data);
</script>
</body>
</html>

View File

@ -1,3 +1,6 @@
<!-- OnlyPrompt - Profile page:
- User profile display with avatar, bio, stats, and prompt cards (personal prompts) -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>

197
html/settings.html Normal file
View File

@ -0,0 +1,197 @@
<!-- OnlyPrompt - Settings page:
- User preferences with tabs for profile, security, and notifications -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OnlyPrompt - Settings</title>
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/base.css">
<link rel="stylesheet" href="../css/sidebar.css">
<link rel="stylesheet" href="../css/login.css">
<link rel="stylesheet" href="../css/topbar.css">
<link rel="stylesheet" href="../css/settings.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
</head>
<body>
<div class="layout" style="display: flex; min-height: 100vh; background: var(--bg);">
<div id="sidebar-container"></div>
<div style="flex:1; display: flex; flex-direction: column;">
<div id="topbar-container"></div>
<main class="settings-main">
<div class="settings-container">
<div class="settings-header">
<h1>Settings</h1>
<p>Manage your account preferences and profile.</p>
</div>
<!-- Tabs -->
<div class="settings-tabs">
<button class="tab-btn active" data-tab="profile">Profile</button>
<button class="tab-btn" data-tab="security">Security</button>
<button class="tab-btn" data-tab="notifications">Notifications</button>
</div>
<!-- Tab Content: Profile -->
<div id="profileTab" class="tab-content active">
<form class="settings-form">
<div class="form-group">
<label for="avatar">Profile Picture</label>
<div class="avatar-upload">
<img src="../images/content/cat.png" alt="Avatar" class="settings-avatar" id="avatarPreview">
<input type="file" id="avatarUpload" accept="image/png, image/jpeg">
<button type="button" class="upload-btn">Upload new</button>
</div>
</div>
<div class="form-group">
<label for="displayName">Display Name</label>
<input type="text" id="displayName" placeholder="Sunny the Cat">
</div>
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" placeholder="@username">
</div>
<div class="form-group">
<label for="bio">Bio</label>
<textarea id="bio" rows="3" placeholder="Tell us about yourself..."></textarea>
</div>
<div class="form-group">
<label for="email">Email Address</label>
<input type="email" id="email" placeholder="your@email.com">
</div>
<div class="form-actions">
<button type="submit" class="save-btn">Save Changes</button>
</div>
</form>
</div>
<!-- Tab Content: Security -->
<div id="securityTab" class="tab-content">
<form class="settings-form">
<div class="form-group">
<label for="currentPw">Current Password</label>
<input type="password" id="currentPw" placeholder="Enter current password">
</div>
<div class="form-group">
<label for="newPw">New Password</label>
<input type="password" id="newPw" placeholder="Enter new password">
</div>
<div class="form-group">
<label for="confirmPw">Confirm New Password</label>
<input type="password" id="confirmPw" placeholder="Confirm new password">
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="twoFactor"> Enable Two-Factor Authentication
</label>
</div>
<div class="form-actions">
<button type="submit" class="save-btn">Update Password</button>
</div>
</form>
</div>
<!-- Tab Content: Notifications (erweitert) -->
<div id="notificationsTab" class="tab-content">
<form class="settings-form">
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="notifLikes"> When someone likes my prompt
</label>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="notifSaves"> When someone saves my prompt
</label>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="notifMessages"> New message received
</label>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="notifFollowers"> New follower
</label>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="notifPurchases"> Prompt purchase (paid prompts)
</label>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" id="notifComments"> Comment on my prompt
</label>
</div>
<div class="form-actions">
<button type="submit" class="save-btn">Save Preferences</button>
</div>
</form>
</div>
</div>
</main>
</div>
</div>
<script>
// Tab switching
const tabBtns = document.querySelectorAll('.tab-btn');
const tabContents = document.querySelectorAll('.tab-content');
tabBtns.forEach(btn => {
btn.addEventListener('click', () => {
const tabId = btn.getAttribute('data-tab');
tabBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
tabContents.forEach(content => content.classList.remove('active'));
document.getElementById(`${tabId}Tab`).classList.add('active');
});
});
// Avatar preview (simple)
const avatarUpload = document.getElementById('avatarUpload');
const avatarPreview = document.getElementById('avatarPreview');
if (avatarUpload) {
avatarUpload.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file && (file.type === 'image/png' || file.type === 'image/jpeg')) {
const reader = new FileReader();
reader.onload = function(ev) {
avatarPreview.src = ev.target.result;
};
reader.readAsDataURL(file);
}
});
}
// Demo form submits for all forms
document.querySelectorAll('.settings-form').forEach(form => {
form.addEventListener('submit', (e) => {
e.preventDefault();
alert('Settings saved (demo)');
});
});
// Fetch sidebar and topbar
fetch('../html/sidebar.html')
.then(r => r.text())
.then(data => {
document.getElementById('sidebar-container').innerHTML = data;
document.querySelectorAll('#sidebar-container .sidebar a').forEach(link => {
link.classList.remove('active');
});
const settingsLink = document.querySelector('#sidebar-container a[href="settings.html"]');
if (settingsLink) settingsLink.classList.add('active');
});
fetch('../html/topbar.html')
.then(r => r.text())
.then(data => document.getElementById('topbar-container').innerHTML = data);
</script>
</body>
</html>

View File

@ -1,3 +1,6 @@
<!-- OnlyPrompt - Signup page:
- Registration form with email, password, full name, username, and terms acceptance -->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">

View File

@ -1,7 +1,7 @@
<!-- <!--
Reusable topbar for OnlyPrompt Reusable topbar for OnlyPrompt
- Search in the middle - Search in the middle
- small action icons - small chat & notification icons
- profile avatar on the right - profile avatar on the right
--> -->
@ -11,6 +11,14 @@
<input type="text" placeholder="Search"> <input type="text" placeholder="Search">
</div> </div>
<div class="topbar-actions">
<button class="topbar-icon-btn" aria-label="Notifications">
<i class="bi bi-bell"></i>
</button>
<button class="topbar-icon-btn" aria-label="Messages">
<i class="bi bi-chat-dots"></i>
</button>
<!-- Profile avatar on the right (must be changed with backend) --> <!-- Profile avatar on the right (must be changed with backend) -->
<button class="topbar-avatar-btn" aria-label="Profile"> <button class="topbar-avatar-btn" aria-label="Profile">
<img src="../images/content/cat.png" alt="Profile Picture" class="topbar-avatar"> <img src="../images/content/cat.png" alt="Profile Picture" class="topbar-avatar">