Dc0der-x commited on
Commit
48bd70b
·
verified ·
1 Parent(s): eec7ce7

ho wdo i add backend into this to make it functional and live can you help me - Follow Up Deployment

Browse files
Files changed (1) hide show
  1. index.html +278 -24
index.html CHANGED
@@ -96,7 +96,11 @@
96
  <div class="container mx-auto px-4 py-3 flex justify-between items-center">
97
  <div class="flex items-center space-x-2">
98
  <i class="fas fa-leaf text-2xl text-green-600"></i>
99
- <h1 class="text-xl font-bold text-gray-800">Dr. Plant</h1>
 
 
 
 
100
  </div>
101
  <nav class="hidden md:flex space-x-8">
102
  <a href="#" class="nav-item active text-green-600 font-medium">Home</a>
@@ -232,7 +236,7 @@
232
 
233
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
234
  <!-- Remedy Card 1 -->
235
- <div class="remedy-card bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition">
236
  <img src="https://images.unsplash.com/photo-1601493700631-2b16ec4b4716?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80"
237
  alt="Neem leaves"
238
  class="w-full h-48 object-cover">
@@ -253,7 +257,7 @@
253
  </div>
254
 
255
  <!-- Remedy Card 2 -->
256
- <div class="remedy-card bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition">
257
  <img src="https://images.unsplash.com/photo-1601493700896-4b8ac38ba0e8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80"
258
  alt="Turmeric powder"
259
  class="w-full h-48 object-cover">
@@ -274,7 +278,7 @@
274
  </div>
275
 
276
  <!-- Remedy Card 3 -->
277
- <div class="remedy-card bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition">
278
  <img src="https://images.unsplash.com/photo-1601493700631-2b16ec4b4716?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80"
279
  alt="Banana peel"
280
  class="w-full h-48 object-cover">
@@ -576,32 +580,282 @@
576
  </div>
577
 
578
  <script>
579
- // Simple JavaScript for demonstration
 
 
 
 
 
580
  document.addEventListener('DOMContentLoaded', function() {
581
- // Mobile menu toggle would go here
582
- // Camera button functionality
583
- const cameraBtn = document.querySelector('.camera-btn');
584
- cameraBtn.addEventListener('click', function() {
585
- alert('Camera functionality would open here to scan your plant');
 
 
 
 
 
 
 
 
 
586
  });
587
 
588
- // Plant card hover effect
589
- const plantCards = document.querySelectorAll('.plant-card');
590
- plantCards.forEach(card => {
591
- card.addEventListener('mouseenter', function() {
592
- this.style.transition = 'all 0.3s ease';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
593
  });
594
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
595
 
596
- // Remedy card click
597
- const remedyCards = document.querySelectorAll('.remedy-card');
598
- remedyCards.forEach(card => {
599
- card.addEventListener('click', function() {
600
- // In a real app, this would navigate to remedy details
601
- console.log('Viewing remedy details');
602
  });
603
- });
604
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
  </script>
606
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Dc0der-x/dr-plant" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
607
  </html>
 
96
  <div class="container mx-auto px-4 py-3 flex justify-between items-center">
97
  <div class="flex items-center space-x-2">
98
  <i class="fas fa-leaf text-2xl text-green-600"></i>
99
+ <div>
100
+ <h1 class="text-xl font-bold text-gray-800">Dr. Plant</h1>
101
+ <p class="text-xs text-gray-500">Your plant's health is our priority</p>
102
+ <div id="backend-status" class="text-xs text-green-600 hidden md:block">Backend: Connected</div>
103
+ </div>
104
  </div>
105
  <nav class="hidden md:flex space-x-8">
106
  <a href="#" class="nav-item active text-green-600 font-medium">Home</a>
 
236
 
237
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
238
  <!-- Remedy Card 1 -->
239
+ <div class="remedy-card bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition" data-remedy-id="neem-oil">
240
  <img src="https://images.unsplash.com/photo-1601493700631-2b16ec4b4716?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80"
241
  alt="Neem leaves"
242
  class="w-full h-48 object-cover">
 
257
  </div>
258
 
259
  <!-- Remedy Card 2 -->
260
+ <div class="remedy-card bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition" data-remedy-id="turmeric-fungal">
261
  <img src="https://images.unsplash.com/photo-1601493700896-4b8ac38ba0e8?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80"
262
  alt="Turmeric powder"
263
  class="w-full h-48 object-cover">
 
278
  </div>
279
 
280
  <!-- Remedy Card 3 -->
281
+ <div class="remedy-card bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition" data-remedy-id="banana-fertilizer">
282
  <img src="https://images.unsplash.com/photo-1601493700631-2b16ec4b4716?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80"
283
  alt="Banana peel"
284
  class="w-full h-48 object-cover">
 
580
  </div>
581
 
582
  <script>
583
+ // Backend API configuration - replace with your actual backend URL
584
+ const API_BASE_URL = 'http://localhost:3000/api'; // or your deployed backend URL
585
+
586
+ // Global state
587
+ let currentUser = null;
588
+
589
  document.addEventListener('DOMContentLoaded', function() {
590
+ // Check authentication status
591
+ checkAuthStatus();
592
+
593
+ // Check backend connection
594
+ checkBackendStatus();
595
+
596
+ // Setup event listeners
597
+ setupEventListeners();
598
+ });
599
+
600
+ function setupEventListeners() {
601
+ // Camera/scan functionality
602
+ document.querySelectorAll('.camera-btn, .scan-btn').forEach(btn => {
603
+ btn.addEventListener('click', handleScanClick);
604
  });
605
 
606
+ // Sign in/out buttons
607
+ document.querySelector('.signin-btn')?.addEventListener('click', showAuthModal);
608
+ document.querySelector('.signout-btn')?.addEventListener('click', handleSignOut);
609
+
610
+ // Plant management
611
+ document.querySelector('.add-plant-btn')?.addEventListener('click', showAddPlantModal);
612
+
613
+ // Form submissions
614
+ document.getElementById('auth-form')?.addEventListener('submit', handleAuthSubmit);
615
+ document.getElementById('scan-form')?.addEventListener('submit', handleScanSubmit);
616
+ document.getElementById('add-plant-form')?.addEventListener('submit', handleAddPlantSubmit);
617
+ }
618
+
619
+ // Authentication functions
620
+ async function checkAuthStatus() {
621
+ try {
622
+ const token = localStorage.getItem('plantcare_token');
623
+ if (!token) return;
624
+
625
+ const response = await fetch(`${API_BASE_URL}/auth/check`, {
626
+ headers: { 'Authorization': `Bearer ${token}` }
627
  });
628
+
629
+ if (response.ok) {
630
+ currentUser = await response.json();
631
+ updateAuthUI(true);
632
+ }
633
+ } catch (error) {
634
+ console.error('Auth check failed:', error);
635
+ }
636
+ }
637
+
638
+ async function handleAuthSubmit(e) {
639
+ e.preventDefault();
640
+ const formData = new FormData(e.target);
641
+ const credentials = Object.fromEntries(formData);
642
 
643
+ try {
644
+ const response = await fetch(`${API_BASE_URL}/auth/login`, {
645
+ method: 'POST',
646
+ headers: { 'Content-Type': 'application/json' },
647
+ body: JSON.stringify(credentials)
 
648
  });
649
+
650
+ if (response.ok) {
651
+ const { token, user } = await response.json();
652
+ localStorage.setItem('plantcare_token', token);
653
+ currentUser = user;
654
+ updateAuthUI(true);
655
+ hideAuthModal();
656
+ } else {
657
+ alert('Login failed. Please check your credentials.');
658
+ }
659
+ } catch (error) {
660
+ console.error('Login error:', error);
661
+ alert('Login failed. Please try again.');
662
+ }
663
+ }
664
+
665
+ // Plant scanning functions
666
+ async function handleScanSubmit(e) {
667
+ e.preventDefault();
668
+ const formData = new FormData(e.target);
669
+ const fileInput = e.target.querySelector('input[type="file"]');
670
+
671
+ if (!fileInput.files.length) {
672
+ alert('Please select an image first');
673
+ return;
674
+ }
675
+
676
+ try {
677
+ const formData = new FormData();
678
+ formData.append('image', fileInput.files[0]);
679
+
680
+ const token = localStorage.getItem('plantcare_token');
681
+ const headers = token ? { 'Authorization': `Bearer ${token}` } : {};
682
+
683
+ const response = await fetch(`${API_BASE_URL}/scan`, {
684
+ method: 'POST',
685
+ headers,
686
+ body: formData
687
+ });
688
+
689
+ if (response.ok) {
690
+ const result = await response.json();
691
+ displayScanResult(result);
692
+ } else {
693
+ throw new Error('Scan failed');
694
+ }
695
+ } catch (error) {
696
+ console.error('Scan error:', error);
697
+ alert('Scan failed. Please try again.');
698
+ }
699
+ }
700
+
701
+ // Plant management functions
702
+ async function handleAddPlantSubmit(e) {
703
+ e.preventDefault();
704
+ const formData = new FormData(e.target);
705
+ const plantData = Object.fromEntries(formData);
706
+
707
+ try {
708
+ const token = localStorage.getItem('plantcare_token');
709
+ if (!token) throw new Error('Not authenticated');
710
+
711
+ const response = await fetch(`${API_BASE_URL}/plants`, {
712
+ method: 'POST',
713
+ headers: {
714
+ 'Authorization': `Bearer ${token}`,
715
+ 'Content-Type': 'application/json'
716
+ },
717
+ body: JSON.stringify(plantData)
718
+ });
719
+
720
+ if (response.ok) {
721
+ const newPlant = await response.json();
722
+ addPlantToUI(newPlant);
723
+ hideAddPlantModal();
724
+ } else {
725
+ throw new Error('Failed to add plant');
726
+ }
727
+ } catch (error) {
728
+ console.error('Add plant error:', error);
729
+ alert('Failed to add plant. Please try again.');
730
+ }
731
+ }
732
+
733
+ // UI update functions
734
+ function updateAuthUI(isLoggedIn) {
735
+ if (isLoggedIn) {
736
+ document.querySelector('.signin-btn').classList.add('hidden');
737
+ document.querySelector('.signout-btn').classList.remove('hidden');
738
+ document.querySelector('.user-greeting').textContent = `Hi, ${currentUser.name}`;
739
+ } else {
740
+ document.querySelector('.signin-btn').classList.remove('hidden');
741
+ document.querySelector('.signout-btn').classList.add('hidden');
742
+ document.querySelector('.user-greeting').textContent = '';
743
+ }
744
+ }
745
+
746
+ function displayScanResult(result) {
747
+ const resultContainer = document.getElementById('scan-result');
748
+ resultContainer.innerHTML = `
749
+ <h3 class="text-xl font-bold mb-2">Scan Result</h3>
750
+ <p>Status: <span class="font-semibold">${result.healthy ? 'Healthy' : 'Disease Detected'}</span></p>
751
+ ${result.disease ? `<p>Disease: <span class="font-semibold">${result.disease}</span></p>` : ''}
752
+ ${result.confidence ? `<p>Confidence: <span class="font-semibold">${result.confidence}%</span></p>` : ''}
753
+ ${result.remedies ? `<div class="mt-4">
754
+ <h4 class="font-bold">Suggested Remedies:</h4>
755
+ <ul class="list-disc pl-5 mt-2">
756
+ ${result.remedies.map(r => `<li>${r}</li>`).join('')}
757
+ </ul>
758
+ </div>` : ''}
759
+ `;
760
+ }
761
+
762
+ // Modal functions
763
+ function showAuthModal() {
764
+ document.getElementById('auth-modal').classList.remove('hidden');
765
+ }
766
+
767
+ function hideAuthModal() {
768
+ document.getElementById('auth-modal').classList.add('hidden');
769
+ }
770
+
771
+ // Add these modal templates before the closing body tag
772
+ document.body.insertAdjacentHTML('beforeend', `
773
+ <!-- Auth Modal -->
774
+ <div id="auth-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
775
+ <div class="bg-white rounded-lg p-6 max-w-md w-full">
776
+ <h2 class="text-2xl font-bold mb-4">Sign In</h2>
777
+ <form id="auth-form">
778
+ <div class="mb-4">
779
+ <label class="block text-gray-700 mb-2">Email</label>
780
+ <input type="email" name="email" required
781
+ class="w-full px-3 py-2 border rounded-lg">
782
+ </div>
783
+ <div class="mb-4">
784
+ <label class="block text-gray-700 mb-2">Password</label>
785
+ <input type="password" name="password" required
786
+ class="w-full px-3 py-2 border rounded-lg">
787
+ </div>
788
+ <button type="submit"
789
+ class="w-full bg-green-600 text-white py-2 rounded-lg">
790
+ Sign In
791
+ </button>
792
+ </form>
793
+ <button onclick="hideAuthModal()"
794
+ class="mt-4 text-gray-500 hover:text-gray-700">
795
+ Cancel
796
+ </button>
797
+ </div>
798
+ </div>
799
+
800
+ <!-- Scan Modal -->
801
+ <div id="scan-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
802
+ <div class="bg-white rounded-lg p-6 max-w-md w-full">
803
+ <h2 class="text-2xl font-bold mb-4">Scan Your Plant</h2>
804
+ <form id="scan-form">
805
+ <div class="mb-4">
806
+ <label class="block text-gray-700 mb-2">Plant Image</label>
807
+ <input type="file" name="image" accept="image/*" capture="environment" required
808
+ class="w-full px-3 py-2 border rounded-lg">
809
+ </div>
810
+ <button type="submit"
811
+ class="w-full bg-green-600 text-white py-2 rounded-lg">
812
+ Analyze Plant
813
+ </button>
814
+ </form>
815
+ <div id="scan-result" class="mt-4"></div>
816
+ <button onclick="hideScanModal()"
817
+ class="mt-4 text-gray-500 hover:text-gray-700">
818
+ Close
819
+ </button>
820
+ </div>
821
+ </div>
822
+
823
+ <!-- Add Plant Modal -->
824
+ <div id="add-plant-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
825
+ <div class="bg-white rounded-lg p-6 max-w-md w-full">
826
+ <h2 class="text-2xl font-bold mb-4">Add New Plant</h2>
827
+ <form id="add-plant-form">
828
+ <div class="mb-4">
829
+ <label class="block text-gray-700 mb-2">Plant Name</label>
830
+ <input type="text" name="name" required
831
+ class="w-full px-3 py-2 border rounded-lg">
832
+ </div>
833
+ <div class="mb-4">
834
+ <label class="block text-gray-700 mb-2">Plant Type</label>
835
+ <select name="type" class="w-full px-3 py-2 border rounded-lg">
836
+ <option value="indoor">Indoor</option>
837
+ <option value="outdoor">Outdoor</option>
838
+ <option value="succulent">Succulent</option>
839
+ <option value="herb">Herb</option>
840
+ </select>
841
+ </div>
842
+ <div class="mb-4">
843
+ <label class="block text-gray-700 mb-2">Watering Frequency (days)</label>
844
+ <input type="number" name="water_frequency" min="1" value="7"
845
+ class="w-full px-3 py-2 border rounded-lg">
846
+ </div>
847
+ <button type="submit"
848
+ class="w-full bg-green-600 text-white py-2 rounded-lg">
849
+ Add Plant
850
+ </button>
851
+ </form>
852
+ <button onclick="hideAddPlantModal()"
853
+ class="mt-4 text-gray-500 hover:text-gray-700">
854
+ Cancel
855
+ </button>
856
+ </div>
857
+ </div>
858
+ `);
859
  </script>
860
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Dc0der-x/dr-plant" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
861
  </html>