π§Oil Change Tracker
Track oil changes, service history, and maintenance schedules for all your vehicles. Smart reminders based on mileage and time intervals. Works with synthetic, conventional, and blend oils for optimal engine protection.
π€ What Is an Oil Change Tracker?
Think of a personal assistant for your car's health - that's our oil change tracker! This smart tool monitors service history and maintenance schedules for all your vehicles with automatic reminders based on mileage and time intervals. Never miss an oil change again, whether you use synthetic or conventional oil!
π Add Your Vehicle
π― Try Sample Vehicles
π 2024 Honda Civic
Synthetic Oil β’ Normal Driving β’ 15,000 miles
π 2023 Toyota RAV4
Full Synthetic β’ Highway Driving β’ 25,000 miles
π» 2022 Ford F-150
Conventional Oil β’ Severe Conditions β’ 45,000 miles
ποΈ 2024 BMW M3
High Performance Synthetic β’ Track Use β’ 8,000 miles
${new Date(record.date).toLocaleDateString()}
${record.mileage.toLocaleString()} miles - ${record.oilType} oil
${vehicle.name} - Maintenance History
${historyHtml}${content.replace(/\n/g, '
')}`; } chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } // Geminiμ λ©μμ§ μ μ‘ async function sendToGemini() { const input = document.getElementById('geminiInput'); const message = input.value.trim(); if (!message) return; addMessage('user', message); input.value = ''; const loadingMsg = document.createElement('div'); loadingMsg.className = 'message assistant'; loadingMsg.innerHTML = 'β¨ Gemini:
Thinking...'; loadingMsg.id = 'loading-message'; document.getElementById('chatMessages').appendChild(loadingMsg); try { const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${aiModalState.apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: `Context: User is using an Oil Change Tracker tool for vehicle maintenance. Current oil change intervals by type: - Synthetic: 7,500-15,000 miles (normal), 5,000-7,500 (severe) - Blend: 5,000-8,000 miles (normal), 3,000-5,000 (severe) - Conventional: 3,000-5,000 miles (normal), 3,000 (severe) Severe conditions include: city driving, short trips, extreme temperatures, towing, dusty conditions. User question: ${message}` }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 1000 } }) }); const data = await response.json(); document.getElementById('loading-message').remove(); if (data.candidates && data.candidates[0] && data.candidates[0].content) { const reply = data.candidates[0].content.parts[0].text; addMessage('assistant', reply); } else { addMessage('assistant', 'Sorry, I could not generate a response. Please try again.'); } } catch (error) { document.getElementById('loading-message')?.remove(); if (error.message.includes('API key')) { addMessage('error', 'Invalid API key. Please check your API key and try again.'); showAPIKeySetup(); } else { addMessage('error', 'Failed to connect to Gemini. Please check your internet connection and try again.'); } } } // ========== EVENT LISTENERS ========== document.addEventListener('DOMContentLoaded', function() { // Initialize vehicles display renderVehicles(); // AI λ²νΌ μ΄λ²€νΈ document.getElementById('aiBtn').addEventListener('click', openAIModal); // λͺ¨λ¬ μΈλΆ ν΄λ¦μ λ«κΈ° document.getElementById('aiModal').addEventListener('click', function(e) { if (e.target === this) { closeAIModal(); } }); // μν° ν€ μ§μ document.addEventListener('keydown', function(e) { if (e.key === 'Enter') { const geminiInput = document.getElementById('geminiInput'); if (document.activeElement === geminiInput) { sendToGemini(); } } if (e.key === 'Escape') { closeAIModal(); } }); // μ΄κΈ° API ν€ μν μ λ°μ΄νΈ updateAPIKeyStatus(); updateCurrentYear(); updateToolCount(); }); // ========== DYNAMIC TOOL COUNT ========== async function updateToolCount() { try { const response = await fetch('/api/tool-count.php'); const data = await response.json(); document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${data.count}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${data.count}+ ${suffix}`; }); } catch (error) { const fallbackCount = 333; document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${fallbackCount}+ free online tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${fallbackCount}+ ${suffix}`; }); } } function updateCurrentYear() { const currentYear = new Date().getFullYear(); document.querySelectorAll('.current-year').forEach(el => { el.textContent = currentYear; }); } // ========== ANALYTICS ========== window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXX'); trackEvent('page_view', { tool: TOOL_CONFIG.name, category: TOOL_CONFIG.category });