realtimecursor
Version:
Real-time collaboration system with cursor tracking and approval workflow
330 lines (315 loc) • 12.4 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RealtimeCursor Dashboard</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #f8f9fa;
}
.sidebar {
background-color: #212529;
color: white;
min-height: 100vh;
padding-top: 20px;
}
.sidebar .nav-link {
color: rgba(255,255,255,.75);
padding: 10px 20px;
margin: 5px 0;
border-radius: 5px;
}
.sidebar .nav-link:hover {
color: white;
background-color: rgba(255,255,255,.1);
}
.sidebar .nav-link.active {
color: white;
background-color: #0d6efd;
}
.main-content {
padding: 20px;
}
.card {
margin-bottom: 20px;
border: none;
box-shadow: 0 2px 4px rgba(0,0,0,.1);
}
.api-key {
font-family: monospace;
background-color: #f8f9fa;
padding: 10px;
border-radius: 5px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<!-- Sidebar -->
<div class="col-md-3 col-lg-2 sidebar">
<h5 class="px-3 mb-4">RealtimeCursor</h5>
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="#">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Projects</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">API Keys</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Usage</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Billing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Settings</a>
</li>
<li class="nav-item mt-5">
<a class="nav-link" href="#">Logout</a>
</li>
</ul>
</div>
<!-- Main Content -->
<div class="col-md-9 col-lg-10 main-content">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Dashboard</h2>
<div>
<span class="badge bg-primary me-2">Pro Plan</span>
<button class="btn btn-outline-primary">Upgrade</button>
</div>
</div>
<!-- Overview Cards -->
<div class="row mb-4">
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Active Projects</h5>
<p class="display-4">3</p>
<p class="text-muted">2 active collaborations</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Active Users</h5>
<p class="display-4">12</p>
<p class="text-muted">+3 from last week</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">API Usage</h5>
<p class="display-4">78%</p>
<p class="text-muted">of monthly limit</p>
</div>
</div>
</div>
</div>
<!-- API Keys Section -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">API Keys</h5>
<button class="btn btn-primary btn-sm" id="createApiKey">Create New API Key</button>
</div>
<div class="card-body">
<div class="api-key-list">
<div class="api-key-item mb-4">
<div class="d-flex justify-content-between align-items-center mb-2">
<h6>Production API Key</h6>
<span class="badge bg-success">Active</span>
</div>
<div class="api-key">sk_live_abcdefghijklmnopqrstuvwxyz123456</div>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">Created on May 15, 2023</small>
<button class="btn btn-sm btn-outline-danger">Revoke</button>
</div>
</div>
<div class="api-key-item mb-4">
<div class="d-flex justify-content-between align-items-center mb-2">
<h6>Development API Key</h6>
<span class="badge bg-success">Active</span>
</div>
<div class="api-key">sk_test_abcdefghijklmnopqrstuvwxyz123456</div>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">Created on June 2, 2023</small>
<button class="btn btn-sm btn-outline-danger">Revoke</button>
</div>
</div>
<div class="api-key-item mb-4">
<div class="d-flex justify-content-between align-items-center mb-2">
<h6>Legacy API Key</h6>
<span class="badge bg-secondary">Inactive</span>
</div>
<div class="api-key">sk_old_abcdefghijklmnopqrstuvwxyz123456</div>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">Created on January 10, 2023</small>
<button class="btn btn-sm btn-outline-secondary" disabled>Revoked</button>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Activity -->
<div class="card mt-4">
<div class="card-header">
<h5 class="mb-0">Recent Activity</h5>
</div>
<div class="card-body">
<table class="table">
<thead>
<tr>
<th>Project</th>
<th>Event</th>
<th>Users</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr>
<td>Marketing Website</td>
<td>Collaboration Session</td>
<td>5 users</td>
<td>10 minutes ago</td>
</tr>
<tr>
<td>Product Dashboard</td>
<td>Content Update</td>
<td>2 users</td>
<td>1 hour ago</td>
</tr>
<tr>
<td>Documentation</td>
<td>Collaboration Session</td>
<td>3 users</td>
<td>3 hours ago</td>
</tr>
<tr>
<td>Marketing Website</td>
<td>Content Update</td>
<td>1 user</td>
<td>Yesterday</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Create API Key Modal -->
<div class="modal fade" id="apiKeyModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create New API Key</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="apiKeyForm">
<div class="mb-3">
<label for="keyName" class="form-label">Key Name</label>
<input type="text" class="form-control" id="keyName" placeholder="e.g., Production, Development">
</div>
<div class="mb-3">
<label for="keyType" class="form-label">Key Type</label>
<select class="form-select" id="keyType">
<option value="live">Live</option>
<option value="test">Test</option>
</select>
</div>
<div class="mb-3">
<label for="keyPermissions" class="form-label">Permissions</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="permRead" checked>
<label class="form-check-label" for="permRead">Read</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="permWrite" checked>
<label class="form-check-label" for="permWrite">Write</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="permAdmin">
<label class="form-check-label" for="permAdmin">Admin</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="createKeyBtn">Create Key</button>
</div>
</div>
</div>
</div>
<!-- New API Key Modal -->
<div class="modal fade" id="newKeyModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Your New API Key</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="alert alert-warning">
<strong>Important:</strong> This is the only time your API key will be displayed. Please copy it now and store it securely.
</div>
<div class="api-key mb-3" id="newApiKey">sk_live_abcdefghijklmnopqrstuvwxyz123456</div>
<button class="btn btn-sm btn-outline-primary" id="copyKeyBtn">Copy to Clipboard</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">I've Copied My Key</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Simple dashboard functionality
document.addEventListener('DOMContentLoaded', function() {
const createApiKeyBtn = document.getElementById('createApiKey');
const createKeyBtn = document.getElementById('createKeyBtn');
const copyKeyBtn = document.getElementById('copyKeyBtn');
// Show create API key modal
createApiKeyBtn.addEventListener('click', function() {
const apiKeyModal = new bootstrap.Modal(document.getElementById('apiKeyModal'));
apiKeyModal.show();
});
// Create key button click
createKeyBtn.addEventListener('click', function() {
const apiKeyModal = bootstrap.Modal.getInstance(document.getElementById('apiKeyModal'));
apiKeyModal.hide();
// Generate a random API key for demo purposes
const newKey = 'sk_' +
(document.getElementById('keyType').value === 'live' ? 'live_' : 'test_') +
Array.from(crypto.getRandomValues(new Uint8Array(16)))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
document.getElementById('newApiKey').textContent = newKey;
const newKeyModal = new bootstrap.Modal(document.getElementById('newKeyModal'));
newKeyModal.show();
});
// Copy key button click
copyKeyBtn.addEventListener('click', function() {
const keyText = document.getElementById('newApiKey').textContent;
navigator.clipboard.writeText(keyText).then(function() {
copyKeyBtn.textContent = 'Copied!';
setTimeout(() => {
copyKeyBtn.textContent = 'Copy to Clipboard';
}, 2000);
});
});
});
</script>
</body>
</html>