Download executable_code/templates/index.html from Novadotgg/Cropiee: direct link, hf CLI and curl.
- Browser
- Download file 23.4 kB
-
https://huggingface.co/spaces/Novadotgg/Cropiee/resolve/main/executable_code/templates/index.html
- Command line
-
hf download hf://spaces/Novadotgg/Cropiee/executable_code/templates/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Novadotgg/Cropiee/resolve/main/executable_code/templates/index.html
23.4 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Cropiee | Agricultural Intelligence</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap" rel="stylesheet"> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <style> | |
| :root { | |
| /* Light Mode Tokens */ | |
| --primary: #1a4d2e; | |
| --primary-light: #4f6f52; | |
| --accent: #ff9f1c; | |
| --bg-gradient: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%); | |
| --glass: rgba(255, 255, 255, 0.7); | |
| --glass-border: rgba(255, 255, 255, 0.3); | |
| --text-main: #1b4332; | |
| --text-muted: #52796f; | |
| --shadow: 0 12px 40px rgba(0, 0, 0, 0.08); | |
| --bot-bubble: #ffffff; | |
| --user-bubble: linear-gradient(135deg, #2d6a4f 0%, #1a4d2e 100%); | |
| --input-bg: #f8fbf8; | |
| } | |
| [data-theme="dark"] { | |
| /* Dark Mode "Eco-Dark" Tokens */ | |
| --primary: #95d5b2; | |
| --primary-light: #74c69d; | |
| --accent: #ff9f1c; | |
| --bg-solid: #081c15; | |
| --bg-gradient: linear-gradient(135deg, #081c15 0%, #1b4332 100%); | |
| --glass: rgba(27, 67, 50, 0.95); | |
| --glass-border: rgba(255, 255, 255, 0.1); | |
| --text-main: #d8f3dc; | |
| --text-muted: #b7e4c7; | |
| --shadow: 0 12px 40px rgba(0, 0, 0, 0.6); | |
| --bot-bubble: #1b4332; | |
| --user-bubble: linear-gradient(135deg, #40916c 0%, #2d6a4f 100%); | |
| --input-bg: #081c15; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| transition: background-color 0.3s, color 0.3s, border-color 0.3s; | |
| } | |
| body, | |
| html { | |
| min-height: 100vh; | |
| margin: 0; | |
| padding: 0; | |
| font-family: 'Outfit', sans-serif; | |
| background: var(--bg-solid, #e8f5e9); | |
| background: var(--bg-gradient); | |
| background-attachment: fixed; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| overflow-x: hidden; | |
| width: 100vw; | |
| } | |
| #particles-js { | |
| position: fixed; | |
| width: 100%; | |
| height: 100%; | |
| z-index: -1; | |
| top: 0; | |
| left: 0; | |
| } | |
| .dashboard { | |
| display: flex; | |
| width: 95%; | |
| max-width: 1200px; | |
| height: 90vh; | |
| gap: 20px; | |
| margin: 20px; | |
| animation: fadeIn 0.8s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(20px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| #chat-container { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| background: var(--glass); | |
| backdrop-filter: blur(20px); | |
| -webkit-backdrop-filter: blur(20px); | |
| border-radius: 32px; | |
| box-shadow: var(--shadow); | |
| border: 1px solid var(--glass-border); | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| .visual-panel { | |
| flex: 1.2; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| position: relative; | |
| background: transparent; | |
| } | |
| .visual-panel h2 { | |
| color: var(--primary); | |
| font-size: 2.2rem; | |
| margin-bottom: 20px; | |
| text-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); | |
| font-weight: 700; | |
| } | |
| .agri-core { | |
| width: 400px; | |
| height: 400px; | |
| position: relative; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .orbit { | |
| position: absolute; | |
| border-radius: 50%; | |
| border: 1px solid rgba(149, 213, 178, 0.2); | |
| animation: rotateOrbit linear infinite; | |
| } | |
| .orbit-1 { | |
| width: 300px; | |
| height: 300px; | |
| animation-duration: 15s; | |
| } | |
| .orbit-2 { | |
| width: 220px; | |
| height: 220px; | |
| animation-duration: 20s; | |
| animation-direction: reverse; | |
| } | |
| @keyframes rotateOrbit { | |
| from { | |
| transform: rotate(0deg); | |
| } | |
| to { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| .node { | |
| position: absolute; | |
| width: 12px; | |
| height: 12px; | |
| background: var(--accent); | |
| border-radius: 50%; | |
| box-shadow: 0 0 15px var(--accent); | |
| } | |
| .plant-container { | |
| width: 180px; | |
| height: 180px; | |
| background: rgba(45, 106, 79, 0.1); | |
| border-radius: 50%; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| border: 2px solid rgba(45, 106, 79, 0.2); | |
| position: relative; | |
| overflow: hidden; | |
| backdrop-filter: blur(5px); | |
| } | |
| .scanning-beam { | |
| position: absolute; | |
| width: 100%; | |
| height: 60px; | |
| background: linear-gradient(to bottom, transparent, rgba(255, 159, 28, 0.4), transparent); | |
| animation: scanLoop 3s ease-in-out infinite; | |
| z-index: 2; | |
| } | |
| @keyframes scanLoop { | |
| 0%, | |
| 100% { | |
| transform: translateY(-100px); | |
| } | |
| 50% { | |
| transform: translateY(100px); | |
| } | |
| } | |
| #chat-header { | |
| padding: 20px 30px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.1); | |
| } | |
| .bot-avatar { | |
| width: 48px; | |
| height: 48px; | |
| background: var(--primary); | |
| border-radius: 12px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: #ffffff; | |
| } | |
| [data-theme="dark"] .bot-avatar { | |
| color: #081c15; | |
| } | |
| #chat-box { | |
| flex: 1; | |
| padding: 25px; | |
| overflow-y: auto; | |
| scroll-behavior: smooth; | |
| } | |
| .msg-wrapper { | |
| margin-bottom: 20px; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .user-wrapper { | |
| align-items: flex-end; | |
| } | |
| .bot-wrapper { | |
| align-items: flex-start; | |
| } | |
| .user-bubble { | |
| background: var(--user-bubble); | |
| color: white; | |
| border-radius: 20px 20px 4px 20px; | |
| padding: 12px 18px; | |
| box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); | |
| } | |
| .bot-bubble { | |
| background: var(--bot-bubble); | |
| color: var(--text-main); | |
| border-radius: 20px 20px 20px 4px; | |
| padding: 12px 18px; | |
| border: 1px solid var(--glass-border); | |
| line-height: 1.5; | |
| } | |
| .chart-container { | |
| width: 100%; | |
| max-width: 250px; | |
| margin-top: 10px; | |
| background: rgba(255, 255, 255, 0.05); | |
| border-radius: 12px; | |
| padding: 10px; | |
| } | |
| #input-container { | |
| padding: 20px; | |
| background: var(--bot-bubble); | |
| display: flex; | |
| gap: 15px; | |
| border-top: 1px solid var(--glass-border); | |
| } | |
| #user-input { | |
| flex: 1; | |
| padding: 14px 20px; | |
| background: var(--input-bg); | |
| border: 1px solid var(--glass-border); | |
| border-radius: 12px; | |
| outline: none; | |
| font-size: 0.95rem; | |
| color: var(--text-main); | |
| } | |
| #send-btn { | |
| width: 50px; | |
| height: 50px; | |
| background: var(--primary); | |
| border: none; | |
| border-radius: 12px; | |
| color: #ffffff; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| [data-theme="dark"] #send-btn { | |
| color: #081c15; | |
| } | |
| .suggestion-chip { | |
| padding: 8px 16px; | |
| background: var(--bot-bubble); | |
| border: 1px solid var(--glass-border); | |
| border-radius: 20px; | |
| font-size: 0.85rem; | |
| cursor: pointer; | |
| color: var(--text-main); | |
| transition: 0.2s; | |
| white-space: nowrap; | |
| } | |
| .suggestion-chip:hover { | |
| background: var(--primary); | |
| color: #ffffff; | |
| } | |
| .suggestions { | |
| padding: 0 25px 15px; | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 10px; | |
| overflow-x: auto; | |
| scrollbar-width: none; | |
| } | |
| /* Onboarding Overlay */ | |
| #onboarding { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0, 0, 0, 0.6); | |
| z-index: 100; | |
| display: none; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| border-radius: 32px; | |
| backdrop-filter: blur(4px); | |
| } | |
| .onboarding-card { | |
| background: var(--bot-bubble); | |
| padding: 30px; | |
| border-radius: 24px; | |
| max-width: 80%; | |
| text-align: center; | |
| color: var(--text-main); | |
| box-shadow: var(--shadow); | |
| position: relative; | |
| } | |
| .onboarding-card h3 { | |
| margin: 0 0 15px; | |
| color: var(--primary); | |
| } | |
| .onboarding-btn { | |
| background: var(--primary); | |
| color: #ffffff; | |
| border: none; | |
| padding: 10px 20px; | |
| border-radius: 10px; | |
| cursor: pointer; | |
| margin-top: 20px; | |
| font-weight: 600; | |
| } | |
| /* Dark Mode Toggle */ | |
| .theme-toggle { | |
| padding: 8px; | |
| border-radius: 10px; | |
| background: var(--glass-border); | |
| cursor: pointer; | |
| display: flex; | |
| gap: 5px; | |
| align-items: center; | |
| } | |
| @media (max-width: 992px) { | |
| .visual-panel { | |
| display: none; | |
| } | |
| .dashboard { | |
| max-width: 520px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .dashboard { | |
| width: 100%; | |
| height: 100vh; | |
| margin: 0; | |
| border-radius: 0; | |
| } | |
| #chat-container { | |
| border-radius: 0; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body data-theme="light"> | |
| <div id="particles-js"></div> | |
| <div class="dashboard"> | |
| <div id="chat-container"> | |
| <!-- Onboarding --> | |
| <div id="onboarding"> | |
| <div class="onboarding-card"> | |
| <h3 id="ob-title">Welcome to Cropiee!</h3> | |
| <p id="ob-text">I'm your AI agriculture assistant. Let's get started on your farming journey.</p> | |
| <button class="onboarding-btn" onclick="nextOb()">Next Step</button> | |
| <div style="margin-top:10px; font-size: 0.8rem; opacity: 0.7;" id="ob-count">1 / 3</div> | |
| </div> | |
| </div> | |
| <div id="chat-header"> | |
| <div style="display: flex; align-items: center; gap: 12px;"> | |
| <div class="bot-avatar"> | |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" | |
| stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"> | |
| <rect x="5" y="10" width="14" height="10" rx="3"></rect> | |
| <circle cx="9" cy="14" r="1.2" fill="currentColor"></circle> | |
| <circle cx="15" cy="14" r="1.2" fill="currentColor"></circle> | |
| <path d="M10 17h4"></path> | |
| <path d="M12 10V7"></path> | |
| <path d="M12 7c1.5-1.5 2.5-1.5 2.5-3s-1-1.5-2.5 0"></path> | |
| <path d="M12 7c-1.5-1.5-2.5-1.5-2.5-3s1-1.5 2.5 0"></path> | |
| </svg> | |
| </div> | |
| <div> | |
| <h1 style="margin:0; font-size:1.1rem; font-weight:700; color:var(--text-main)">Cropiee</h1> | |
| </div> | |
| </div> | |
| <div style="display: flex; gap: 10px; align-items: center;"> | |
| <button class="theme-toggle" | |
| style="border:none; color:inherit; font-weight:600; font-family:inherit; font-size: 0.9rem;" | |
| onclick="showOnboarding()"> | |
| โ Guide | |
| </button> | |
| <div class="theme-toggle" onclick="toggleTheme()" title="Toggle Dark Mode"> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" | |
| stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | |
| <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> | |
| </svg> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="chat-box"></div> | |
| <div class="suggestions"> | |
| <div class="suggestion-chip" onclick="quickSend('Suggest a crop')">๐ฟ Recommend</div> | |
| <div class="suggestion-chip" onclick="quickSend('Soil analysis')">๐ฑ Soil Advice</div> | |
| </div> | |
| <div id="input-container"> | |
| <input type="text" id="user-input" placeholder="Cultivate a query..." autocomplete="off"> | |
| <button id="send-btn" onclick="sendMessage()"> | |
| <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" | |
| stroke-linecap="round" stroke-linejoin="round"> | |
| <line x1="22" y1="2" x2="11" y2="13"></line> | |
| <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="visual-panel"> | |
| <h2>Hybrid AI Analytics</h2> | |
| <div class="agri-core"> | |
| <div class="orbit orbit-1"> | |
| <div class="node" style="top:0; left:50%; transform:translateX(-50%)"></div> | |
| <div class="node" style="bottom:0; left:50%; transform:translateX(-50%)"></div> | |
| </div> | |
| <div class="orbit orbit-2"> | |
| <div class="node" style="left:0; top:50%; transform:translateY(-50%)"></div> | |
| <div class="node" style="right:0; top:50%; transform:translateY(-50%)"></div> | |
| </div> | |
| <div class="plant-container"> | |
| <div class="scanning-beam"></div> | |
| <svg width="100" height="100" viewBox="0 0 24 24" fill="none" stroke="var(--primary)" | |
| stroke-width="1.8"> | |
| <path | |
| d="M7 20l3-3 3 3m-3-3V10m0 0a4 4 0 0 1 4-4c1.5 0 3 .5 3 2s-1.5 2-3 2a4 4 0 0 1-4 4zm0-6a4 4 0 0 0-4-4c-1.5 0-3 .5-3 2s1.5 2 3 2a4 4 0 0 0 4 4z"> | |
| </path> | |
| </svg> | |
| </div> | |
| </div> | |
| <div style="margin-top:40px; text-align:center; color: var(--text-muted); font-size: 0.9rem;"> | |
| <span id="stat-text" style="color:var(--primary); font-weight:600;">Processing Agro-Neural | |
| Data...</span> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> | |
| <script> | |
| // Theme Toggle Logic | |
| function toggleTheme() { | |
| const body = document.body; | |
| const current = body.getAttribute('data-theme'); | |
| const target = current === 'light' ? 'dark' : 'light'; | |
| body.setAttribute('data-theme', target); | |
| localStorage.setItem('cropiee-theme', target); | |
| updateChartThemes(); | |
| } | |
| // Onboarding Logic | |
| const obData = [ | |
| { title: "Smart Recommendations ๐ฟ", text: "Ask me 'What can I grow in Delhi?' and I'll use real-time weather and ML models to suggest the best crop." }, | |
| { title: "Soil Analysis ๐ฑ", text: "Type 'soil for rice' to get precise chemical requirement charts for your favorite crops." }, | |
| { title: "Market Insights ๐", text: "I fetch current mandi prices to tell you the profit potential of your farm." } | |
| ]; | |
| let obIdx = 0; | |
| function showOnboarding() { document.getElementById('onboarding').style.display = 'flex'; obIdx = 0; updateOb(); } | |
| function nextOb() { | |
| obIdx++; | |
| if (obIdx >= obData.length) { document.getElementById('onboarding').style.display = 'none'; return; } | |
| updateOb(); | |
| } | |
| function updateOb() { | |
| document.getElementById('ob-title').innerText = obData[obIdx].title; | |
| document.getElementById('ob-text').innerText = obData[obIdx].text; | |
| document.getElementById('ob-count').innerText = `${obIdx + 1} / 3`; | |
| } | |
| // Particles | |
| particlesJS('particles-js', { | |
| "particles": { "number": { "value": 40 }, "color": { "value": "#2d6a4f" }, "shape": { "type": "circle" }, "opacity": { "value": 0.3 }, "size": { "value": 3 }, "line_linked": { "enable": true, "distance": 150, "color": "#2d6a4f", "opacity": 0.2, "width": 1 }, "move": { "enable": true, "speed": 1.5 } } | |
| }); | |
| // Chat & Charts | |
| const chatBox = document.getElementById('chat-box'); | |
| const userInput = document.getElementById('user-input'); | |
| const charts = []; | |
| function updateChartThemes() { | |
| const isDark = document.body.getAttribute('data-theme') === 'dark'; | |
| const color = isDark ? '#d8f3dc' : '#1b4332'; | |
| charts.forEach(c => { | |
| c.options.scales.r.grid.color = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.05)'; | |
| c.options.scales.r.pointLabels.color = color; | |
| c.update(); | |
| }); | |
| } | |
| function createChart(canvasId, labels, values, labelTitle) { | |
| const ctx = document.getElementById(canvasId).getContext('2d'); | |
| const isDark = document.body.getAttribute('data-theme') === 'dark'; | |
| const primary = isDark ? '#95d5b2' : '#1a4d2e'; | |
| const newChart = new Chart(ctx, { | |
| type: 'radar', | |
| data: { | |
| labels: labels, | |
| datasets: [{ | |
| label: labelTitle, | |
| data: values, | |
| backgroundColor: isDark ? 'rgba(149, 213, 178, 0.3)' : 'rgba(26, 77, 46, 0.3)', | |
| borderColor: primary, | |
| borderWidth: 2, | |
| pointBackgroundColor: primary | |
| }] | |
| }, | |
| options: { | |
| scales: { | |
| r: { | |
| angleLines: { color: isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.05)' }, | |
| grid: { color: isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.05)' }, | |
| pointLabels: { color: isDark ? '#d8f3dc' : '#1b4332', font: { size: 10 } }, | |
| ticks: { display: false } | |
| } | |
| }, | |
| plugins: { legend: { display: false } } | |
| } | |
| }); | |
| charts.push(newChart); | |
| } | |
| function addMessage(text, isUser = false, chartData = null) { | |
| const wrapper = document.createElement('div'); | |
| wrapper.className = `msg-wrapper ${isUser ? 'user-wrapper' : 'bot-wrapper'}`; | |
| const bubble = document.createElement('div'); | |
| bubble.className = `msg-bubble ${isUser ? 'user-bubble' : 'bot-bubble'}`; | |
| bubble.innerHTML = text; | |
| wrapper.appendChild(bubble); | |
| if (chartData) { | |
| const chartDiv = document.createElement('div'); | |
| chartDiv.className = 'chart-container'; | |
| const canvasId = 'chart-' + Date.now(); | |
| chartDiv.innerHTML = `<canvas id="${canvasId}"></canvas>`; | |
| bubble.appendChild(chartDiv); | |
| setTimeout(() => { | |
| createChart(canvasId, chartData.labels, chartData.values, isUser ? "Your Input" : "Ideal soil Readings"); | |
| }, 100); | |
| } | |
| chatBox.appendChild(wrapper); | |
| chatBox.scrollTo({ top: chatBox.scrollHeight, behavior: 'smooth' }); | |
| } | |
| async function sendMessage() { | |
| const text = userInput.value.trim(); | |
| if (!text) return; | |
| userInput.value = ''; | |
| addMessage(text, true); | |
| try { | |
| let response = await fetch('/chatbot', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ message: text }) | |
| }); | |
| const data = await response.json(); | |
| addMessage(data.reply, false, data.chart); | |
| } catch (e) { | |
| addMessage("I'm momentarily offline. ๐ฟ"); | |
| } | |
| } | |
| userInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') sendMessage(); }); | |
| function quickSend(v) { userInput.value = v; sendMessage(); } | |
| window.onload = () => { | |
| const saved = localStorage.getItem('cropiee-theme'); | |
| if (saved) document.body.setAttribute('data-theme', saved); | |
| addMessage("Hello! I'm <b>Cropiee</b>. ๐\nWelcome to your intelligent agricultural dashboard."); | |
| // Auto show onboarding for first time | |
| if (!localStorage.getItem('ob-seen')) { | |
| showOnboarding(); | |
| localStorage.setItem('ob-seen', 'true'); | |
| } | |
| } | |
| // Stats Rotation | |
| const statText = document.getElementById('stat-text'); | |
| const states = ["Analyzing N-P-K Levels...", "Syncing IoT Sensor Data...", "Predicting Hybrid Yields...", "Matching Mandi Price API..."]; | |
| let sIdx = 0; | |
| setInterval(() => { | |
| statText.innerText = states[sIdx]; | |
| sIdx = (sIdx + 1) % states.length; | |
| }, 4000); | |
| </script> | |
| </body> | |
| </html> |