create a dashboard, with shadcn sidebar... sidebar header: logo icon + Favosites text sidebar content: 4 icons + links to pages sidebar footer: link to settings page the sidebar is collapsible with icon... when collapsed only shows the icons
a login page
An error occurred: "Error: [@vue/compiler-sfc] <script> and <script setup> must have the same language type."
generate login page
a tailwind v4 time picker input
a login page
Create a fully functional corporate website for Aktin Biotechnology a biotech company specialised in peptide technologies, manifacturing and distrubtion of peptides. Also peptide based formulations.
Create a floating action button frontend vuejs use for chat customer support
Uma pagian de listagem de produtos com as opções de visualição de grid, lista, tabela etc
Uma pagian de listagem de produtos com as opções de visualição de grid, lista, tabela etc
UMa pagina de upload de videos como youtube
its awfull
A Notion-like editor
<template> <div id="app"> <div class="container"> <h1>Real-Time Speech Translation</h1> <div class="controls"> <button @click="startListening" :disabled="isListening"> {{ isListening ? 'Listening...' : 'Start Listening' }} </button> <button @click="stopListening" :disabled="!isListening"> Stop Listening </button> <div class="file-upload"> <input type="file" id="audioFile" ref="fileInput" accept=".mp3,.wav,.ogg" @change="handleFileUpload"> <label for="audioFile">Upload Audio File</label> </div> </div> <div class="status"> <p v-if="statusMessage" :class="statusClass">{{ statusMessage }}</p> <p v-if="errorMessage" class="error">{{ errorMessage }}</p> </div> <div class="transcription-container"> <div class="transcription-box"> <h2>Original (English)</h2> <div class="transcription-content"> <p v-for="(line, index) in originalText" :key="'original-'+index">{{ line }}</p> <p v-if="isProcessing" class="processing-indicator">Processing...</p> </div> </div> <div class="transcription-box"> <h2>Translation (Spanish)</h2> <div class="transcription-content"> <p v-for="(line, index) in translatedText" :key="'translated-'+index">{{ line }}</p> <p v-if="isProcessing" class="processing-indicator">Processing...</p> </div> </div> </div> <div class="metrics-panel" v-if="showMetrics"> <h3>Performance Metrics</h3> <div class="metrics-grid"> <div class="metric-card"> <div class="metric-title">Transcription Time</div> <div class="metric-value">{{ latestMetrics.transcriptionTime }}s</div> <div class="metric-subtitle">Speech-to-Text</div> </div> <div class="metric-card"> <div class="metric-title">Translation Time</div> <div class="metric-value">{{ latestMetrics.translationTime }}s</div> <div class="metric-subtitle">Text-to-Text</div> </div> <div class="metric-card"> <div class="metric-title">Total Processing</div> <div class="metric-value">{{ latestMetrics.totalProcessingTime }}s</div> <div class="metric-subtitle">End-to-End</div> </div> <div class="metric-card"> <div class="metric-title">Average Total</div> <div class="metric-value">{{ averageMetrics.totalProcessingTime }}s</div> <div class="metric-subtitle">Running Average</div> </div> </div> <button @click="toggleMetrics" class="toggle-button">Hide Metrics</button> </div> <button v-else @click="toggleMetrics" class="toggle-button">Show Metrics</button> <div class="debug" v-if="debugMode"> <h3>Debug Information</h3> <pre>Polling Status: {{ pollingActive ? 'Active' : 'Inactive' }}</pre> <pre>Last Poll: {{ lastPollTime }}</pre> <pre>Total Transcriptions: {{ totalTranscriptions }}</pre> <pre>Metrics History: {{ metricsHistory.length }} entries</pre> <button @click="toggleDebug" class="toggle-button">Hide Debug</button> </div> <button v-else @click="toggleDebug" class="toggle-button">Show Debug</button> </div> </div> </template> <script> export default { name: 'App', data() { return { isListening: false, isProcessing: false, pollingActive: false, pollingInterval: null, originalText: [], translatedText: [], statusMessage: '', errorMessage: '', debugMode: true, showMetrics: true, lastPollTime: 'Never', lastSeenIndex: 0, totalTranscriptions: 0, baseUrl: 'http://localhost:5001', metricsHistory: [], latestMetrics: { transcriptionTime: 0, translationTime: 0, totalProcessingTime: 0 }, averageMetrics: { transcriptionTime: 0, translationTime: 0, totalProcessingTime: 0 } } }, computed: { statusClass() { return { 'status-info': !this.errorMessage, 'status-error': this.errorMessage } } }, created() { // Nothing to setup initially }, beforeDestroy() { this.stopPolling(); }, methods: { startPolling() { if (this.pollingInterval) { clearInterval(this.pollingInterval); } this.pollingActive = true; this.pollingInterval = setInterval(() => { this.pollTranscriptions(); }, 1000); // Poll every second }, stopPolling() { if (this.pollingInterval) { clearInterval(this.pollingInterval); this.pollingInterval = null; } this.pollingActive = false; }, async pollTranscriptions() { try { const response = await fetch(`${this.baseUrl}/api/poll_transcriptions?last_seen=${this.lastSeenIndex}`); if (!response.ok) { throw new Error('Failed to poll transcriptions'); } const data = await response.json(); this.lastPollTime = new Date().toLocaleTimeString(); this.totalTranscriptions = data.total_count; // Process new transcriptions for (const item of data.transcriptions) { if (item.error) { this.handleError(item.error); } else { this.handleTranscriptionUpdate(item); // Process metrics if available if (item.metrics) { this.processMetrics(item.metrics); } } } // Update last seen index this.lastSeenIndex = data.total_count; } catch (error) { console.error('Polling error:', error); } }, processMetrics(metrics) { // Store the latest metrics this.latestMetrics = { transcriptionTime: metrics.transcription_time, translationTime: metrics.translation_time, totalProcessingTime: metrics.total_processing_time }; // Add to history this.metricsHistory.push(this.latestMetrics); // Calculate running averages if (this.metricsHistory.length > 0) { const totals = this.metricsHistory.reduce((acc, curr) => { return { transcriptionTime: acc.transcriptionTime + curr.transcriptionTime, translationTime: acc.translationTime + curr.translationTime, totalProcessingTime: acc.totalProcessingTime + curr.totalProcessingTime }; }, { transcriptionTime: 0, translationTime: 0, totalProcessingTime: 0 }); const count = this.metricsHistory.length; this.averageMetrics = { transcriptionTime: (totals.transcriptionTime / count).toFixed(3), translationTime: (totals.translationTime / count).toFixed(3), totalProcessingTime: (totals.totalProcessingTime / count).toFixed(3) }; } // Limit history size to prevent memory issues if (this.metricsHistory.length > 50) { this.metricsHistory = this.metricsHistory.slice(-50); } }, handleTranscriptionUpdate(payload) { this.isProcessing = false; this.originalText.push(payload.original); this.translatedText.push(payload.translation); // Auto-scroll to bottom this.$nextTick(() => { const containers = document.querySelectorAll('.transcription-content'); containers.forEach(container => { container.scrollTop = container.scrollHeight; }); }); }, handleError(error) { console.error('Error:', error); this.errorMessage = error; this.isProcessing = false; // Clear error after 5 seconds setTimeout(() => { this.errorMessage = ''; }, 5000); }, async startListening() { this.isListening = true; this.isProcessing = true; this.statusMessage = 'Starting microphone listening...'; this.lastSeenIndex = 0; // Reset the counter this.metricsHistory = []; // Reset metrics history try { const response = await fetch(`${this.baseUrl}/api/start_listening`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Failed to start listening'); } // Start polling for updates this.startPolling(); this.statusMessage = 'Listening to microphone...'; } catch (error) { this.handleError(error.message); this.isListening = false; this.isProcessing = false; } }, async stopListening() { this.isListening = false; this.statusMessage = 'Stopping microphone listening...'; try { const response = await fetch(`${this.baseUrl}/api/stop_listening`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); if (!response.ok) throw new Error('Failed to stop listening'); // Continue polling for any remaining transcriptions setTimeout(() => { this.stopPolling(); }, 3000); // Poll for 3 more seconds to catch final transcriptions this.statusMessage = 'Microphone stopped'; } catch (error) { this.handleError(error.message); } }, async handleFileUpload(event) { const file = event.target.files[0]; if (!file) return; this.isProcessing = true; this.statusMessage = `Processing file: ${file.name}`; this.lastSeenIndex = 0; // Reset the counter this.metricsHistory = []; // Reset metrics history const formData = new FormData(); formData.append('file', file); try { const response = await fetch(`${this.baseUrl}/api/upload`, { method: 'POST', body: formData }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Failed to upload file'); } const data = await response.json(); // Start polling for file processing updates this.startPolling(); this.statusMessage = data.status === 'processing' ? `Processing file: ${file.name}` : 'File uploaded successfully'; } catch (error) { this.handleError(error.message); } finally { // Reset file input this.$refs.fileInput.value = ''; } }, toggleMetrics() { this.showMetrics = !this.showMetrics; }, toggleDebug() { this.debugMode = !this.debugMode; } } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #2c3e50; margin: 0; padding: 20px; min-height: 100vh; background-color: #f5f7fa; } .container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } h1 { text-align: center; color: #2c3e50; margin-bottom: 30px; } .controls { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; justify-content: center; } button { padding: 10px 15px; background-color: #42b983; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; transition: background-color 0.3s; } button:hover { background-color: #3aa876; } button:disabled { background-color: #cccccc; cursor: not-allowed; } .file-upload { position: relative; overflow: hidden; display: inline-block; } .file-upload input[type="file"] { position: absolute; left: 0; top: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; } .file-upload label { display: inline-block; padding: 10px 15px; background-color: #4285f4; color: white; border-radius: 4px; cursor: pointer; font-size: 16px; transition: background-color 0.3s; } .file-upload label:hover { background-color: #3367d6; } .status { margin: 15px 0; text-align: center; } .status-info { color: #42b983; } .status-error { color: #ff5252; } .error { color: #ff5252; text-align: center; } .transcription-container { display: flex; gap: 20px; margin-top: 20px; } .transcription-box { flex: 1; border: 1px solid #e0e0e0; border-radius: 8px; padding: 15px; background-color: #f9f9f9; } .transcription-box h2 { margin-top: 0; color: #2c3e50; border-bottom: 1px solid #e0e0e0; padding-bottom: 10px; } .transcription-content { height: 300px; overflow-y: auto; padding: 10px; background-color: white; border-radius: 4px; } .transcription-content p { margin: 5px 0; line-height: 1.5; } .processing-indicator { color: #888; font-style: italic; } .metrics-panel { margin-top: 30px; padding: 15px; background-color: #f9f9f9; border-radius: 8px; border: 1px solid #e0e0e0; } .metrics-panel h3 { margin-top: 0; color: #2c3e50; text-align: center; margin-bottom: 15px; } .metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 15px; } .metric-card { background-color: white; border-radius: 8px; padding: 15px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05); text-align: center; } .metric-title { font-weight: bold; color: #4285f4; margin-bottom: 5px; } .metric-value { font-size: 1.8em; font-weight: bold; color: #2c3e50; margin: 5px 0; } .metric-subtitle { font-size: 0.9em; color: #888; } .toggle-button { display: block; margin: 0 auto; background-color: #757575; } .toggle-button:hover { background-color: #616161; } .debug { margin-top: 30px; padding: 15px; background-color: #f0f0f0; border-radius: 8px; font-family: monospace; } .debug h3 { margin-top: 0; } @media (max-width: 768px) { .transcription-container { flex-direction: column; } .metrics-grid { grid-template-columns: 1fr; } } </style> make the ui way better. also add a video component with:Subtitle Overlay & UI Integration: Eventyay Video Integration: Develop a module that overlays interpreted subtitles onto the live video stream from the eventyay video platform. Customization: Provide configurable options (e.g., font size, color, position, language selection, and toggle controls) to optimize subtitle display for diverse event settings.
A treeview component with collapsible items, offset from the left. icons on the left of the items. a vertical line when hovering over an item to see what items are in it