### Firebase Initialization and Auth Setup
Source: https://quicktranscript.app/api-keys
Initializes Firebase with provided configuration and sets up authentication. Handles potential initialization errors and updates the UI accordingly. Requires Firebase configuration object and Firebase SDKs.
```javascript
import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-app.js";
import { getAuth, onAuthStateChanged, signOut, getIdToken as firebaseGetIdToken } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-auth.js";
// Firebase config passed from backend
const firebaseConfig = {
"apiKey": "AIzaSyBPC\_gWUl-d6Inq4Kv8uCSQYS1ZdBlDbmY",
"appId": "1:172535120003:web:a3f56cd30b647ecab3dbb6",
"authDomain": "videodigestai.firebaseapp.com",
"measurementId": "G-DX4T3CPZ6Z",
"messagingSenderId": "172535120003",
"projectId": "videodigestai",
"storageBucket": "videodigestai.firebasestorage.app"
};
let app, auth;
if (firebaseConfig && firebaseConfig.apiKey) {
try {
app = initializeApp(firebaseConfig);
auth = getAuth(app);
console.log("Firebase initialized successfully on API Keys page.");
} catch (error) {
console.error("Firebase initialization failed:", error);
document.getElementById('auth-status').textContent = 'Error initializing authentication.';
}
} else {
console.error("Firebase configuration is missing or incomplete.");
document.getElementById('auth-status').textContent = 'Authentication configuration error.';
}
```
--------------------------------
### Get Firebase Access Token
Source: https://quicktranscript.app/api-keys
Retrieves the current user's Firebase ID token, which is used for authenticating API requests. Returns null if the user is not authenticated or an error occurs during token retrieval. Handles token expiration by attempting to sign out the user.
```javascript
async function getAccessToken() {
if (!auth || !auth.currentUser) {
console.warn("Cannot get access token: No authenticated user.");
return null;
}
try {
const token = await firebaseGetIdToken(auth.currentUser, false); // Get potentially cached token
return token;
} catch (error) {
console.error("Error getting access token:", error);
// Attempt sign out if token fetch fails badly
if (error.code === 'auth/user-token-expired' || error.code === 'auth/invalid-user-token') {
await signOutUser();
}
return null;
}
}
```
--------------------------------
### Credit Packages Styling
Source: https://quicktranscript.app/
Styles for displaying credit packages in a grid layout. Includes styling for individual package cards, names, prices, descriptions, and a buy button. Also handles hover effects for interactivity.
```css
.credit-packages {
margin-top: 30px;
padding: 20px;
background: #f5f9ff;
border-radius: 10px;
border: 1px solid #dbe9f9;
}
.credit-packages h3 {
text-align: center;
margin-top: 0;
margin-bottom: 20px;
color: #2c3e50;
}
.packages-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 20px;
}
.package-card {
background: white;
border-radius: 8px;
padding: 25px;
text-align: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
position: relative;
transition: transform 0.3s, box-shadow 0.3s;
}
.package-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
}
.package-name {
font-size: 1.5rem;
font-weight: bold;
color: #2c3e50;
margin-bottom: 5px;
}
.credit-amount {
font-size: 2.5rem;
font-weight: bold;
color: #4285F4;
margin: 15px 0;
}
.credits-received {
font-size: 0.9rem;
font-weight: normal;
color: #666;
display: block;
margin-top: 5px;
}
.package-price {
font-size: 1.8rem;
color: #27ae60;
font-weight: bold;
margin-bottom: 10px;
}
.credit-description {
color: #666;
font-size: 0.9rem;
margin-bottom: 15px;
font-style: italic;
}
.savings-badge {
position: absolute;
top: -10px;
right: -10px;
background: #e74c3c;
color: white;
padding: 5px 10px;
border-radius: 20px;
font-weight: bold;
font-size: 0.9rem;
}
.buy-package-btn {
background: #4285F4;
color: white;
border: none;
width: 100%;
padding: 12px;
border-radius: 6px;
font-weight: bold;
font-size: 1rem;
cursor: pointer;
transition: background 0.2s;
}
.buy-package-btn:hover {
background: #3367d6;
}
```
--------------------------------
### Basic Body and Container Styling
Source: https://quicktranscript.app/api-keys
Provides basic styling for the page body, including font, background color, and a centered container with padding and shadow. This sets up the overall visual layout for the application.
```css
body {
font-family: sans-serif;
background-color: #f4f7f6;
margin: 0;
padding: 0;
}
.container {
max-width: 900px;
margin: 20px auto;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
```
--------------------------------
### Payment and Credit Management
Source: https://quicktranscript.app/api-docs
Endpoints related to managing user credits and payment packages. These allow users to view available plans and initiate checkout processes.
```APIDOC
View Payment Packages:
Method: GET
Endpoint: /payments/packages
Description: Retrieves information about available credit packages and pricing.
Output:
(Details on different credit bundles and their costs)
Create Checkout Session:
Method: POST
Endpoint: /payments/create-checkout
Description: Initiates a payment session for purchasing credits.
Input:
(Details on package selection and user information)
Output:
(Information needed to redirect the user to a payment gateway)
```
--------------------------------
### API Authentication and Test Endpoint
Source: https://quicktranscript.app/api-docs
Details on how to authenticate API requests using an API Key and a test endpoint to verify authentication. API keys are passed in the 'X-API-Key' header.
```APIDOC
API Authentication:
Requires an API key passed in the 'X-API-Key' HTTP header.
Generate keys on the [API Keys page](/api-keys) (login required).
Test Endpoint:
Method: GET
Endpoint: /api/auth/test
Description: Verifies if the provided API key is working correctly.
Headers:
X-API-Key: Your unique API key
Example (curl):
curl -X GET "https://quicktranscript.app/api/auth/test" -H "X-API-Key: vdz_your_api_key"
```
--------------------------------
### Firebase Configuration Object
Source: https://quicktranscript.app/
Provides the global Firebase configuration object, including API keys, project ID, and other necessary details for initializing Firebase services in the application. This object is made available on the window object for client-side access.
```javascript
window.firebaseConfig = {
"apiKey": "AIzaSyBPC\_gWUl-d6Inq4Kv8uCSQYS1ZdBlDbmY",
"appId": "1:172535120003:web:a3f56cd30b647ecab3dbb6",
"authDomain": "videodigestai.firebaseapp.com",
"measurementId": "G-DX4T3CPZ6Z",
"messagingSenderId": "172535120003",
"projectId": "videodigestai",
"storageBucket": "videodigestai.firebasestorage.app"
};
```
--------------------------------
### Google Tag Manager Initialization
Source: https://quicktranscript.app/api-keys
Initializes Google Tag Manager (GTM) by dynamically creating a script tag and appending it to the document. This is a standard method for integrating GTM into a web page to track analytics and events.
```javascript
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-W928F3WF');
```
--------------------------------
### Render API Keys List in Table
Source: https://quicktranscript.app/api-keys
Renders a list of API keys into an HTML table. Displays key label, prefix, creation date, last used date, status (Active/Inactive), and a revoke button for active keys. Handles cases with no keys or missing data.
```javascript
function renderApiKeysList(keys) {
if (!apiKeysListDiv) return;
if (!keys || keys.length === 0) {
apiKeysListDiv.innerHTML = '
";
} finally {
setTimeout(() => {
if (apiKeyStatusDiv && apiKeyStatusDiv.innerHTML.includes('Revoking key...')) {
apiKeyStatusDiv.innerHTML = '';
}
}, 3000);
}
}
// --- Authentication Logic ---
async function signOutUser() {
if (!auth) return;
try {
await signOut(auth); // Assumes signOut is imported from firebase/auth
window.location.href = '/'; // Redirect to home page after sign out
} catch (error) {
console.error("Sign Out Error:", error);
alert(`Sign-out failed: ${error.message}`);
}
}
function updateUI(user) {
if (!authStatusDiv || !logoutButton) return;
if (user) {
authStatusDiv.textContent = `Logged in as: ${user.email}`;
logoutButton.style.display = 'inline-block';
fetchApiKeys(); // Fetch API keys now that user is confirmed
} else {
authStatusDiv.textContent = 'Redirecting to login...';
logoutButton.style.display = 'none';
window.location.href = '/'; // Redirect to home
}
}
// --- Initialization ---
document.addEventListener('DOMContentLoaded', () => {
// Get DOM elements
createKeyForm = document.getElementById('create-key-form');
apiKeyLabelInput = document.getElementById('apiKeyLabel');
newKeyDisplay = document.getElementById('new-key-display');
newKeyValue = document.getElementById('new-key-value');
newKeyLabelElement = document.getElementById('new-key-label');
copyKeyButton = document.getElementById('copy-key-button');
apiKeysListDiv = document.getElementById('api-keys-list');
apiKeyStatusDiv = document.getElementById('api-key-status');
createKeyIndicator = document.getElementById('create-key-indicator');
authStatusDiv = document.getElementById('auth-status');
logoutButton = document.getElementById('logout-button');
// Add event listeners
if (createKeyForm) createKeyForm.addEventListener('submit', createApiKey);
if (copyKeyButton) copyKeyButton.addEventListener('click', copyApiKeyToClipboard);
if (logoutButton) logoutButton.addEventListener('click', signOutUser);
if (apiKeysListDiv) {
apiKeysListDiv.addEventListener('click', function(event) {
if (event.target.classList.contains('revoke-key-btn')) {
const keyId = event.target.getAttribute('data-key-id');
if (keyId) {
revokeApiKey(keyId);
}
}
});
}
// Set up auth state listener
if (auth) {
onAuthStateChanged(auth, (user) => { // Assumes onAuthStateChanged is imported from firebase/auth
console.log("Auth state changed on API Keys page:", user ? `User: ${user.email}` : "No user");
updateUI(user);
});
}
});
// Placeholder for assumed functions/variables
// const auth = getAuth(); // Example: Initialize Firebase Auth
// async function getAccessToken() { return 'fake-token'; } // Example: Function to get auth token
// function fetchApiKeys() { console.log('Fetching API keys...'); } // Example: Function to fetch and display keys
// const submitButton = document.getElementById('submit-key-button'); // Example: Assuming a submit button exists
```
--------------------------------
### Create New API Key
Source: https://quicktranscript.app/api-keys
Handles the submission of the API key creation form. It prevents default submission, validates the label, and sends a request to the backend to create a new API key. Shows loading indicators and disables the submit button during the process.
```javascript
async function createApiKey(event) {
event.preventDefault();
if (!auth || !auth.currentUser || !createKeyForm || !apiKeyLabelInput || !createKeyIndicator || !apiKeyStatusDiv) return;
const label = apiKeyLabelInput.value.trim();
if (!label) {
apiKeyStatusDiv.innerHTML = `
Authentication er
```
--------------------------------
### Purchase Credits Function Placeholder
Source: https://quicktranscript.app/
A placeholder function for handling the purchase of credit packages. This function is intended to be implemented or handled by an authentication module, making it available globally for user interactions.
```javascript
window.purchaseCredits = function(packageId) {
// This will be handled by the auth module
};
```
--------------------------------
### Fetch API Keys from Backend
Source: https://quicktranscript.app/api-keys
Fetches the list of API keys associated with the authenticated user from the '/api/keys' endpoint. Requires a valid Firebase ID token for authorization. Displays loading states and handles API response errors.
```javascript
async function fetchApiKeys() {
if (!auth || !auth.currentUser) {
if (apiKeysListDiv) apiKeysListDiv.innerHTML = '
Authentication required.
';
return;
}
if (!apiKeysListDiv) return;
apiKeysListDiv.innerHTML = '