### 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 = '

You have not generated any API keys yet.

'; return; } let tableHtml = ` `; keys.forEach(key => { const createdDate = key.created_at ? new Date(key.created_at).toLocaleDateString() : 'N/A'; const lastUsedDate = key.last_used && key.last_used !== 'None' ? new Date(key.last_used).toLocaleString() : 'Never'; const status = key.is_active ? 'Active' : 'Inactive'; tableHtml += ` `; }); tableHtml += `
Label Key Prefix Created Last Used Status Action
${escapeHtml(key.label || 'No Label')} ${escapeHtml(key.key_prefix || 'N/A')}... ${createdDate} ${lastUsedDate} ${status} ${key.is_active ? `` : ''}
`; apiKeysListDiv.innerHTML = tableHtml; } ``` -------------------------------- ### Firebase Auth State Listener for Nav Link Source: https://quicktranscript.app/api-docs Initializes Firebase with provided configuration and sets up an authentication state listener. It dynamically shows or hides a navigation link based on the user's login status, ensuring UI consistency with authentication state. ```javascript import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-app.js"; import { getAuth, onAuthStateChanged } from "https://www.gstatic.com/firebasejs/11.6.0/firebase-auth.js"; 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 auth; if (firebaseConfig && firebaseConfig.apiKey) { try { const app = initializeApp(firebaseConfig); auth = getAuth(app); console.log("Firebase initialized on API Docs page."); onAuthStateChanged(auth, (user) => { const apiKeysNavLink = document.getElementById('nav-api-keys-link'); if (apiKeysNavLink) { apiKeysNavLink.style.display = user ? 'inline-block' : 'none'; } }); } catch (error) { console.error("Firebase initialization failed on API Docs page:", error); } } else { console.warn("Firebase config missing on API Docs page."); } ``` -------------------------------- ### Header and Navigation Styling Source: https://quicktranscript.app/api-keys Styles the page header, including alignment of the main title and a back link. It also defines styles for links and hover effects, ensuring a clean and navigable interface. ```css .page-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 15px; border-bottom: 1px solid #eee; margin-bottom: 20px; } .page-header h1 { margin: 0; font-size: 1.8rem; color: #333; } .back-link { color: #4285F4; text-decoration: none; font-weight: 500; } .back-link:hover { text-decoration: underline; } ``` -------------------------------- ### Sign-in Modal Styles Source: https://quicktranscript.app/ Styles for a modal dialog used for sign-in or user authentication. Includes overlay, content box, header, message area, and action buttons. Supports primary and secondary button styles. ```css .modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 1000; } .modal-content { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 30px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); max-width: 400px; width: 90%; text-align: center; } .modal-header { margin-bottom: 20px; } .modal-title { font-size: 1.5rem; font-weight: bold; color: #333; margin: 0 0 10px 0; } .modal-message { color: #666; margin-bottom: 25px; line-height: 1.5; } .modal-actions { display: flex; gap: 15px; justify-content: center; } .modal-btn { padding: 12px 24px; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; transition: all 0.2s; } .modal-btn-primary { background: #4285F4; color: white; } .modal-btn-primary:hover { background: #3367d6; } .modal-btn-secondary { background: #f1f3f4; color: #333; } .modal-btn-secondary:hover { background: #e8eaed; } ``` -------------------------------- ### New API Key Display and Copy Button Source: https://quicktranscript.app/api-keys Styles the area where a newly generated API key is displayed, including success messages, code formatting for the key, and a copy button. It handles initial hidden state and visual feedback. ```css #new-key-display { display: none; background-color: #e9f7ec; border: 1px solid #c3e6cb; border-radius: 5px; padding: 15px; margin-bottom: 20px; position: relative; } #new-key-display p { margin: 0 0 10px 0; font-weight: 500; color: #155724; } #new-key-display code { background-color: #d4edda; padding: 5px 8px; border-radius: 3px; word-break: break-all; display: inline-block; margin-right: 10px; } #new-key-display .copy-key-btn { background-color: #28a745; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; font-size: 0.9em; margin-left: 10px; vertical-align: middle; } #new-key-display .copy-key-btn:hover { background-color: #218838; } ``` -------------------------------- ### Google Tag Manager Initialization Source: https://quicktranscript.app/ JavaScript code snippet to initialize Google Tag Manager (GTM) on the webpage. This script loads the GTM container and enables website analytics, tracking, and tag management capabilities. ```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'); ``` -------------------------------- ### API Key Management Section Styles Source: https://quicktranscript.app/api-keys Styles the main section for API key management, including its background, border, and spacing. It also styles the heading for this section. ```css #api-keys-section { margin-top: 20px; padding: 25px; background-color: #f8f9fa; border-radius: 10px; border: 1px solid #e9ecef; } #api-keys-section h3 { margin-top: 0; margin-bottom: 20px; color: #343a40; text-align: center; } ``` -------------------------------- ### API Key Management Functions (JavaScript) Source: https://quicktranscript.app/api-keys Provides core functionalities for creating, displaying, copying, and revoking API keys. It includes error handling, user feedback, and interaction with backend APIs via fetch requests. Dependencies include DOM elements for UI updates and Firebase authentication for user context. ```javascript let createKeyForm, apiKeyLabelInput, newKeyDisplay, newKeyValue, newKeyLabelElement, copyKeyButton, apiKeysListDiv, apiKeyStatusDiv, createKeyIndicator, authStatusDiv, logoutButton; // --- API Key Operations --- async function createApiKey(event) { event.preventDefault(); if (!apiKeyLabelInput || !createKeyIndicator || !apiKeyStatusDiv || !submitButton) return; const label = apiKeyLabelInput.value.trim(); if (!label) { apiKeyStatusDiv.innerHTML = "
Label cannot be empty.
"; return; } createKeyIndicator.style.display = 'block'; if(submitButton) submitButton.disabled = true; apiKeyStatusDiv.innerHTML = ''; // Clear previous messages try { const token = await getAccessToken(); // Assumes getAccessToken() is defined elsewhere if (!token) { apiKeyStatusDiv.innerHTML = "
Authentication error. Please refresh or log in again.
"; return; } const formData = new FormData(); formData.append('label', label); // API Call: POST /api/keys const response = await fetch('/api/keys', { method: 'POST', headers: { 'Authorization': `Bearer ${token}` }, body: formData }); const result = await response.json(); if (response.ok) { displayNewKey(result); apiKeyLabelInput.value = ''; fetchApiKeys(); // Assumes fetchApiKeys() is defined elsewhere to refresh the list } else { apiKeyStatusDiv.innerHTML = `
Error: ${result.detail || 'Failed to create key'}
`; } } catch (error) { console.error('Error creating API key:', error); apiKeyStatusDiv.innerHTML = "
An unexpected error occurred.
"; } finally { createKeyIndicator.style.display = 'none'; if(submitButton) submitButton.disabled = false; } } function displayNewKey(keyData) { if (!newKeyDisplay || !newKeyValue || !newKeyLabelElement || !copyKeyButton) return; newKeyValue.textContent = keyData.api_key; newKeyLabelElement.textContent = keyData.label; newKeyDisplay.style.display = 'block'; newKeyDisplay.scrollIntoView({ behavior: 'smooth', block: 'center' }); copyKeyButton.textContent = 'Copy'; copyKeyButton.disabled = false; } async function copyApiKeyToClipboard() { if (!newKeyValue || !copyKeyButton) return; try { await navigator.clipboard.writeText(newKeyValue.textContent); copyKeyButton.textContent = 'Copied!'; copyKeyButton.disabled = true; setTimeout(() => { copyKeyButton.textContent = 'Copy'; copyKeyButton.disabled = false; }, 2000); } catch (err) { console.error('Failed to copy API key: ', err); alert('Failed to copy key. Please copy it manually.'); } } async function revokeApiKey(keyId) { if (!keyId || !auth || !auth.currentUser) return; if (!confirm("Are you sure you want to revoke this API key? This action cannot be undone.")) { return; } apiKeyStatusDiv.innerHTML = 'Revoking key...'; try { const token = await getAccessToken(); if (!token) { apiKeyStatusDiv.innerHTML = "
Authentication error. Please refresh or log in again.
"; return; } // API Call: DELETE /api/keys/{keyId} const response = await fetch(`/api/keys/${keyId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { apiKeyStatusDiv.innerHTML = "
API Key revoked successfully.
"; fetchApiKeys(); // Refresh list } else { const errorData = await response.json(); apiKeyStatusDiv.innerHTML = `
Error: ${errorData.detail || 'Failed to revoke key'}
`; } } catch (error) { console.error('Error revoking API key:', error); apiKeyStatusDiv.innerHTML = "
An unexpected error occurred.
"; } 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 = `
Please enter a label for the key.
`; return; } createKeyIndicator.style.display = 'inline'; apiKeyStatusDiv.innerHTML = ''; const submitButton = createKeyForm.querySelector('button[type="submit"]'); if(submitButton) submitButton.disabled = true; try { const token = await getAccessToken(); if (!token) { 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 = '

Loading keys...

'; try { const token = await getAccessToken(); if (!token) { apiKeysListDiv.innerHTML = '

Authentication error. Please refresh or log in again.

'; return; } const response = await fetch('/api/keys', { headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { const keys = await response.json(); renderApiKeysList(keys); } else { const errorData = await response.json(); console.error('Failed to fetch API keys:', errorData); apiKeysListDiv.innerHTML = `

Failed to load keys: ${errorData.detail || response.statusText}

`; } } catch (error) { console.error('Error fetching API keys:', error); apiKeysListDiv.innerHTML = '

An error occurred while loading keys.

'; } } ``` -------------------------------- ### API Key Generation Form Styling Source: https://quicktranscript.app/api-keys Styles the form used for generating new API keys, including input fields, labels, and buttons. It supports responsive layout with wrapping for form elements. ```css #create-key-form { display: flex; gap: 15px; margin-bottom: 25px; align-items: flex-end; flex-wrap: wrap; } #create-key-form .form-group { flex-grow: 1; margin-bottom: 0; } #create-key-form label { display: block; margin-bottom: 5px; font-weight: 500; color: #495057; } #create-key-form input[type="text"] { width: 100%; padding: 8px 12px; border: 1px solid #ced4da; border-radius: 4px; box-sizing: border-box; } #create-key-form .submit-button.small { padding: 9px 18px; white-space: nowrap; background-color: #4285F4; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: 500; transition: background-color 0.2s; } #create-key-form .submit-button.small:hover { background-color: #3367D6; } #create-key-form .htmx-indicator { font-style: italic; color: #666; margin-left: 10px; display: none; } ``` -------------------------------- ### UI Styles for Media Transcriber Source: https://quicktranscript.app/ CSS rules for styling the web interface, including tab navigation, input fields, and specific elements for YouTube and file URL inputs. These styles enhance user experience and visual feedback. ```css .her-section { display: block; } /* Shown when logged in */ .footer-link { color: #4285F4; text-decoration: none; margin: 0 10px; } /* Tab Styles */ .upload-tabs { display: flex; margin-bottom: 20px; border-bottom: 2px solid #e0e0e0; } .tab-button { background: none; border: none; padding: 12px 24px; cursor: pointer; font-size: 16px; color: #666; border-bottom: 3px solid transparent; transition: all 0.3s ease; flex: 1; } .tab-button:hover { color: #4285F4; background-color: #f8f9fa; } .tab-button.active { color: #4285F4; border-bottom-color: #4285F4; font-weight: 500; } .tab-content { display: none; } .tab-content.active { display: block; } /* YouTube-specific styles */ .youtube-notice { background-color: #fff3cd; border: 1px solid #ffeaa7; border-radius: 4px; padding: 8px 12px; margin: 10px 0; font-size: 0.9rem; } #youtubeInput { width: 100%; padding: 10px; border: 2px solid #ddd; border-radius: 4px; font-size: 16px; } #urlInput { width: 100%; padding: 10px; border: 2px solid #ddd; border-radius: 4px; font-size: 16px; } #youtubeInput:focus { border-color: #4285F4; outline: none; } #youtubeInput:valid { border-color: #28a745; } #youtubeInput:invalid:not(:placeholder-shown) { border-color: #dc3545; } #youtube-display { min-height: 40px; display: flex; align-items: center; } /* File URL tab specific styles */ .provider-info { margin-top: 8px; padding: 8px 12px; background: #e3f2fd; border: 1px solid #bbdefb; border-radius: 4px; font-size: 0.9em; } .provider-label { color: #1976d2; font-weight: 500; } .provider-name { color: #0d47a1; font-weight: bold; margin-left: 5px; } .url-help { margin-top: 15px; padding: 15px; background: #f5f5f5; border-radius: 6px; border-left: 4px solid #4285f4; } .url-help p { margin: 0 0 10px 0; color: #333; } .url-help ul { margin: 10px 0; padding-left: 20px; } .url-help li { margin: 5px 0; color: #555; } .url-help small { color: #666; font-style: italic; } #url-display { min-height: 40px; display: flex; align-items: center; } /* Disabled submit button visual */ .submit-button[disabled] { opacity: 0.6; cursor: not-allowed; } ``` -------------------------------- ### Initialize Google Tag Manager Source: https://quicktranscript.app/privacy This script initializes Google Tag Manager for website analytics and tracking. It is designed to be placed in the head of the HTML document to ensure timely loading of tags. ```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'); ``` -------------------------------- ### JavaScript UI Update on Auth Status Source: https://quicktranscript.app/api-keys This JavaScript code fragment illustrates updating the user interface based on the outcome of an authentication process. It handles both successful authentication, by calling updateUI with user data, and failed initialization, by calling updateUI with null. ```javascript }); updateUI(user); }); } else { // Handle case where auth failed to initialize updateUI(null); } }); ``` -------------------------------- ### API Endpoint: /api/keys Source: https://quicktranscript.app/api-keys This API endpoint is used for managing user API keys. It supports fetching a list of existing keys and creating new ones. Authentication is required via a Bearer token (Firebase ID token). ```APIDOC GET /api/keys Description: Retrieves a list of API keys associated with the authenticated user. Authentication: Required (Bearer Token - Firebase ID Token) Parameters: - Authorization: Bearer (string, required) Responses: - 200 OK: Content-Type: application/json Body: [ { "key_id": "string", "label": "string", "key_prefix": "string", "created_at": "datetime", "last_used": "datetime | null", "is_active": "boolean" } ] - 401 Unauthorized: If the authentication token is missing or invalid. - 500 Internal Server Error: If there's a server-side issue. POST /api/keys Description: Creates a new API key for the authenticated user. Authentication: Required (Bearer Token - Firebase ID Token) Parameters: - Authorization: Bearer (string, required) - Request Body (JSON): { "label": "string" // User-defined label for the API key (required) } Responses: - 201 Created: Content-Type: application/json Body: { "key_id": "string", "label": "string", "key": "string", // The newly generated API key "key_prefix": "string", "created_at": "datetime", "last_used": null, "is_active": true } - 400 Bad Request: If the request body is invalid (e.g., missing label). - 401 Unauthorized: If the authentication token is missing or invalid. - 500 Internal Server Error: If there's a server-side issue. DELETE /api/keys/{key_id} Description: Revokes (deactivates) an existing API key. Authentication: Required (Bearer Token - Firebase ID Token) Parameters: - Authorization: Bearer (string, required) - key_id: The unique identifier of the API key to revoke (string, path parameter, required) Responses: - 200 OK: Content-Type: application/json Body: { "message": "API key revoked successfully." } - 401 Unauthorized: If the authentication token is missing or invalid. - 404 Not Found: If the specified key_id does not exist or does not belong to the user. - 500 Internal Server Error: If there's a server-side issue. ``` -------------------------------- ### Transcription Job Management Source: https://quicktranscript.app/api-docs Endpoints for submitting new transcription jobs, checking the status of existing jobs, and retrieving a list of completed transcriptions. These are crucial for processing audio files and integrating with workflows. ```APIDOC Create Transcription Job: Method: POST Endpoint: /api/transcriptions Description: Submits a new audio file for transcription. Input: (Details on file upload and parameters like language, format, etc. would be here) Output: (Details on response, e.g., task ID for status checking) Check Transcription Status: Method: GET Endpoint: /api/transcriptions/{task_id} Description: Monitors the progress and status of a specific transcription job. Parameters: task_id: The unique identifier for the transcription task. Output: (Details on status, progress percentage, and final result when available) Get Completed Transcriptions: Method: GET Endpoint: /api/transcriptions/completed Description: Polls for new transcriptions that have been successfully completed. Output: (List of completed transcription jobs, potentially with metadata) ``` -------------------------------- ### Voucher Section Styling Source: https://quicktranscript.app/ Styles for the voucher redemption section, including a container with background and border, a heading, and a form for voucher input. Also styles status messages for success or errors. ```css /* Voucher section styles */ .voucher-container { background-color: #f0f8ff; /* AliceBlue */ padding: 20px; border-radius: 8px; margin-top: 20px; margin-bottom: 30px; border: 1px solid #d6eaff; } .voucher-container h3 { margin-top: 0; margin-bottom: 15px; color: #333; text-align: center; } #voucher-form { display: flex; align-items: center; justify-content: center; gap: 15px; flex-wrap: wrap; /* Allow wrapping on smaller screens */ } #voucher-form .form-group { margin-bottom: 0; /* Remove default bottom margin */ display: flex; /* Align label and input */ align-items: center; gap: 8px; } #voucher-form label { margin-bottom: 0; /* Override default label margin */ font-weight: 500; } #voucher-form input[type="text"] { padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; min-width: 180px; /* Ensure input has some width */ } .submit-button.small { padding: 8px 16px; /* Smaller padding */ font-size: 0.9rem; } .voucher-status { margin-top: 15px; text-align: center; font-weight: 500; } .voucher-status .success-message { color: #28a745; /* Green */ background-color: #e9f7ec; padding: 8px; border-radius: 4px; border: 1px solid #c3e6cb; display: inline-block; /* Fit content */ } .voucher-status .error-container { /* Reuse error style */ color: #dc3545; /* Red */ background-color: #f8d7da; padding: 8px; border-radius: 4px; border: 1px solid #f5c6cb; display: inline-block; /* Fit content */ } #voucher-indicator { font-style: italic; color: #555; } /* Show voucher section only when logged in */ #voucher-section { display: none; /* Hidden by default */ } body.user-logged-in #voucher-section { display: block; /* Show when logged in */ } ``` -------------------------------- ### Conditional Visibility Styles Source: https://quicktranscript.app/ Styles that control the visibility of UI elements based on application state, such as user login status or form processing. Includes hiding/showing buy buttons and login prompts. ```css /* Hide landing section when the form is being processed */ body.upload-in-progress .landing-section { display: none; } /* Credit package button/prompt visibility */ .buy-package-btn { display: none; /* Hide buy buttons by default */ } .login-to-purchase-prompt { display: block; /* Show login prompt by default */ font-size: 0.9em; color: #666; margin-top: 15px; } body.user-logged-in .buy-package-btn { display: block; /* Show buy buttons when user is logged in */ } body.user-logged-in .login-to-purchase-prompt { display: none; /* Hide login prompt when user is logged in */ } ``` -------------------------------- ### SEO Content Styling Source: https://quicktranscript.app/ Basic styling for SEO-related content sections, including headings and paragraph text, to ensure readability and structure. ```css .seo-content { color: #666; line-height: 1.8; margin-top: 50px; } .seo-content h2, .seo-content h3 { color: #2c3e50; margin-top: 30px; margin-bottom: 15px; } ``` -------------------------------- ### API Keys List Table Styling Source: https://quicktranscript.app/api-keys Styles the table used to display existing API keys, including headers, cells, and borders. It also styles specific elements like revoke buttons and inactive status indicators. ```css #api-keys-list table { width: 100%; border-collapse: collapse; margin-top: 15px; } #api-keys-list th, #api-keys-list td { border: 1px solid #dee2e6; padding: 10px 12px; text-align: left; vertical-align: middle; } #api-keys-list th { background-color: #e9ecef; font-weight: 600; color: #495057; } #api-keys-list td { color: #212529; } #api-keys-list .revoke-key-btn { background-color: #dc3545; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; font-size: 0.9em; } #api-keys-list .revoke-key-btn:hover { background-color: #c82333; } #api-keys-list .key-status-inactive { font-style: italic; color: #6c757d; } ``` -------------------------------- ### Status Message Styling Source: https://quicktranscript.app/api-keys Defines shared styles for status messages, such as success or error notifications, used within the API key management section. This includes padding, borders, and color schemes for different message types. ```css .api-key-status { margin-top: 10px; text-align: center; font-weight: 500; } .api-key-status .error-container, .api-key-status .success-message { padding: 8px 12px; border-radius: 4px; border: 1px solid transparent; display: inline-block; margin-bottom: 15px; } .api-key-status .error-container { color: #721c24; background-color: #f8d7da; border-color: #f5c6cb; } .api-key-status .success-message { color: #155724; background-color: #d4edda; border-color: #c3e6cb; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.