1 Commits

160 changed files with 6883 additions and 144311 deletions
-22
View File
@@ -1,22 +0,0 @@
# Database
MONGODB_ROOT_USERNAME=mongo_user
MONGODB_ROOT_PASSWORD=mongo_pass
MONGODB_URI=mongodb://mongo_user:mongo_pass@database:27017
# SMTP
SMTP_SERVICE=gmail
SMTP_EMAILADDR=example@gmail.com
SMTP_PASSWORD=app pass here
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
# Cloudinary
CLOUDINARY_CLOUD_NAME=cloudname_here
CLOUDINARY_API_KEY=api_key_here
CLOUDINARY_API_SECRET=api_secret_here
# Gemini
GEMINI_API_KEY=gemini_api_here
# Refresh token
REFRESH_TOKEN_SECRET=a_random_60_or_more_char_secret_here
-4
View File
@@ -1,4 +0,0 @@
package-lock.json
node_modules/
db/
deployed-compose.yaml
-6
View File
@@ -1,6 +0,0 @@
Dockerfile
node_modules/
package-lock.json
.dockerignore
.env.back
.gitignore
-26
View File
@@ -1,26 +0,0 @@
PORT = 8000
FRONTEND_URI = ${FRONTEND_URI}
# Database
MONGODB_URI = ${MONGODB_URI}
DATABASE_NAME=CropCompass
# Mail server
SMPT_SERVICE = ${SMTP_SERVICE}
SMPT_MAIL = ${SMTP_EMAILADDR}
SMPT_PASSWORD = ${SMTP_PASSWORD}
HOST = ${SMTP_HOST}
EMAIL_PORT = ${SMTP_PORT}
# Cloudinary
CLOUDINARY_CLOUD_NAME = ${CLOUDINARY_CLOUD_NAME}
CLOUDINARY_API_KEY = ${CLOUDINARY_API_KEY}
CLOUDINARY_API_SECRET = ${CLOUDINARY_API_SECRET}
# Gemini
GEMINI_API_KEY = ${GEMINI_API_KEY}
# Refresh token
TOKEN_NAME = uid
REFRESH_TOKEN_EXPIRY = 10d
REFRESH_TOKEN_SECRET = ${REFRESH_TOKEN_SECRET}
+1 -3
View File
@@ -1,5 +1,3 @@
package-lock.json
# Logs
logs
*.log
@@ -19,7 +17,7 @@ node_modules/
jspm_packages/
# Environment files
.env.bak
.env
.env.*.local
# Build outputs
-1
View File
@@ -39,7 +39,6 @@ const getUserFarms = async (req, res) => {
// Get a single farm by ID
const getFarmById = async (req, res) => {
try {
console.log("also i am clla ing", "My farm id is : ", req.params.farmId);
const farm = await Farm.findById(req.params.farmId)
.populate("crops")
.populate("finances");
+1 -47
View File
@@ -2,55 +2,15 @@ const Finance = require("../Models/finance.model.js");
const Farm = require("../Models/farm.model.js");
// Create finance record for a farm
// const createFinance = async (req, res) => {
// try {
// const { farm } = req.body;
// console.log("My farm id is which is going to be created : ", req.body);
// // Check if the farm exists
// const existingFarm = await Farm.findById(farm);
// if (!existingFarm)
// return res.status(404).json({ message: "Farm not found" });
// const finance = new Finance({
// farm,
// transactions: [],
// totalExpenses: 0,
// totalRevenue: 0,
// });
// await finance.save();
// // Link finance to farm
// existingFarm.finances = finance._id;
// await existingFarm.save();
// res.status(201).json(finance);
// } catch (error) {
// res.status(500).json({ message: error.message });
// }
// };
const createFinance = async (req, res) => {
try {
const { farm } = req.body;
console.log("My farm id is which is going to be created : ", farm);
// Check if the farm exists
const existingFarm = await Farm.findById(farm);
if (!existingFarm) {
if (!existingFarm)
return res.status(404).json({ message: "Farm not found" });
}
// Check if finance already exists for this farm
if (existingFarm.finances) {
return res
.status(400)
.json({ message: "Finance already exists for this farm" });
}
// Create finance entry
const finance = new Finance({
farm,
transactions: [],
@@ -90,12 +50,6 @@ const addTransaction = async (req, res) => {
try {
const { type, amount, description } = req.body;
console.log("My type is : ", type);
console.log("My amount is : ", amount);
console.log("My description is : ", description);
console.log("My finance id is : ", req.params.financeId);
const finance = await Finance.findById(req.params.financeId);
if (!finance)
return res.status(404).json({ message: "Finance record not found" });
+7 -22
View File
@@ -4,28 +4,11 @@ const { uploadOnCloudinary } = require("../Utils/cloudinary.js");
const sendEmail = require("../Utils/sendmail.js");
const crypto = require("crypto");
const jwt = require("jsonwebtoken");
const sha1 = require("sha1");
const axios = require("axios");
// Register or Sign up new User -- Done
const registerUser = catchAsyncErrors(async (req, res) => {
const { name, email, password, role } = req.body;
// Strong password policy
const strongPasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$/;
if (!strongPasswordRegex.test(password)) {
return res.status(400).json({ success: false, message: "Password must be at least 8 characters long and include uppercase, lowercase, number, and special character." });
}
// Check for data breach with haveibeenpwned.com
const hashed = sha1(password).toUpperCase();
const prefix = hashed.slice(0, 5);
const suffix = hashed.slice(5);
const response = await axios.get(`https://api.pwnedpasswords.com/range/${prefix}`);
if (response.data.includes(suffix)) {
return res.status(400).json({ success: false, message: "This password has appeared in a data breach. Please choose a different one." });
}
const user = await User.create({
name,
email,
@@ -82,12 +65,12 @@ const loginUser = catchAsyncErrors(async (req, res) => {
return res
.status(200)
.cookie("uid", token, {
httpOnly: true, // Prevent access from JavaScript (recommended for security)
secure: false, // ⚠️ Set to `false` for localhost
sameSite: "Lax", // Use "Lax" instead of "None" for better compatibility
.cookie(process.env.TOKEN_NAME, token, {
path: "/",
expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days
sameSite: "None",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
})
.json({
success: true,
@@ -277,6 +260,8 @@ const resetPassword = catchAsyncErrors(async (req, res) => {
// get user personal details
const getUserDetails = catchAsyncErrors(async (req, res) => {
const user = await User.findById(req.user._id);
if (!user) {
+5 -9
View File
@@ -3,23 +3,19 @@ const catchAsyncErrors = require("../Middlewares/catchAsyncErrors.js");
const DB_connect = catchAsyncErrors(async () => {
try {
const dbUri = `${process.env.MONGODB_URI}/${process.env.DATABASE_NAME}?authSource=admin`;
const connectionInstance = await mongoose.connect(dbUri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
const connectionInstance = await mongoose.connect(
`${process.env.MONGODB_URI}/${process.env.DATABASE_NAME}`
);
if (!connectionInstance) {
console.log("MongoDB connection failed");
} else {
}
console.log(
"MongoDB connected Successfully to:",
"MongoDB connected Successfully on server : " +
connectionInstance.connection.host
);
}
} catch (error) {
console.log("MongoDB connection failed due to some error :", error);
}
});
module.exports = DB_connect;
-37
View File
@@ -1,37 +0,0 @@
# Base image
FROM node:22
# Metadata
LABEL maintainer="kshitijka"
LABEL version=1.1.0
LABEL description="Crop Compass is a centralized management dashboard designed for farmers, enabling them to efficiently oversee their farms while leveraging advanced AI technology for disease identification and more."
# Update and upgrade
RUN apt update && apt upgrade -y && \
apt clean all && rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -s /bin/bash nonroot
# Create working directory
RUN mkdir -p /app /home/nonroot
RUN chown -R nonroot:nonroot /app /home/nonroot
WORKDIR /app
# Switch user
USER nonroot
# Copy contents
COPY . .
# Generate a random hex token and write it to .env
#RUN echo "REFRESH_TOKEN_SECRET = $(openssl rand -hex 32)" >> /app/.env
# Install dependencies
RUN npm install
# Expose backend port
EXPOSE 8000
# Run backend
CMD ["node", "index.js"]
+1 -1
View File
@@ -2,7 +2,7 @@ const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./uploads");
cb(null, "./public/images");
},
filename: function (req, file, cb) {
-11
View File
@@ -1,11 +0,0 @@
const rateLimit = require("express-rate-limit");
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // limit each IP to 5 login requests per windowMs
message: "Too many login attempts. Try again in 15 minutes.",
standardHeaders: true,
legacyHeaders: false,
});
module.exports = { loginLimiter };
+1 -3
View File
@@ -19,13 +19,11 @@ const { checkAuthenticated } = require("../Middlewares/authentication.js");
const upload = require("../Middlewares/multer.js");
const { loginLimiter } = require("../Middlewares/rateLimiter");
const router = express.Router();
router.route("/register").post(registerUser);
router.route("/login").post(loginLimiter, loginUser);
router.route("/login").post(loginUser);
router.route("/password/forgot").post(forgetPassword);
+356
View File
@@ -1,3 +1,359 @@
// const {
// GoogleGenerativeAI,
// HarmCategory,
// HarmBlockThreshold,
// } = require("@google/generative-ai");
// const {
// GoogleGenerativeAI,
// HarmCategory,
// HarmBlockThreshold,
// } = require("@google/generative-ai");
// const dotenv = require("dotenv");
// dotenv.config({
// path: "./.env",
// });
// const apiKey = process.env.GEMINI_API_KEY;
// const genAI = new GoogleGenerativeAI(apiKey);
// const model = genAI.getGenerativeModel({
// model: "gemini-2.0-flash",
// });
// const generationConfig = {
// temperature: 1,
// topP: 0.95,
// topK: 40,
// maxOutputTokens: 8192,
// responseMimeType: "text/plain",
// };
// export async function run(message) {
// const chatSession = model.startChat({
// generationConfig,
// history: [
// {
// role: "user",
// parts: [
// {
// text: "AI Model Guidelines:\n\nContext Restriction: Only provide answers based on the content available on [Your Website Name]. Do not generate responses unrelated to the website's information.\nNo External Knowledge: If a user asks about a topic outside the websites scope, politely inform them that you can only assist with website-related queries.\nSafe & Ethical Responses: Do not answer harmful, illegal, controversial, or inappropriate questions. If such a query is detected, respond with a neutral message stating that the request cannot be fulfilled.\nAccuracy & Clarity: Ensure responses are factual, clear, and helpful, directly referencing available website data without assumptions or speculation.\n\nGreeting should be similar lto this :\nHello! 👋\nIm here to assist you with information available on [Your Website Name]. Heres what I can do:\n\n✅ Answer questions based on the content from this website.\n✅ Guide you through available services, features, and resources.\n✅ Help you navigate and find what you need.\n\nuse emoji when you feel like it makes sense and increases the user understanding",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Hello! 👋\n\nIm here to assist you with information available on [Your Website Name]. Heres what I can do:\n\n✅ Answer questions based on the content from this website.\n✅ Guide you through available services, features, and resources.\n✅ Help you navigate and find what you need.\n\nHow can I help you today? 😃\n",
// },
// ],
// },
// {
// role: "user",
// parts: [{ text: "forget everythings until now " }],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I am now reset and ready to assist you with information available on [Your Website Name], adhering to the guidelines. How can I help you?\n",
// },
// ],
// },
// {
// role: "user",
// parts: [
// {
// text: "you will get some json or js object which will be some questions related to farming, you have to answer those questions and give proper description which is neccessary for a farmer to have if you recommend some kind of poisonous pestiside or something give a small warning and some things to keep some precausetions, dont answer anything unrelated to farming and strictly avoid harmful topics like war or viiolence, if farmer wants to kill pestisides then thats ok but anything else is not \n ",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will answer questions related to farming based on the content available on [Your Website Name]. I will provide detailed descriptions where necessary, including precautions when recommending potentially harmful pesticides. I will strictly avoid topics unrelated to farming or any harmful subjects. Please provide the JSON or JS object containing the questions. I'm ready! 🚜\n",
// },
// ],
// },
// {
// role: "user",
// parts: [
// {
// text: "keep the warning and precuastions short, and you are not a chatbot you are a data processing unit who will have the data and analyze it and answer accordingly\n ",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will function as a data processing unit, analyzing the provided data related to farming and answering questions with concise warnings and precautions where applicable. I will not engage in conversational chatbot behavior. Please provide the data. I'm ready to process! 👩‍🌾\n",
// },
// ],
// },
// ],
// });
// const result = await chatSession.sendMessage(message);
// console.log(result.response.text());
// }
// const {
// GoogleGenerativeAI,
// HarmCategory,
// HarmBlockThreshold,
// } = require("@google/generative-ai");
// const apiKey = "AIzaSyDsXug23r4umgcJpj77KeqNyYW0hQnYDgg";
// const genAI = new GoogleGenerativeAI(apiKey);
// const model = genAI.getGenerativeModel({
// model: "gemini-2.0-flash",
// });
// const generationConfig = {
// temperature: 1,
// topP: 0.95,
// topK: 40,
// maxOutputTokens: 8192,
// responseMimeType: "text/plain",
// };
// async function run(message) {
// const chatSession = model.startChat({
// generationConfig,
// history: [
// {
// role: "user",
// parts: [
// {
// text: "you will get some json or js object which will be some questions related to farming, you have to answer those questions and give proper description which is neccessary for a farmer to have if you recommend some kind of poisonous pestiside or something give a small warning and some things to keep some precausetions, dont answer anything unrelated to farming and strictly avoid harmful topics like war or viiolence, if farmer wants to kill pestisides then thats ok but anything else is not \n ",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will answer questions related to farming based on the content available on [Your Website Name]. I will provide detailed descriptions where necessary, including precautions when recommending potentially harmful pesticides. I will strictly avoid topics unrelated to farming or any harmful subjects. Please provide the JSON or JS object containing the questions. I'm ready! 🚜\n",
// },
// ],
// },
// {
// role: "user",
// parts: [
// {
// text: "keep the warning and precuastions short, and you are not a chatbot you are a data processing unit who will have the data and analyze it and answer accordingly\n ",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will function as a data processing unit, analyzing the provided data related to farming and answering questions with concise warnings and precautions where applicable. I will not engage in conversational chatbot behavior. Please provide the data. I'm ready to process! 👩‍🌾\n",
// },
// ],
// },
// ],
// });
// const result = await chatSession.sendMessage(message);
// console.log(result.response.text());
// }
// run("How we check the farmes soil type ? ");
// const {
// GoogleGenerativeAI,
// HarmCategory,
// HarmBlockThreshold,
// } = require("@google/generative-ai");
// const apiKey = "AIzaSyDsXug23r4umgcJpj77KeqNyYW0hQnYDgg";
// const genAI = new GoogleGenerativeAI(apiKey);
// const model = genAI.getGenerativeModel({
// model: "gemini-2.0-flash",
// });
// const generationConfig = {
// temperature: 1,
// topP: 0.95,
// topK: 40,
// maxOutputTokens: 8192,
// responseMimeType: "text/plain",
// };
// async function run(message) {
// const chatSession = model.startChat({
// generationConfig,
// history: [
// {
// role: "user",
// parts: [
// {
// text: "AI Guidelines:\n- The AI must only provide answers related to farming, including crops, sowing, irrigation, harvesting, fertilizers, pesticides, soil health, and climate conditions. \n- The AI must not answer anything outside farming. \n- If asked an unrelated question, the AI must not respond. \n- If the query is unclear, the AI must default to farming-related guidance. \n- The AI must provide only one-line responses without extra details. \n- No harmful, hurtful, or controversial responses. \n- No advice on illegal, unsafe, or unethical farming practices.\n",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will only provide one-line responses directly related to farming.\n",
// },
// ],
// },
// ],
// });
// const result = await chatSession.sendMessage(message);
// console.log(result.response.text());
// }
// const {
// GoogleGenerativeAI,
// HarmCategory,
// HarmBlockThreshold,
// } = require("@google/generative-ai");
// const apiKey = "AIzaSyDsXug23r4umgcJpj77KeqNyYW0hQnYDgg";
// const genAI = new GoogleGenerativeAI(apiKey);
// const model = genAI.getGenerativeModel({
// model: "gemini-2.0-flash",
// });
// const generationConfig = {
// temperature: 1,
// topP: 0.95,
// topK: 40,
// maxOutputTokens: 8192,
// responseMimeType: "text/plain",
// };
// async function run() {
// const chatSession = model.startChat({
// generationConfig,
// history: [
// {
// role: "user",
// parts: [
// {
// text: "AI Guidelines:\n- The AI must only provide answers related to farming, including crops, sowing, irrigation, harvesting, fertilizers, pesticides, soil health, and climate conditions. \n- The AI must not answer anything outside farming. \n- If asked an unrelated question, the AI must not respond. \n- If the query is unclear, the AI must default to farming-related guidance. \n- The AI must provide only one-line responses without extra details. \n- No harmful, hurtful, or controversial responses. \n- No advice on illegal, unsafe, or unethical farming practices.\n",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will only provide one-line responses directly related to farming.\n",
// },
// ],
// },
// {
// role: "user",
// parts: [
// {
// text: "you can also receive json or javascript object as an input ",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will process the JSON or JavaScript object only if it pertains to farming and respond with a single line.\n",
// },
// ],
// },
// ],
// });
// const result = await chatSession.sendMessage("INSERT_INPUT_HERE");
// console.log(result.response.text());
// }
// const {
// GoogleGenerativeAI,
// HarmCategory,
// HarmBlockThreshold,
// } = require("@google/generative-ai");
// const apiKey = "AIzaSyDsXug23r4umgcJpj77KeqNyYW0hQnYDgg";
// const genAI = new GoogleGenerativeAI(apiKey);
// const model = genAI.getGenerativeModel({
// model: "gemini-2.0-flash",
// });
// const generationConfig = {
// temperature: 1,
// topP: 0.95,
// topK: 40,
// maxOutputTokens: 8192,
// responseMimeType: "text/plain",
// };
// async function run(message) {
// const chatSession = model.startChat({
// generationConfig,
// history: [
// {
// role: "user",
// parts: [
// {
// text: "AI Guidelines:\n- The AI must only provide answers related to farming, including crops, sowing, irrigation, harvesting, fertilizers, pesticides, soil health, and climate conditions. \n- The AI must not answer anything outside farming. \n- If asked an unrelated question, the AI must not respond. \n- If the query is unclear, the AI must default to farming-related guidance. \n- The AI must provide only one-line responses without extra details. \n- No harmful, hurtful, or controversial responses. \n- No advice on illegal, unsafe, or unethical farming practices.\n",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will only provide one-line responses directly related to farming.\n",
// },
// ],
// },
// {
// role: "user",
// parts: [
// {
// text: "you can also receive json or javascript object as an input ",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will process the JSON or JavaScript object only if it pertains to farming and respond with a single line.\n",
// },
// ],
// },
// {
// role: "user",
// parts: [
// {
// text: "Answer everything which falls under the farming and agriculture even if the prompt does not include any farm or agriculture word in it",
// },
// ],
// },
// {
// role: "model",
// parts: [
// {
// text: "Understood. I will assume all queries are related to farming and provide a one-line farming-related response.\n",
// },
// ],
// },
// ],
// });
// const result = await chatSession.sendMessage(message);
// console.log(result.response.text());
// return result.response.text();
// }
const {
GoogleGenerativeAI,
HarmCategory,
+2 -11
View File
@@ -1,7 +1,6 @@
const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const helmet = require("helmet");
const userRoute = require("./Routes/user.routes.js");
const farmRoute = require("./Routes/farm.routes.js");
@@ -18,8 +17,6 @@ dotenv.config({
const app = express();
app.use(helmet()); // Secure headers
const corsOptions = {
origin: process.env.FRONTEND_URI,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
@@ -33,7 +30,7 @@ app.use(express.static("public"));
app.use(cookieParser());
app.get("/", (req, res) => {
return res.send("Server is running...");
return res.send("Hiddskpkpk...");
});
app.use("/api/v1", userRoute);
@@ -46,12 +43,6 @@ app.use("/api/v1/finance", financeRoute);
app.use("/api/v1/task", taskRoute);
// Redirect HTTP to HTTPS (works behind proxy)
app.use((req, res, next) => {
if (req.headers["x-forwarded-proto"] !== "https" && process.env.NODE_ENV === "production") {
return res.redirect(`https://${req.headers.host}${req.url}`);
}
next();
});
module.exports = app;
+4823
View File
File diff suppressed because it is too large Load Diff
+15 -16
View File
@@ -1,6 +1,6 @@
{
"name": "backend",
"version": "1.1.0",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
@@ -10,24 +10,23 @@
"license": "ISC",
"description": "",
"dependencies": {
"@google/generative-ai": "^0.24.1",
"axios": "^1.6.8",
"bcrypt": "^6.0.0",
"cloudinary": "^2.7.0",
"cookie-parser": "^1.4.7",
"@google/generative-ai": "^0.22.0",
"@huggingface/transformers": "^3.3.3",
"@xenova/transformers": "^2.17.2",
"bcrypt": "^5.1.1",
"cloudinary": "^2.5.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.5.0",
"express": "^5.1.0",
"express-rate-limit": "^6.7.0",
"helmet": "^7.0.0",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"jimp": "^1.6.0",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.16.0",
"multer": "^2.0.1",
"nodemailer": "^7.0.3",
"sha1": "^1.1.1",
"socket.io": "^4.8.1"
"mongoose": "^8.6.1",
"multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.15",
"socket.io": "^4.7.5"
},
"devDependencies": {
"nodemon": "^3.1.10"
"nodemon": "^3.1.4"
}
}
+31
View File
@@ -0,0 +1,31 @@
import { pipeline } from "@xenova/transformers";
import Jimp from "jimp";
async function main() {
const modelName = "Xenova/distilbert-base-uncased-finetuned-sst-2-english"; // Example model
// Load the model
const classifier = await pipeline("image-classification", modelName);
// Load the image
let image;
try {
image = await Jimp.read("/home/karan/Downloads/tomato.png");
image.rgba(true);
} catch (error) {
console.error("Error: Unable to open image. Check the file type or path.");
console.error(error);
return;
}
// Convert image to buffer
const buffer = await image.getBufferAsync(Jimp.MIME_PNG);
// Classify the image
const result = await classifier(buffer);
console.log("Predicted class:", result);
}
main().catch(console.error);
-8
View File
@@ -1,8 +0,0 @@
dist/
Dockerfile
node_modules/
package-lock.json
README.md
vercel.json
.dockerignore
.gitignore
-1
View File
@@ -1 +0,0 @@
VITE_API_URL = ${BACKEND_URI}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
-142
View File
@@ -1,142 +0,0 @@
{
"hash": "2bafedf9",
"configHash": "7e00041b",
"lockfileHash": "a954eb91",
"browserHash": "c3bc7b53",
"optimized": {
"react": {
"src": "../../node_modules/react/index.js",
"file": "react.js",
"fileHash": "902ee93a",
"needsInterop": true
},
"react-dom/client": {
"src": "../../node_modules/react-dom/client.js",
"file": "react-dom_client.js",
"fileHash": "cfbeda6d",
"needsInterop": true
},
"react-router-dom": {
"src": "../../node_modules/react-router-dom/dist/index.js",
"file": "react-router-dom.js",
"fileHash": "216229fd",
"needsInterop": false
},
"react-redux": {
"src": "../../node_modules/react-redux/dist/react-redux.mjs",
"file": "react-redux.js",
"fileHash": "b9f679da",
"needsInterop": false
},
"@reduxjs/toolkit": {
"src": "../../node_modules/@reduxjs/toolkit/dist/redux-toolkit.modern.mjs",
"file": "@reduxjs_toolkit.js",
"fileHash": "13da79f3",
"needsInterop": false
},
"socket.io-client": {
"src": "../../node_modules/socket.io-client/build/esm/index.js",
"file": "socket__io-client.js",
"fileHash": "ab2fcae8",
"needsInterop": false
},
"react-icons/io": {
"src": "../../node_modules/react-icons/io/index.mjs",
"file": "react-icons_io.js",
"fileHash": "fb80952c",
"needsInterop": false
},
"react-icons/fa6": {
"src": "../../node_modules/react-icons/fa6/index.mjs",
"file": "react-icons_fa6.js",
"fileHash": "da456fb8",
"needsInterop": false
},
"react-icons/ri": {
"src": "../../node_modules/react-icons/ri/index.mjs",
"file": "react-icons_ri.js",
"fileHash": "6e092d47",
"needsInterop": false
},
"react-icons/bs": {
"src": "../../node_modules/react-icons/bs/index.mjs",
"file": "react-icons_bs.js",
"fileHash": "c070a6ed",
"needsInterop": false
},
"react-icons/fa": {
"src": "../../node_modules/react-icons/fa/index.mjs",
"file": "react-icons_fa.js",
"fileHash": "aa81607f",
"needsInterop": false
},
"react-icons/md": {
"src": "../../node_modules/react-icons/md/index.mjs",
"file": "react-icons_md.js",
"fileHash": "60d442c6",
"needsInterop": false
},
"react-icons/io5": {
"src": "../../node_modules/react-icons/io5/index.mjs",
"file": "react-icons_io5.js",
"fileHash": "5d65fe60",
"needsInterop": false
},
"framer-motion": {
"src": "../../node_modules/framer-motion/dist/es/index.mjs",
"file": "framer-motion.js",
"fileHash": "05223771",
"needsInterop": false
},
"react-intersection-observer": {
"src": "../../node_modules/react-intersection-observer/dist/index.mjs",
"file": "react-intersection-observer.js",
"fileHash": "575187c6",
"needsInterop": false
},
"react-chartjs-2": {
"src": "../../node_modules/react-chartjs-2/dist/index.js",
"file": "react-chartjs-2.js",
"fileHash": "07d12b80",
"needsInterop": false
},
"chart.js": {
"src": "../../node_modules/chart.js/dist/chart.js",
"file": "chart__js.js",
"fileHash": "39dbe037",
"needsInterop": false
},
"react-apexcharts": {
"src": "../../node_modules/react-apexcharts/dist/react-apexcharts.min.js",
"file": "react-apexcharts.js",
"fileHash": "2bdb7b94",
"needsInterop": true
},
"react-typewriter-effect": {
"src": "../../node_modules/react-typewriter-effect/dist/index.js",
"file": "react-typewriter-effect.js",
"fileHash": "574603a4",
"needsInterop": true
}
},
"chunks": {
"chunk-UU7TO5PY": {
"file": "chunk-UU7TO5PY.js"
},
"chunk-2YIK36WJ": {
"file": "chunk-2YIK36WJ.js"
},
"chunk-UHINIFCJ": {
"file": "chunk-UHINIFCJ.js"
},
"chunk-SD42HLFO": {
"file": "chunk-SD42HLFO.js"
},
"chunk-W4EHDCLL": {
"file": "chunk-W4EHDCLL.js"
},
"chunk-EWTE5DHJ": {
"file": "chunk-EWTE5DHJ.js"
}
}
}
-100
View File
@@ -1,100 +0,0 @@
import {
Animation,
Animations,
ArcElement,
BarController,
BarElement,
BasePlatform,
BasicPlatform,
BubbleController,
CategoryScale,
Chart,
DatasetController,
DomPlatform,
DoughnutController,
Element,
Interaction,
LineController,
LineElement,
LinearScale,
LogarithmicScale,
PieController,
PointElement,
PolarAreaController,
RadarController,
RadialLinearScale,
Scale,
ScatterController,
Ticks,
TimeScale,
TimeSeriesScale,
_detectPlatform,
adapters,
animator,
controllers,
defaults,
elements,
index,
layouts,
plugin_colors,
plugin_decimation,
plugin_legend,
plugin_subtitle,
plugin_title,
plugin_tooltip,
plugins,
registerables,
registry,
scales
} from "./chunk-2YIK36WJ.js";
import "./chunk-EWTE5DHJ.js";
export {
Animation,
Animations,
ArcElement,
BarController,
BarElement,
BasePlatform,
BasicPlatform,
BubbleController,
CategoryScale,
Chart,
plugin_colors as Colors,
DatasetController,
plugin_decimation as Decimation,
DomPlatform,
DoughnutController,
Element,
index as Filler,
Interaction,
plugin_legend as Legend,
LineController,
LineElement,
LinearScale,
LogarithmicScale,
PieController,
PointElement,
PolarAreaController,
RadarController,
RadialLinearScale,
Scale,
ScatterController,
plugin_subtitle as SubTitle,
Ticks,
TimeScale,
TimeSeriesScale,
plugin_title as Title,
plugin_tooltip as Tooltip,
adapters as _adapters,
_detectPlatform,
animator,
controllers,
defaults,
elements,
layouts,
plugins,
registerables,
registry,
scales
};
//# sourceMappingURL=chart__js.js.map
-7
View File
@@ -1,7 +0,0 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
-45
View File
@@ -1,45 +0,0 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
export {
__esm,
__commonJS,
__export,
__toESM,
__toCommonJS,
__publicField
};
//# sourceMappingURL=chunk-EWTE5DHJ.js.map
@@ -1,7 +0,0 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}
-149
View File
@@ -1,149 +0,0 @@
import {
require_react
} from "./chunk-W4EHDCLL.js";
import {
__toESM
} from "./chunk-EWTE5DHJ.js";
// node_modules/react-icons/lib/iconBase.mjs
var import_react2 = __toESM(require_react(), 1);
// node_modules/react-icons/lib/iconContext.mjs
var import_react = __toESM(require_react(), 1);
var DefaultContext = {
color: void 0,
size: void 0,
className: void 0,
style: void 0,
attr: void 0
};
var IconContext = import_react.default.createContext && import_react.default.createContext(DefaultContext);
// node_modules/react-icons/lib/iconBase.mjs
var _excluded = ["attr", "size", "title"];
function _objectWithoutProperties(source, excluded) {
if (source == null) return {};
var target = _objectWithoutPropertiesLoose(source, excluded);
var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {
key = sourceSymbolKeys[i];
if (excluded.indexOf(key) >= 0) continue;
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
target[key] = source[key];
}
}
return target;
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
}
return target;
}
function _extends() {
_extends = Object.assign ? Object.assign.bind() : function(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function(r2) {
return Object.getOwnPropertyDescriptor(e, r2).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), true).forEach(function(r2) {
_defineProperty(e, r2, t[r2]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r2) {
Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2));
});
}
return e;
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) {
Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true });
} else {
obj[key] = value;
}
return obj;
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function Tree2Element(tree) {
return tree && tree.map((node, i) => import_react2.default.createElement(node.tag, _objectSpread({
key: i
}, node.attr), Tree2Element(node.child)));
}
function GenIcon(data) {
return (props) => import_react2.default.createElement(IconBase, _extends({
attr: _objectSpread({}, data.attr)
}, props), Tree2Element(data.child));
}
function IconBase(props) {
var elem = (conf) => {
var {
attr,
size,
title
} = props, svgProps = _objectWithoutProperties(props, _excluded);
var computedSize = size || conf.size || "1em";
var className;
if (conf.className) className = conf.className;
if (props.className) className = (className ? className + " " : "") + props.className;
return import_react2.default.createElement("svg", _extends({
stroke: "currentColor",
fill: "currentColor",
strokeWidth: "0"
}, conf.attr, attr, svgProps, {
className,
style: _objectSpread(_objectSpread({
color: props.color || conf.color
}, conf.style), props.style),
height: computedSize,
width: computedSize,
xmlns: "http://www.w3.org/2000/svg"
}), title && import_react2.default.createElement("title", null, title), props.children);
};
return IconContext !== void 0 ? import_react2.default.createElement(IconContext.Consumer, null, (conf) => elem(conf)) : elem(DefaultContext);
}
export {
GenIcon
};
//# sourceMappingURL=chunk-SD42HLFO.js.map
@@ -1,7 +0,0 @@
{
"version": 3,
"sources": ["../../node_modules/react-icons/lib/iconBase.mjs", "../../node_modules/react-icons/lib/iconContext.mjs"],
"sourcesContent": ["var _excluded = [\"attr\", \"size\", \"title\"];\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } } return target; }\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nfunction ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }\nfunction _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nimport React from \"react\";\nimport { IconContext, DefaultContext } from \"./iconContext.mjs\";\nfunction Tree2Element(tree) {\n return tree && tree.map((node, i) => /*#__PURE__*/React.createElement(node.tag, _objectSpread({\n key: i\n }, node.attr), Tree2Element(node.child)));\n}\nexport function GenIcon(data) {\n return props => /*#__PURE__*/React.createElement(IconBase, _extends({\n attr: _objectSpread({}, data.attr)\n }, props), Tree2Element(data.child));\n}\nexport function IconBase(props) {\n var elem = conf => {\n var {\n attr,\n size,\n title\n } = props,\n svgProps = _objectWithoutProperties(props, _excluded);\n var computedSize = size || conf.size || \"1em\";\n var className;\n if (conf.className) className = conf.className;\n if (props.className) className = (className ? className + \" \" : \"\") + props.className;\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n stroke: \"currentColor\",\n fill: \"currentColor\",\n strokeWidth: \"0\"\n }, conf.attr, attr, svgProps, {\n className: className,\n style: _objectSpread(_objectSpread({\n color: props.color || conf.color\n }, conf.style), props.style),\n height: computedSize,\n width: computedSize,\n xmlns: \"http://www.w3.org/2000/svg\"\n }), title && /*#__PURE__*/React.createElement(\"title\", null, title), props.children);\n };\n return IconContext !== undefined ? /*#__PURE__*/React.createElement(IconContext.Consumer, null, conf => elem(conf)) : elem(DefaultContext);\n}", "import React from \"react\";\nexport var DefaultContext = {\n color: undefined,\n size: undefined,\n className: undefined,\n style: undefined,\n attr: undefined\n};\nexport var IconContext = React.createContext && /*#__PURE__*/React.createContext(DefaultContext);"],
"mappings": ";;;;;;;;AASA,IAAAA,gBAAkB;;;ACTlB,mBAAkB;AACX,IAAI,iBAAiB;AAAA,EAC1B,OAAO;AAAA,EACP,MAAM;AAAA,EACN,WAAW;AAAA,EACX,OAAO;AAAA,EACP,MAAM;AACR;AACO,IAAI,cAAc,aAAAC,QAAM,iBAA8B,aAAAA,QAAM,cAAc,cAAc;;;ADR/F,IAAI,YAAY,CAAC,QAAQ,QAAQ,OAAO;AACxC,SAAS,yBAAyB,QAAQ,UAAU;AAAE,MAAI,UAAU,KAAM,QAAO,CAAC;AAAG,MAAI,SAAS,8BAA8B,QAAQ,QAAQ;AAAG,MAAI,KAAK;AAAG,MAAI,OAAO,uBAAuB;AAAE,QAAI,mBAAmB,OAAO,sBAAsB,MAAM;AAAG,SAAK,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;AAAE,YAAM,iBAAiB,CAAC;AAAG,UAAI,SAAS,QAAQ,GAAG,KAAK,EAAG;AAAU,UAAI,CAAC,OAAO,UAAU,qBAAqB,KAAK,QAAQ,GAAG,EAAG;AAAU,aAAO,GAAG,IAAI,OAAO,GAAG;AAAA,IAAG;AAAA,EAAE;AAAE,SAAO;AAAQ;AAC3e,SAAS,8BAA8B,QAAQ,UAAU;AAAE,MAAI,UAAU,KAAM,QAAO,CAAC;AAAG,MAAI,SAAS,CAAC;AAAG,WAAS,OAAO,QAAQ;AAAE,QAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,GAAG;AAAE,UAAI,SAAS,QAAQ,GAAG,KAAK,EAAG;AAAU,aAAO,GAAG,IAAI,OAAO,GAAG;AAAA,IAAG;AAAA,EAAE;AAAE,SAAO;AAAQ;AACtR,SAAS,WAAW;AAAE,aAAW,OAAO,SAAS,OAAO,OAAO,KAAK,IAAI,SAAU,QAAQ;AAAE,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AAAE,UAAI,SAAS,UAAU,CAAC;AAAG,eAAS,OAAO,QAAQ;AAAE,YAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,GAAG;AAAE,iBAAO,GAAG,IAAI,OAAO,GAAG;AAAA,QAAG;AAAA,MAAE;AAAA,IAAE;AAAE,WAAO;AAAA,EAAQ;AAAG,SAAO,SAAS,MAAM,MAAM,SAAS;AAAG;AAClV,SAAS,QAAQ,GAAG,GAAG;AAAE,MAAI,IAAI,OAAO,KAAK,CAAC;AAAG,MAAI,OAAO,uBAAuB;AAAE,QAAI,IAAI,OAAO,sBAAsB,CAAC;AAAG,UAAM,IAAI,EAAE,OAAO,SAAUC,IAAG;AAAE,aAAO,OAAO,yBAAyB,GAAGA,EAAC,EAAE;AAAA,IAAY,CAAC,IAAI,EAAE,KAAK,MAAM,GAAG,CAAC;AAAA,EAAG;AAAE,SAAO;AAAG;AAC9P,SAAS,cAAc,GAAG;AAAE,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AAAE,QAAI,IAAI,QAAQ,UAAU,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;AAAG,QAAI,IAAI,QAAQ,OAAO,CAAC,GAAG,IAAE,EAAE,QAAQ,SAAUA,IAAG;AAAE,sBAAgB,GAAGA,IAAG,EAAEA,EAAC,CAAC;AAAA,IAAG,CAAC,IAAI,OAAO,4BAA4B,OAAO,iBAAiB,GAAG,OAAO,0BAA0B,CAAC,CAAC,IAAI,QAAQ,OAAO,CAAC,CAAC,EAAE,QAAQ,SAAUA,IAAG;AAAE,aAAO,eAAe,GAAGA,IAAG,OAAO,yBAAyB,GAAGA,EAAC,CAAC;AAAA,IAAG,CAAC;AAAA,EAAG;AAAE,SAAO;AAAG;AACtb,SAAS,gBAAgB,KAAK,KAAK,OAAO;AAAE,QAAM,eAAe,GAAG;AAAG,MAAI,OAAO,KAAK;AAAE,WAAO,eAAe,KAAK,KAAK,EAAE,OAAc,YAAY,MAAM,cAAc,MAAM,UAAU,KAAK,CAAC;AAAA,EAAG,OAAO;AAAE,QAAI,GAAG,IAAI;AAAA,EAAO;AAAE,SAAO;AAAK;AAC3O,SAAS,eAAe,GAAG;AAAE,MAAI,IAAI,aAAa,GAAG,QAAQ;AAAG,SAAO,YAAY,OAAO,IAAI,IAAI,IAAI;AAAI;AAC1G,SAAS,aAAa,GAAG,GAAG;AAAE,MAAI,YAAY,OAAO,KAAK,CAAC,EAAG,QAAO;AAAG,MAAI,IAAI,EAAE,OAAO,WAAW;AAAG,MAAI,WAAW,GAAG;AAAE,QAAI,IAAI,EAAE,KAAK,GAAG,KAAK,SAAS;AAAG,QAAI,YAAY,OAAO,EAAG,QAAO;AAAG,UAAM,IAAI,UAAU,8CAA8C;AAAA,EAAG;AAAE,UAAQ,aAAa,IAAI,SAAS,QAAQ,CAAC;AAAG;AAGvT,SAAS,aAAa,MAAM;AAC1B,SAAO,QAAQ,KAAK,IAAI,CAAC,MAAM,MAAmB,cAAAC,QAAM,cAAc,KAAK,KAAK,cAAc;AAAA,IAC5F,KAAK;AAAA,EACP,GAAG,KAAK,IAAI,GAAG,aAAa,KAAK,KAAK,CAAC,CAAC;AAC1C;AACO,SAAS,QAAQ,MAAM;AAC5B,SAAO,WAAsB,cAAAA,QAAM,cAAc,UAAU,SAAS;AAAA,IAClE,MAAM,cAAc,CAAC,GAAG,KAAK,IAAI;AAAA,EACnC,GAAG,KAAK,GAAG,aAAa,KAAK,KAAK,CAAC;AACrC;AACO,SAAS,SAAS,OAAO;AAC9B,MAAI,OAAO,UAAQ;AACjB,QAAI;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,OACJ,WAAW,yBAAyB,OAAO,SAAS;AACtD,QAAI,eAAe,QAAQ,KAAK,QAAQ;AACxC,QAAI;AACJ,QAAI,KAAK,UAAW,aAAY,KAAK;AACrC,QAAI,MAAM,UAAW,cAAa,YAAY,YAAY,MAAM,MAAM,MAAM;AAC5E,WAAoB,cAAAA,QAAM,cAAc,OAAO,SAAS;AAAA,MACtD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,aAAa;AAAA,IACf,GAAG,KAAK,MAAM,MAAM,UAAU;AAAA,MAC5B;AAAA,MACA,OAAO,cAAc,cAAc;AAAA,QACjC,OAAO,MAAM,SAAS,KAAK;AAAA,MAC7B,GAAG,KAAK,KAAK,GAAG,MAAM,KAAK;AAAA,MAC3B,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,IACT,CAAC,GAAG,SAAsB,cAAAA,QAAM,cAAc,SAAS,MAAM,KAAK,GAAG,MAAM,QAAQ;AAAA,EACrF;AACA,SAAO,gBAAgB,SAAyB,cAAAA,QAAM,cAAc,YAAY,UAAU,MAAM,UAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,cAAc;AAC3I;",
"names": ["import_react", "React", "r", "React"]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
-172
View File
@@ -1,172 +0,0 @@
import {
__commonJS
} from "./chunk-EWTE5DHJ.js";
// node_modules/object-assign/index.js
var require_object_assign = __commonJS({
"node_modules/object-assign/index.js"(exports, module) {
"use strict";
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
function toObject(val) {
if (val === null || val === void 0) {
throw new TypeError("Object.assign cannot be called with null or undefined");
}
return Object(val);
}
function shouldUseNative() {
try {
if (!Object.assign) {
return false;
}
var test1 = new String("abc");
test1[5] = "de";
if (Object.getOwnPropertyNames(test1)[0] === "5") {
return false;
}
var test2 = {};
for (var i = 0; i < 10; i++) {
test2["_" + String.fromCharCode(i)] = i;
}
var order2 = Object.getOwnPropertyNames(test2).map(function(n) {
return test2[n];
});
if (order2.join("") !== "0123456789") {
return false;
}
var test3 = {};
"abcdefghijklmnopqrst".split("").forEach(function(letter) {
test3[letter] = letter;
});
if (Object.keys(Object.assign({}, test3)).join("") !== "abcdefghijklmnopqrst") {
return false;
}
return true;
} catch (err) {
return false;
}
}
module.exports = shouldUseNative() ? Object.assign : function(target, source) {
var from;
var to = toObject(target);
var symbols;
for (var s = 1; s < arguments.length; s++) {
from = Object(arguments[s]);
for (var key in from) {
if (hasOwnProperty.call(from, key)) {
to[key] = from[key];
}
}
if (getOwnPropertySymbols) {
symbols = getOwnPropertySymbols(from);
for (var i = 0; i < symbols.length; i++) {
if (propIsEnumerable.call(from, symbols[i])) {
to[symbols[i]] = from[symbols[i]];
}
}
}
}
return to;
};
}
});
// node_modules/prop-types/lib/ReactPropTypesSecret.js
var require_ReactPropTypesSecret = __commonJS({
"node_modules/prop-types/lib/ReactPropTypesSecret.js"(exports, module) {
"use strict";
var ReactPropTypesSecret = "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";
module.exports = ReactPropTypesSecret;
}
});
// node_modules/prop-types/lib/has.js
var require_has = __commonJS({
"node_modules/prop-types/lib/has.js"(exports, module) {
module.exports = Function.call.bind(Object.prototype.hasOwnProperty);
}
});
// node_modules/prop-types/checkPropTypes.js
var require_checkPropTypes = __commonJS({
"node_modules/prop-types/checkPropTypes.js"(exports, module) {
"use strict";
var printWarning = function() {
};
if (true) {
ReactPropTypesSecret = require_ReactPropTypesSecret();
loggedTypeFailures = {};
has = require_has();
printWarning = function(text) {
var message = "Warning: " + text;
if (typeof console !== "undefined") {
console.error(message);
}
try {
throw new Error(message);
} catch (x) {
}
};
}
var ReactPropTypesSecret;
var loggedTypeFailures;
var has;
function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
if (true) {
for (var typeSpecName in typeSpecs) {
if (has(typeSpecs, typeSpecName)) {
var error;
try {
if (typeof typeSpecs[typeSpecName] !== "function") {
var err = Error(
(componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."
);
err.name = "Invariant Violation";
throw err;
}
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
} catch (ex) {
error = ex;
}
if (error && !(error instanceof Error)) {
printWarning(
(componentName || "React class") + ": type specification of " + location + " `" + typeSpecName + "` is invalid; the type checker function must return `null` or an `Error` but returned a " + typeof error + ". You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument)."
);
}
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
loggedTypeFailures[error.message] = true;
var stack = getStack ? getStack() : "";
printWarning(
"Failed " + location + " type: " + error.message + (stack != null ? stack : "")
);
}
}
}
}
}
checkPropTypes.resetWarningCache = function() {
if (true) {
loggedTypeFailures = {};
}
};
module.exports = checkPropTypes;
}
});
export {
require_object_assign,
require_ReactPropTypesSecret,
require_has,
require_checkPropTypes
};
/*! Bundled license information:
object-assign/index.js:
(*
object-assign
(c) Sindre Sorhus
@license MIT
*)
*/
//# sourceMappingURL=chunk-UU7TO5PY.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
-3
View File
@@ -1,3 +0,0 @@
{
"type": "module"
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-190
View File
@@ -1,190 +0,0 @@
import {
BarController,
BubbleController,
Chart,
DoughnutController,
LineController,
PieController,
PolarAreaController,
RadarController,
ScatterController
} from "./chunk-2YIK36WJ.js";
import {
require_react
} from "./chunk-W4EHDCLL.js";
import {
__toESM
} from "./chunk-EWTE5DHJ.js";
// node_modules/react-chartjs-2/dist/index.js
var import_react = __toESM(require_react());
var defaultDatasetIdKey = "label";
function reforwardRef(ref, value) {
if (typeof ref === "function") {
ref(value);
} else if (ref) {
ref.current = value;
}
}
function setOptions(chart, nextOptions) {
const options = chart.options;
if (options && nextOptions) {
Object.assign(options, nextOptions);
}
}
function setLabels(currentData, nextLabels) {
currentData.labels = nextLabels;
}
function setDatasets(currentData, nextDatasets) {
let datasetIdKey = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : defaultDatasetIdKey;
const addedDatasets = [];
currentData.datasets = nextDatasets.map((nextDataset) => {
const currentDataset = currentData.datasets.find((dataset) => dataset[datasetIdKey] === nextDataset[datasetIdKey]);
if (!currentDataset || !nextDataset.data || addedDatasets.includes(currentDataset)) {
return {
...nextDataset
};
}
addedDatasets.push(currentDataset);
Object.assign(currentDataset, nextDataset);
return currentDataset;
});
}
function cloneData(data) {
let datasetIdKey = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : defaultDatasetIdKey;
const nextData = {
labels: [],
datasets: []
};
setLabels(nextData, data.labels);
setDatasets(nextData, data.datasets, datasetIdKey);
return nextData;
}
function getDatasetAtEvent(chart, event) {
return chart.getElementsAtEventForMode(event.nativeEvent, "dataset", {
intersect: true
}, false);
}
function getElementAtEvent(chart, event) {
return chart.getElementsAtEventForMode(event.nativeEvent, "nearest", {
intersect: true
}, false);
}
function getElementsAtEvent(chart, event) {
return chart.getElementsAtEventForMode(event.nativeEvent, "index", {
intersect: true
}, false);
}
function ChartComponent(props, ref) {
const { height = 150, width = 300, redraw = false, datasetIdKey, type, data, options, plugins = [], fallbackContent, updateMode, ...canvasProps } = props;
const canvasRef = (0, import_react.useRef)(null);
const chartRef = (0, import_react.useRef)(null);
const renderChart = () => {
if (!canvasRef.current) return;
chartRef.current = new Chart(canvasRef.current, {
type,
data: cloneData(data, datasetIdKey),
options: options && {
...options
},
plugins
});
reforwardRef(ref, chartRef.current);
};
const destroyChart = () => {
reforwardRef(ref, null);
if (chartRef.current) {
chartRef.current.destroy();
chartRef.current = null;
}
};
(0, import_react.useEffect)(() => {
if (!redraw && chartRef.current && options) {
setOptions(chartRef.current, options);
}
}, [
redraw,
options
]);
(0, import_react.useEffect)(() => {
if (!redraw && chartRef.current) {
setLabels(chartRef.current.config.data, data.labels);
}
}, [
redraw,
data.labels
]);
(0, import_react.useEffect)(() => {
if (!redraw && chartRef.current && data.datasets) {
setDatasets(chartRef.current.config.data, data.datasets, datasetIdKey);
}
}, [
redraw,
data.datasets
]);
(0, import_react.useEffect)(() => {
if (!chartRef.current) return;
if (redraw) {
destroyChart();
setTimeout(renderChart);
} else {
chartRef.current.update(updateMode);
}
}, [
redraw,
options,
data.labels,
data.datasets,
updateMode
]);
(0, import_react.useEffect)(() => {
if (!chartRef.current) return;
destroyChart();
setTimeout(renderChart);
}, [
type
]);
(0, import_react.useEffect)(() => {
renderChart();
return () => destroyChart();
}, []);
return import_react.default.createElement("canvas", {
ref: canvasRef,
role: "img",
height,
width,
...canvasProps
}, fallbackContent);
}
var Chart2 = (0, import_react.forwardRef)(ChartComponent);
function createTypedChart(type, registerables) {
Chart.register(registerables);
return (0, import_react.forwardRef)((props, ref) => import_react.default.createElement(Chart2, {
...props,
ref,
type
}));
}
var Line = createTypedChart("line", LineController);
var Bar = createTypedChart("bar", BarController);
var Radar = createTypedChart("radar", RadarController);
var Doughnut = createTypedChart("doughnut", DoughnutController);
var PolarArea = createTypedChart("polarArea", PolarAreaController);
var Bubble = createTypedChart("bubble", BubbleController);
var Pie = createTypedChart("pie", PieController);
var Scatter = createTypedChart("scatter", ScatterController);
export {
Bar,
Bubble,
Chart2 as Chart,
Doughnut,
Line,
Pie,
PolarArea,
Radar,
Scatter,
getDatasetAtEvent,
getElementAtEvent,
getElementsAtEvent
};
//# sourceMappingURL=react-chartjs-2.js.map
File diff suppressed because one or more lines are too long
-39
View File
@@ -1,39 +0,0 @@
import {
require_react_dom
} from "./chunk-UHINIFCJ.js";
import "./chunk-W4EHDCLL.js";
import {
__commonJS
} from "./chunk-EWTE5DHJ.js";
// node_modules/react-dom/client.js
var require_client = __commonJS({
"node_modules/react-dom/client.js"(exports) {
var m = require_react_dom();
if (false) {
exports.createRoot = m.createRoot;
exports.hydrateRoot = m.hydrateRoot;
} else {
i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
exports.createRoot = function(c, o) {
i.usingClientEntryPoint = true;
try {
return m.createRoot(c, o);
} finally {
i.usingClientEntryPoint = false;
}
};
exports.hydrateRoot = function(c, h, o) {
i.usingClientEntryPoint = true;
try {
return m.hydrateRoot(c, h, o);
} finally {
i.usingClientEntryPoint = false;
}
};
}
var i;
}
});
export default require_client();
//# sourceMappingURL=react-dom_client.js.map
@@ -1,7 +0,0 @@
{
"version": 3,
"sources": ["../../node_modules/react-dom/client.js"],
"sourcesContent": ["'use strict';\n\nvar m = require('react-dom');\nif (process.env.NODE_ENV === 'production') {\n exports.createRoot = m.createRoot;\n exports.hydrateRoot = m.hydrateRoot;\n} else {\n var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n exports.createRoot = function(c, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.createRoot(c, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n exports.hydrateRoot = function(c, h, o) {\n i.usingClientEntryPoint = true;\n try {\n return m.hydrateRoot(c, h, o);\n } finally {\n i.usingClientEntryPoint = false;\n }\n };\n}\n"],
"mappings": ";;;;;;;;;AAAA;AAAA;AAEA,QAAI,IAAI;AACR,QAAI,OAAuC;AACzC,cAAQ,aAAa,EAAE;AACvB,cAAQ,cAAc,EAAE;AAAA,IAC1B,OAAO;AACD,UAAI,EAAE;AACV,cAAQ,aAAa,SAAS,GAAG,GAAG;AAClC,UAAE,wBAAwB;AAC1B,YAAI;AACF,iBAAO,EAAE,WAAW,GAAG,CAAC;AAAA,QAC1B,UAAE;AACA,YAAE,wBAAwB;AAAA,QAC5B;AAAA,MACF;AACA,cAAQ,cAAc,SAAS,GAAG,GAAG,GAAG;AACtC,UAAE,wBAAwB;AAC1B,YAAI;AACF,iBAAO,EAAE,YAAY,GAAG,GAAG,CAAC;AAAA,QAC9B,UAAE;AACA,YAAE,wBAAwB;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAjBM;AAAA;AAAA;",
"names": []
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
-293
View File
@@ -1,293 +0,0 @@
"use client";
import {
require_react
} from "./chunk-W4EHDCLL.js";
import {
__toESM
} from "./chunk-EWTE5DHJ.js";
// node_modules/react-intersection-observer/dist/index.mjs
var React = __toESM(require_react(), 1);
var React2 = __toESM(require_react(), 1);
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var observerMap = /* @__PURE__ */ new Map();
var RootIds = /* @__PURE__ */ new WeakMap();
var rootId = 0;
var unsupportedValue = void 0;
function defaultFallbackInView(inView) {
unsupportedValue = inView;
}
function getRootId(root) {
if (!root) return "0";
if (RootIds.has(root)) return RootIds.get(root);
rootId += 1;
RootIds.set(root, rootId.toString());
return RootIds.get(root);
}
function optionsToId(options) {
return Object.keys(options).sort().filter(
(key) => options[key] !== void 0
).map((key) => {
return `${key}_${key === "root" ? getRootId(options.root) : options[key]}`;
}).toString();
}
function createObserver(options) {
const id = optionsToId(options);
let instance = observerMap.get(id);
if (!instance) {
const elements = /* @__PURE__ */ new Map();
let thresholds;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
var _a;
const inView = entry.isIntersecting && thresholds.some((threshold) => entry.intersectionRatio >= threshold);
if (options.trackVisibility && typeof entry.isVisible === "undefined") {
entry.isVisible = inView;
}
(_a = elements.get(entry.target)) == null ? void 0 : _a.forEach((callback) => {
callback(inView, entry);
});
});
}, options);
thresholds = observer.thresholds || (Array.isArray(options.threshold) ? options.threshold : [options.threshold || 0]);
instance = {
id,
observer,
elements
};
observerMap.set(id, instance);
}
return instance;
}
function observe(element, callback, options = {}, fallbackInView = unsupportedValue) {
if (typeof window.IntersectionObserver === "undefined" && fallbackInView !== void 0) {
const bounds = element.getBoundingClientRect();
callback(fallbackInView, {
isIntersecting: fallbackInView,
target: element,
intersectionRatio: typeof options.threshold === "number" ? options.threshold : 0,
time: 0,
boundingClientRect: bounds,
intersectionRect: bounds,
rootBounds: bounds
});
return () => {
};
}
const { id, observer, elements } = createObserver(options);
const callbacks = elements.get(element) || [];
if (!elements.has(element)) {
elements.set(element, callbacks);
}
callbacks.push(callback);
observer.observe(element);
return function unobserve() {
callbacks.splice(callbacks.indexOf(callback), 1);
if (callbacks.length === 0) {
elements.delete(element);
observer.unobserve(element);
}
if (elements.size === 0) {
observer.disconnect();
observerMap.delete(id);
}
};
}
function isPlainChildren(props) {
return typeof props.children !== "function";
}
var InView = class extends React.Component {
constructor(props) {
super(props);
__publicField(this, "node", null);
__publicField(this, "_unobserveCb", null);
__publicField(this, "handleNode", (node) => {
if (this.node) {
this.unobserve();
if (!node && !this.props.triggerOnce && !this.props.skip) {
this.setState({ inView: !!this.props.initialInView, entry: void 0 });
}
}
this.node = node ? node : null;
this.observeNode();
});
__publicField(this, "handleChange", (inView, entry) => {
if (inView && this.props.triggerOnce) {
this.unobserve();
}
if (!isPlainChildren(this.props)) {
this.setState({ inView, entry });
}
if (this.props.onChange) {
this.props.onChange(inView, entry);
}
});
this.state = {
inView: !!props.initialInView,
entry: void 0
};
}
componentDidMount() {
this.unobserve();
this.observeNode();
}
componentDidUpdate(prevProps) {
if (prevProps.rootMargin !== this.props.rootMargin || prevProps.root !== this.props.root || prevProps.threshold !== this.props.threshold || prevProps.skip !== this.props.skip || prevProps.trackVisibility !== this.props.trackVisibility || prevProps.delay !== this.props.delay) {
this.unobserve();
this.observeNode();
}
}
componentWillUnmount() {
this.unobserve();
}
observeNode() {
if (!this.node || this.props.skip) return;
const {
threshold,
root,
rootMargin,
trackVisibility,
delay,
fallbackInView
} = this.props;
this._unobserveCb = observe(
this.node,
this.handleChange,
{
threshold,
root,
rootMargin,
// @ts-ignore
trackVisibility,
// @ts-ignore
delay
},
fallbackInView
);
}
unobserve() {
if (this._unobserveCb) {
this._unobserveCb();
this._unobserveCb = null;
}
}
render() {
const { children } = this.props;
if (typeof children === "function") {
const { inView, entry } = this.state;
return children({ inView, entry, ref: this.handleNode });
}
const {
as,
triggerOnce,
threshold,
root,
rootMargin,
onChange,
skip,
trackVisibility,
delay,
initialInView,
fallbackInView,
...props
} = this.props;
return React.createElement(
as || "div",
{ ref: this.handleNode, ...props },
children
);
}
};
function useInView({
threshold,
delay,
trackVisibility,
rootMargin,
root,
triggerOnce,
skip,
initialInView,
fallbackInView,
onChange
} = {}) {
var _a;
const [ref, setRef] = React2.useState(null);
const callback = React2.useRef(onChange);
const [state, setState] = React2.useState({
inView: !!initialInView,
entry: void 0
});
callback.current = onChange;
React2.useEffect(
() => {
if (skip || !ref) return;
let unobserve;
unobserve = observe(
ref,
(inView, entry) => {
setState({
inView,
entry
});
if (callback.current) callback.current(inView, entry);
if (entry.isIntersecting && triggerOnce && unobserve) {
unobserve();
unobserve = void 0;
}
},
{
root,
rootMargin,
threshold,
// @ts-ignore
trackVisibility,
// @ts-ignore
delay
},
fallbackInView
);
return () => {
if (unobserve) {
unobserve();
}
};
},
// We break the rule here, because we aren't including the actual `threshold` variable
// eslint-disable-next-line react-hooks/exhaustive-deps
[
// If the threshold is an array, convert it to a string, so it won't change between renders.
Array.isArray(threshold) ? threshold.toString() : threshold,
ref,
root,
rootMargin,
triggerOnce,
skip,
trackVisibility,
fallbackInView,
delay
]
);
const entryTarget = (_a = state.entry) == null ? void 0 : _a.target;
const previousEntryTarget = React2.useRef(void 0);
if (!ref && entryTarget && !triggerOnce && !skip && previousEntryTarget.current !== entryTarget) {
previousEntryTarget.current = entryTarget;
setState({
inView: !!initialInView,
entry: void 0
});
}
const result = [setRef, state.inView, state.entry];
result.ref = result[0];
result.inView = result[1];
result.entry = result[2];
return result;
}
export {
InView,
defaultFallbackInView,
observe,
useInView
};
//# sourceMappingURL=react-intersection-observer.js.map
File diff suppressed because one or more lines are too long
-1119
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
-6
View File
@@ -1,6 +0,0 @@
import {
require_react
} from "./chunk-W4EHDCLL.js";
import "./chunk-EWTE5DHJ.js";
export default require_react();
//# sourceMappingURL=react.js.map
-7
View File
@@ -1,7 +0,0 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
-48
View File
@@ -1,48 +0,0 @@
# Base image
FROM node:22
# Environment variables
ENV MODEL_URI=http://localhost:8081
ENV BACKEND_URI=http://localhost:8000
# Metadata
LABEL maintainer="kshitijka"
LABEL version=1.1.0
LABEL description="Crop Compass is a centralized management dashboard designed for farmers, enabling them to efficiently oversee their farms while leveraging advanced AI technology for disease identification and more."
# Update and upgrade
RUN apt update && apt upgrade -y && \
apt clean all && rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -s /bin/bash nonroot
# Create working directory
RUN mkdir -p /app
RUN chown -R nonroot:nonroot /app
WORKDIR /app
# Copying contents
COPY . .
# Writing backend uri in .env
RUN echo "VITE_API_URL = $BACKEND_URI" > /app/.env
# Building frontend
RUN npm install
RUN npm run build
# Clean-up
RUN rm -rf eslint.config.js index.html node_modules/ package-lock.json package.json postcss.config.js public/ src/ tailwind.config.js vite.config.js .dockerignore .gitignore .vite/
# Install server
RUN npm install -g serve
# Switch user
USER nonroot
# Expose frontend port
EXPOSE 3000
# Run frontend
CMD ["serve", "-s", "/app/dist"]
+2 -4
View File
@@ -1,7 +1,7 @@
{
"name": "frontend",
"private": true,
"version": "1.1.0",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
@@ -26,9 +26,7 @@
"react-redux": "^9.1.2",
"react-router-dom": "^6.26.1",
"react-typewriter-effect": "^1.1.0",
"socket.io-client": "^4.7.5",
"axios": "^1.6.8",
"sha1": "^1.1.1"
"socket.io-client": "^4.7.5"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 581 B

+13 -40
View File
@@ -1,70 +1,44 @@
import { useDispatch, useSelector } from "react-redux";
import "./App.css";
// import Navbar from "./components/Navbar";
//import Navbar from "./components/Navbar";
import Navbar2 from "./components/Navbar2";
import { useEffect, useState } from "react";
import { useEffect } from "react";
import { userSliceActions } from "./store/userSlice";
import { Outlet } from "react-router-dom";
import { BACKEND_URL } from "./constants";
// Simple LanguageSwitcher component
function LanguageSwitcher({ language, setLanguage }) {
return (
<select
value={language}
onChange={(e) => {
setLanguage(e.target.value);
localStorage.setItem("language", e.target.value);
}}
className="absolute top-2 right-2 p-1 rounded border"
aria-label="Select language"
>
<option value="en">English</option>
<option value="hi">Hindi (ि)</option>
<option value="mr">Marathi (मर)</option>
<option value="fr">Français</option>
{/* Add more languages here */}
</select>
);
}
function App() {
const user = useSelector((store) => store.user);
const dispatch = useDispatch();
const loader = useSelector((store) => store.loader);
// Language state, initialized from localStorage or default to 'en'
const [language, setLanguage] = useState(
localStorage.getItem("language") || "en"
);
console.log("Current language:", language);
useEffect(() => {
async function initialiseUser() {
if (user.role === "unloggeduser") {
if (user.role == "unloggeduser") {
const responce = await fetch(`${BACKEND_URL}/api/v1/getuser`, {
method: "GET",
credentials: "include",
});
const userData = await responce.json();
//console.log("User Datae is ", userData);
dispatch(userSliceActions.addUser(userData.data));
//console.log("Updated User is : ", user);
}
}
initialiseUser();
}, []);
return (
<>
<div className="w-full h-auto flex-col relative">
{/* 2. Language Switcher visible on all pages */}
<LanguageSwitcher language={language} setLanguage={setLanguage} />
{/* 3. Pass language as prop to Navbar2 and Outlet if needed */}
<Outlet context={{ language }} />
<div className="pt-20"></div>
<Outlet />
<div
className={`${
loader ? "block" : "hidden"
@@ -98,4 +72,3 @@ function App() {
}
export default App;
-13
View File
@@ -1,13 +0,0 @@
import React from "react";
const LanguageSwitcher = ({ currentLanguage, onChangeLanguage }) => (
<select value={currentLanguage} onChange={e => onChangeLanguage(e.target.value)}>
<option value="en">English</option>
<option value="hi">Hindi (ि)</option>
<option value="mr">Marathi (मर)</option>
<option value="fr">French (Français)</option>
{/* Add more languages as needed */}
</select>
);
export default LanguageSwitcher;
+1 -1
View File
@@ -3,7 +3,7 @@ import React from "react";
const Container = ({ children }) => {
return (
<>
<div className="w-full max-h-screen">{children}</div>
<div className="w-full h-auto">{children}</div>
</>
);
};
+16 -21
View File
@@ -1,29 +1,24 @@
import { useEffect, useState } from "react";
import Td from "./Td";
import Loader from "./Loader";
import { useGetFarmsQuery } from "../store/api/farmApi";
const FarmList = () => {
// const [data, setData] = useState([]);
// const [loading, setLoading] = useState(true);
const { data: farms, error, isLoading } = useGetFarmsQuery();
console.log(farms);
// useEffect(() => {
// fetch("http://localhost:8000/api/v1/farm", {
// credentials: "include",
// method: "GET",
// headers: { "Content-Type": "application/json" },
// })
// .then((response) => response.json())
// .then((data) => setData(data))
// .then(setLoading(false))
// .catch((error) => console.error(error));
// }, []);
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("http://localhost:8000/api/v1/farm", {
credentials: "include",
method: "GET",
headers: { "Content-Type": "application/json" },
})
.then((response) => response.json())
.then((data) => setData(data))
.then(setLoading(false))
.catch((error) => console.error(error));
}, []);
return (
<div className="relative overflow-x-auto shadow-md sm:rounded-lg">
{isLoading ? (
{loading ? (
<Loader></Loader>
) : (
<table className="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
@@ -47,8 +42,8 @@ const FarmList = () => {
</tr>
</thead>
<tbody>
{farms && farms.length > 0 ? (
farms.map((item) => <Td key={item.id} children={item} />)
{data.length > 0 ? (
data.map((item) => <Td key={item.id} children={item} />)
) : (
<tr>
<td colSpan={5} className="text-center">
-29
View File
@@ -1,29 +0,0 @@
const Laoder = () => {
return (
<div className="w-full bg-white rounded-lg shadow p-4">
<div class="flex items-center justify-center w-full h-56 border border-gray-200 rounded-lg bg-gray-50 dark:bg-gray-800 dark:border-gray-700">
<div role="status">
<svg
aria-hidden="true"
class="w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600"
viewBox="0 0 100 101"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
fill="currentColor"
/>
<path
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
fill="currentFill"
/>
</svg>
<span class="sr-only">Loading...</span>
</div>
</div>
</div>
);
};
export default Laoder;
+5 -11
View File
@@ -1,18 +1,12 @@
import React from "react";
const Message = ({ message, type = "error" }) => {
const Message = ({ message }) => {
const date = new Date();
const background =
type === "error"
? "bg-red-100 border border-red-400 text-red-700"
: "bg-gray-100 border border-gray-300 text-gray-800";
return (
<div className={`rounded-md p-3 ${background}`}>
<p className="font-medium">{message}</p>
<p className="text-end text-sm text-gray-600">
{date.getDate()}/{date.getMonth() + 1}/{date.getFullYear()}{" "}
<div className="w-auto h-auto bg-gray-200 rounded-md text-start p-3 mx-4">
<p className="">{message}</p>
<p className="text-end text-sm ">
{date.getDate()}/{date.getMonth()}/{date.getFullYear()}{" "}
{date.toLocaleTimeString()}
</p>
</div>
+2 -2
View File
@@ -6,7 +6,7 @@ import { BACKEND_URL } from "../constants";
const Navbar = () => {
const user = useSelector((store) => store.user);
//console.log("User is : ", user);
const navigate = useNavigate();
@@ -18,7 +18,7 @@ const Navbar = () => {
const data = await responce.json();
//console.log("User Logged out data is : ", data);
if (data.success == true) {
navigate("/user/login");
+18 -30
View File
@@ -1,38 +1,24 @@
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useState } from "react";
import { Link } from "react-router-dom";
const Navbar2 = () => {
const user = useSelector((store) => store.user);
const [isLoggedIn, setLoggedIn] = useState(false);
useEffect(() => {
if (user.name !== "Unloggedin User") {
setLoggedIn(true);
}
}, [user]);
const handleUserSession = async (event) => {
event.preventDefault();
const responce = await fetch(`http://localhost:8000/api/v1/me`, {
credentials: "include",
});
const user = await responce.json();
dispatch(userSliceActions.addUser(user.data));
};
const [isLoggedIn, setLoggedIn] = useState(false)
return (
<div className=" flex justify-center w-full">
<nav className=" h-18 mt-3 mb-3 w-4/12 mx-5 fixed z-20 dark:bg-gray-800/30 backdrop-blur-md rounded-full">
<div className=" flex justify-center rounded-full">
<nav className=" h-18 mt-3 mb-3 w-[97.5%] mx-5 fixed z-20 dark:bg-gray-800/30 backdrop-blur-md rounded-full">
<div className="absolute inset-0 bg-gradient-to-r from-gray-100/10 to-gray-500/20 pointer-events-none rounded-full"></div>
<div className="relative h-full flex items-center justify-between p-4">
<a
href="/"
className="flex items-center space-x-3 rtl:space-x-reverse"
>
<img src="/images/logo.png" className="size-10" alt="Logo" />
<img
src="/images/logo.png"
className="size-10"
alt="Logo"
/>
<span className="self-center text-2xl text-white font-semibold whitespace-nowrap dark:text-white">
Crop Compass
</span>
@@ -42,15 +28,16 @@ const Navbar2 = () => {
type="button"
className="text-black bg-white hover:bg-purple-200 font-medium rounded-full text-sm py-2 px-4 text-center"
>
{isLoggedIn ? (
<Link to={"/user/dashboard"}>Get Started</Link>
{isLoggedIn? (
<Link to={"/user/dashboard/addfarm"}>Get Started</Link>
) : (
<Link to={"/user/login"}>Log In</Link>
)}
</button>
</div>
{/* <div
<div
className="items-center justify-between hidden w-full md:flex md:w-auto md:order-1"
id="navbar-sticky"
>
@@ -89,11 +76,12 @@ const Navbar2 = () => {
</a>
</li>
</ul>
</div> */}
</div>
</div>
</nav>
</div>
);
};
};
export default Navbar2;
export default Navbar2;
+2 -2
View File
@@ -6,7 +6,7 @@ const Notification = ({ notification }) => {
// const dateStr = "2024-09-26T04:31:50.646+00:00";
const date = new Date(dateStr);
const dayName = date.toLocaleDateString("en-US", { weekday: "long" });
//console.log(dayName);
return dayName;
};
@@ -27,7 +27,7 @@ const Notification = ({ notification }) => {
};
const istDate = date.toLocaleString("en-US", options);
//console.log(istDate); // Output: "September 26, 2024, 10:01:50 AM"
return istDate;
};
+1 -25
View File
@@ -1,28 +1,4 @@
import { useEffect, useState } from "react";
import { useGetFarmsQuery } from "../store/api/farmApi";
const calculateSpend = (farmList) => {
let totalSpend = 0;
for (let i = 0; i < farmList.length; i++) {
if (!farmList[i]) continue;
if (!farmList[i]?.finances) continue;
if (!farmList[i]?.finances?.totalExpenses) continue;
totalSpend += farmList[i]?.finances?.totalExpenses;
}
return totalSpend;
};
const TotalSpent = () => {
const [totalSpend, setTotalSpend] = useState(0);
const { data: farmList, isLoading, error } = useGetFarmsQuery();
useEffect(() => {
if (!isLoading && !error && farmList) {
setTotalSpend(calculateSpend(farmList));
}
}, [farmList]);
return (
<div className="h-full">
<a
@@ -30,7 +6,7 @@ const TotalSpent = () => {
className="h-full block max-w-sm p-6 bg-no-repeat bg-center bg-cover border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
>
<h5 className="mb-2 text-4xl font-bold tracking-tight text-gray-900 dark:text-white">
{totalSpend && totalSpend}
10,000
</h5>
<p className="font-normal text-gray-700 dark:text-gray-400">
This is the total cost which you spent on this farm
@@ -1,5 +1,5 @@
// PerformanceChart.jsx
import React, { useEffect, useState } from "react";
import React from "react";
import { Line } from "react-chartjs-2";
import {
Chart as ChartJS,
@@ -11,7 +11,6 @@ import {
Tooltip,
Legend,
} from "chart.js";
import { useGetFarmsQuery } from "../../store/api/farmApi";
ChartJS.register(
CategoryScale,
@@ -23,35 +22,7 @@ ChartJS.register(
Legend
);
const calculateSpend = (farmList) => {
let totalSpend = [];
for (let i = 0; i < farmList.length; i++) {
if (!farmList[i]) continue;
if (!farmList[i]?.finances) continue;
if (!farmList[i]?.finances?.transactions) continue;
for (let j = 0; j < farmList[i]?.finances?.transactions.length; j++) {
if (!farmList[i]?.finances?.transactions[j]) continue;
if (!farmList[i]?.finances?.transactions[j]?.amount) continue;
if (farmList[i]?.finances?.transactions[j]?.type == "Revenue") continue;
totalSpend.push(farmList[i]?.finances?.transactions[j]?.amount);
}
}
return totalSpend;
};
const PerformanceChart = () => {
const [totalSpend, setTotalSpend] = useState(0);
const [spentList, setSpentList] = useState([]);
const { data: farmList, isLoading, error } = useGetFarmsQuery();
useEffect(() => {
if (!isLoading && !error && farmList) {
setTotalSpend(calculateSpend(farmList));
setSpentList(calculateSpend(farmList));
}
}, [farmList]);
const data = {
labels: [
"Jan",
@@ -69,8 +40,8 @@ const PerformanceChart = () => {
],
datasets: [
{
label: "Expences",
data: spentList, // slightly improved values
label: "Yield",
data: [75, 68, 85, 88, 60, 62, 78, 90, 95, 92, 88, 80], // slightly improved values
fill: false,
backgroundColor: "rgb(75, 192, 192)",
borderColor: "rgba(75, 192, 192, 0.2)",
@@ -82,7 +53,7 @@ const PerformanceChart = () => {
responsive: true,
plugins: {
legend: { position: "top" },
title: { display: true, text: "Expences Tracking " },
title: { display: true, text: "Performance Trend" },
},
};
@@ -1,96 +0,0 @@
// PerformanceChart.jsx
import React, { useEffect, useState } from "react";
import { Line } from "react-chartjs-2";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from "chart.js";
import { useGetFarmsQuery } from "../../store/api/farmApi";
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
);
const calculateSpend = (farmList) => {
let totalSpend = [];
for (let i = 0; i < farmList.length; i++) {
if (!farmList[i]) continue;
if (!farmList[i]?.finances) continue;
if (!farmList[i]?.finances?.transactions) continue;
for (let j = 0; j < farmList[i]?.finances?.transactions.length; j++) {
if (!farmList[i]?.finances?.transactions[j]) continue;
if (!farmList[i]?.finances?.transactions[j]?.amount) continue;
if (farmList[i]?.finances?.transactions[j]?.type == "Expense") continue;
totalSpend.push(farmList[i]?.finances?.transactions[j]?.amount);
}
}
return totalSpend;
};
const PerformanceChart2 = () => {
const [totalSpend, setTotalSpend] = useState(0);
const [spentList, setSpentList] = useState([]);
const { data: farmList, isLoading, error } = useGetFarmsQuery();
useEffect(() => {
if (!isLoading && !error && farmList) {
setTotalSpend(calculateSpend(farmList));
setSpentList(calculateSpend(farmList));
}
}, [farmList]);
const data = {
labels: [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
],
datasets: [
{
label: "Expences",
data: spentList, // slightly improved values
fill: false,
backgroundColor: "rgb(75, 192, 192)",
borderColor: "rgba(75, 192, 192, 0.2)",
},
],
};
const options = {
responsive: true,
plugins: {
legend: { position: "top" },
title: { display: true, text: "Expences Tracking " },
},
};
return <Line data={data} options={options} />;
};
export default PerformanceChart2;
-117
View File
@@ -1,117 +0,0 @@
{
"welcome": "Welcome to CropCompass",
"dashboard": "Dashboard",
"settings": "Settings",
"login_welcome_back": "Welcome Back!",
"login_title": "Login",
"login_subtitle": "Welcome back! Please login to your account.",
"login_email_label": "Email",
"login_email_placeholder": "username@gmail.com",
"login_password_label": "Password",
"login_password_placeholder": "********",
"login_remember_me": "Remember Me",
"login_forgot_password": "Forgot Password?",
"login_button": "Login",
"login_new_user": "New User?",
"login_signup": "Signup",
"main_login_heading": "Welcome to the Login Portal",
"signup_register_heading": "Register Your account",
"signup_welcome": "Welcome to Crop Compass.",
"signup_subtitle": "Please register your new account.",
"signup_first_name_label": "First Name",
"signup_first_name_placeholder": "John",
"signup_last_name_label": "Last Name",
"signup_last_name_placeholder": "Doe",
"signup_email_label": "Email",
"signup_email_placeholder": "user@mail.com",
"signup_password_label": "Password",
"signup_password_placeholder": "At least 6 unique Characters.. ",
"signup_remember_me": "Remember Me",
"signup_register_button": "Register your Account",
"signup_already_have_account": "Already have an Account?",
"signup_login": "Login",
"signup_journey_heading": "Start your Journey",
"signup_with": "with",
"forget_password_heading": "Forget Password?",
"forget_password_subtitle": "No worries, we'll send you reset instructions.",
"forget_password_email_placeholder": "Enter your email",
"forget_password_send_email": "Send Email",
"forget_password_email_sent": "Email Sent to your Mail",
"forget_password_back_to_login": "Back to Login Page",
"reset_password_heading": "Create New Password",
"reset_password_subtitle": "Create your new, unique and secure password here.",
"reset_password_new_label": "New Password :",
"reset_password_new_placeholder": "Enter your New Password",
"reset_password_confirm_label": "Confirm Password :",
"reset_password_confirm_placeholder": "Enter your Confirm Password",
"reset_password_error": "Password and confirm password do not match. Please enter the same password in both fields.",
"reset_password_button": "Reset Password",
"reset_password_back_to_login": "Back to Login Page",
"hero_one_stop_solution": "One stop solution for every farmer's need.",
"hero_plant_alt": "plant",
"card_with_image_alt": "plant",
"card_with_image_title": "High tech, high yields?",
"card_with_image_body": "The Kenyan farmers deploying AI to increase productivity. This article is more than 4 months old. AI apps are increasingly popular among small-scale farmers seeking to improve the quality and quantity of their crop.",
"card_with_image_read_more": "Read more",
"card_with_button_title": "Empowering smallholder farmers with AI tools can bolster global food security",
"card_with_button_body": "AI-powered weather forecasts help rural Indian farmers make informed planting decisions, reducing debt and boosting savings.",
"card_with_button_read_more": "Read more",
"card_with_only_image_alt": "Agritech success story",
"card_only_text_heading1": "AI for agriculture: How Indian farmers are harvesting innovation",
"card_only_text_body1": "Farmers participating in the programme saw a 21% increase in chili yields per acre, a 9% reduction in pesticide use, a 5% decrease in fertilizer usage, and an 8% improvement in unit prices due to quality enhancements.",
"card_only_text_heading2": "SugarChain: Blockchain technology meets Agriculture",
"card_only_text_body2": "The use of blockchain technology can help farmers automate processes with high trust, addressing issues like middlemen involvement and ensuring accurate compensation for their products",
"customization_schedule": "CUSTOMIZE WITH YOUR SCHEDULE",
"customization_tutors_title": "Talented and Qualified Tutors to Serve You for Help",
"customization_paragraph": "Our scheduling system allows you to select based on free time. Lorem ipsum demo text for template. Keep track of your students class and tutoring schedules, and never miss your lectures. The best online class scheduling system with easy accessibility. Lorem ipsum is a placeholder text commonly used to demonstrate the visual form",
"customization_get_started": "Get started",
"customization_image_alt": "Interaction illustration",
"footer_logo_alt": "Crop Compass Logo",
"footer_brand": "Crop Compass",
"footer_rights_reserved": "All Rights Reserved.",
"hero2_card1_heading": "AI for agriculture: How Indian farmers are harvesting innovation",
"hero2_card1_body": "Farmers participating in the programme saw a 21% increase in chili yields per acre, a 9% reduction in pesticide use, a 5% decrease in fertilizer usage, and an 8% improvement in unit prices due to quality enhancements.",
"hero2_card2_heading": "SugarChain: Blockchain technology meets Agriculture",
"hero2_card2_body": "The use of blockchain technology can help farmers automate processes with high trust, addressing issues like middlemen involvement and ensuring accurate compensation for their products",
"hero_heading_main": "Anything and Everything you Need to know About",
"hero_heading_sub": "Your crops and their Health!",
"hero_image_alt": "plant",
"hero_card1_image_alt": "plant",
"hero_card1_title": "Noteworthy technology acquisitions 2021",
"hero_card1_body": "Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.",
"hero_card1_read_more": "Read more",
"hero_card2_title": "Noteworthy technology acquisitions 2021",
"hero_card2_body": "Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.",
"hero_card3_title": "Noteworthy technology acquisitions 2021",
"hero_card3_body": "Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.",
"hero_card3_read_more": "Read more",
"hero_card4_image_alt": "product image",
"hero_card5_title": "Noteworthy technology acquisitions 2021",
"hero_card5_body": "Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.",
"testimonial_heading": "WHY CHOOSE US?",
"testimonial_typewriter": "Unparalleled management for crops & farms.",
"testimonial_card1_title": "Excellent Dashboards",
"testimonial_card1_body": "Our descriptive dashboards give insights into your crop's health and keep track of your burning expenses.",
"testimonial_card2_title": "Crop Disease Prediction",
"testimonial_card2_body": "Predict the possible crop diseases based on their shown symptoms.",
"testimonial_card3_title": "Crop Planner",
"testimonial_card3_body": "Based on previous season's crop and used fertilizers and pesticides, plan what crops would best suit the present state of your soil.",
"testimonial_check_out": "Check Out"
}
-117
View File
@@ -1,117 +0,0 @@
{
"welcome": "Bienvenue sur CropCompass",
"dashboard": "Tableau de bord",
"settings": "Paramètres",
"login_welcome_back": "Bon retour !",
"login_title": "Connexion",
"login_subtitle": "Bon retour ! Veuillez vous connecter à votre compte.",
"login_email_label": "E-mail",
"login_email_placeholder": "nomutilisateur@gmail.com",
"login_password_label": "Mot de passe",
"login_password_placeholder": "********",
"login_remember_me": "Se souvenir de moi",
"login_forgot_password": "Mot de passe oublié ?",
"login_button": "Connexion",
"login_new_user": "Nouvel utilisateur ?",
"login_signup": "S'inscrire",
"main_login_heading": "Bienvenue sur le portail de connexion",
"signup_register_heading": "Enregistrez votre compte",
"signup_welcome": "Bienvenue sur Crop Compass.",
"signup_subtitle": "Veuillez enregistrer votre nouveau compte.",
"signup_first_name_label": "Prénom",
"signup_first_name_placeholder": "Jean",
"signup_last_name_label": "Nom",
"signup_last_name_placeholder": "Dupont",
"signup_email_label": "E-mail",
"signup_email_placeholder": "utilisateur@mail.com",
"signup_password_label": "Mot de passe",
"signup_password_placeholder": "Au moins 6 caractères uniques.. ",
"signup_remember_me": "Se souvenir de moi",
"signup_register_button": "Enregistrer votre compte",
"signup_already_have_account": "Vous avez déjà un compte ?",
"signup_login": "Connexion",
"signup_journey_heading": "Commencez votre aventure",
"signup_with": "avec",
"forget_password_heading": "Mot de passe oublié ?",
"forget_password_subtitle": "Pas d'inquiétude, nous vous enverrons des instructions de réinitialisation.",
"forget_password_email_placeholder": "Entrez votre e-mail",
"forget_password_send_email": "Envoyer l'e-mail",
"forget_password_email_sent": "E-mail envoyé à votre adresse",
"forget_password_back_to_login": "Retour à la page de connexion",
"reset_password_heading": "Créer un nouveau mot de passe",
"reset_password_subtitle": "Créez ici votre nouveau mot de passe unique et sécurisé.",
"reset_password_new_label": "Nouveau mot de passe :",
"reset_password_new_placeholder": "Entrez votre nouveau mot de passe",
"reset_password_confirm_label": "Confirmer le mot de passe :",
"reset_password_confirm_placeholder": "Entrez à nouveau votre mot de passe",
"reset_password_error": "Le mot de passe et sa confirmation ne correspondent pas. Veuillez saisir le même mot de passe dans les deux champs.",
"reset_password_button": "Réinitialiser le mot de passe",
"reset_password_back_to_login": "Retour à la page de connexion",
"hero_one_stop_solution": "Une solution unique pour tous les besoins des agriculteurs.",
"hero_plant_alt": "plante",
"card_with_image_alt": "plante",
"card_with_image_title": "Haute technologie, hauts rendements ?",
"card_with_image_body": "Les agriculteurs kenyans utilisent l'IA pour augmenter leur productivité. Cet article a plus de 4 mois. Les applications d'IA sont de plus en plus populaires auprès des petits exploitants cherchant à améliorer la qualité et la quantité de leurs récoltes.",
"card_with_image_read_more": "Lire la suite",
"card_with_button_title": "Donner aux petits exploitants des outils d'IA peut renforcer la sécurité alimentaire mondiale",
"card_with_button_body": "Les prévisions météorologiques alimentées par l'IA aident les agriculteurs ruraux indiens à prendre des décisions de plantation éclairées, réduisant les dettes et augmentant les économies.",
"card_with_button_read_more": "Lire la suite",
"card_with_only_image_alt": "Succès de l'agritech",
"card_only_text_heading1": "LIA pour lagriculture : comment les agriculteurs indiens récoltent linnovation",
"card_only_text_body1": "Les agriculteurs participant au programme ont constaté une augmentation de 21 % des rendements de piment par acre, une réduction de 9 % de lutilisation de pesticides, une diminution de 5 % de lutilisation dengrais et une amélioration de 8 % des prix unitaires grâce à lamélioration de la qualité.",
"card_only_text_heading2": "SugarChain : la blockchain rencontre lagriculture",
"card_only_text_body2": "Lutilisation de la technologie blockchain peut aider les agriculteurs à automatiser les processus avec une grande confiance, à résoudre les problèmes liés aux intermédiaires et à garantir une rémunération précise de leurs produits",
"customization_schedule": "PERSONNALISEZ AVEC VOTRE EMPLOI DU TEMPS",
"customization_tutors_title": "Des tuteurs talentueux et qualifiés à votre service",
"customization_paragraph": "Notre système de planification vous permet de sélectionner en fonction de votre temps libre. Texte de démonstration Lorem ipsum pour le modèle. Suivez les horaires de vos étudiants et de tutorat, et ne manquez jamais vos cours. Le meilleur système de planification de cours en ligne avec une accessibilité facile. Lorem ipsum est un texte de remplacement couramment utilisé pour démontrer la forme visuelle",
"customization_get_started": "Commencer",
"customization_image_alt": "Illustration d'interaction",
"footer_logo_alt": "Logo de Crop Compass",
"footer_brand": "Crop Compass",
"footer_rights_reserved": "Tous droits réservés.",
"hero2_card1_heading": "LIA pour lagriculture : comment les agriculteurs indiens récoltent linnovation",
"hero2_card1_body": "Les agriculteurs participant au programme ont constaté une augmentation de 21 % des rendements de piment par acre, une réduction de 9 % de lutilisation de pesticides, une diminution de 5 % de lutilisation dengrais et une amélioration de 8 % des prix unitaires grâce à lamélioration de la qualité.",
"hero2_card2_heading": "SugarChain : la blockchain rencontre lagriculture",
"hero2_card2_body": "Lutilisation de la technologie blockchain peut aider les agriculteurs à automatiser les processus avec une grande confiance, à résoudre les problèmes liés aux intermédiaires et à garantir une rémunération précise de leurs produits",
"hero_heading_main": "Tout ce que vous devez savoir sur",
"hero_heading_sub": "Vos cultures et leur santé !",
"hero_image_alt": "plante",
"hero_card1_image_alt": "plante",
"hero_card1_title": "Acquisitions technologiques remarquables 2021",
"hero_card1_body": "Voici les plus grandes acquisitions technologiques d'entreprise de 2021 à ce jour, par ordre chronologique inverse.",
"hero_card1_read_more": "Lire la suite",
"hero_card2_title": "Acquisitions technologiques remarquables 2021",
"hero_card2_body": "Voici les plus grandes acquisitions technologiques d'entreprise de 2021 à ce jour, par ordre chronologique inverse.",
"hero_card3_title": "Acquisitions technologiques remarquables 2021",
"hero_card3_body": "Voici les plus grandes acquisitions technologiques d'entreprise de 2021 à ce jour, par ordre chronologique inverse.",
"hero_card3_read_more": "Lire la suite",
"hero_card4_image_alt": "image du produit",
"hero_card5_title": "Acquisitions technologiques remarquables 2021",
"hero_card5_body": "Voici les plus grandes acquisitions technologiques d'entreprise de 2021 à ce jour, par ordre chronologique inverse.",
"testimonial_heading": "POURQUOI NOUS CHOISIR ?",
"testimonial_typewriter": "Gestion inégalée pour les cultures et les fermes.",
"testimonial_card1_title": "Tableaux de bord excellents",
"testimonial_card1_body": "Nos tableaux de bord descriptifs donnent un aperçu de la santé de vos cultures et suivent vos dépenses importantes.",
"testimonial_card2_title": "Prédiction des maladies des cultures",
"testimonial_card2_body": "Prédisez les maladies possibles des cultures en fonction des symptômes observés.",
"testimonial_card3_title": "Planificateur de cultures",
"testimonial_card3_body": "En fonction des cultures de la saison précédente et des engrais et pesticides utilisés, planifiez les cultures qui conviendraient le mieux à l’état actuel de votre sol.",
"testimonial_check_out": "Voir"
}
-116
View File
@@ -1,116 +0,0 @@
{
"welcome": "क्रॉप कम्पास में आपका स्वागत है",
"dashboard": "डैशबोर्ड",
"settings": "सेटिंग्स",
"login_welcome_back": "फिर से स्वागत है!",
"login_title": "लॉगिन",
"login_subtitle": "फिर से स्वागत है! कृपया अपने खाते में लॉगिन करें।",
"login_email_label": "ईमेल",
"login_email_placeholder": "username@gmail.com",
"login_password_label": "पासवर्ड",
"login_password_placeholder": "********",
"login_remember_me": "मुझे याद रखें",
"login_forgot_password": "पासवर्ड भूल गए?",
"login_button": "लॉगिन",
"login_new_user": "नया उपयोगकर्ता?",
"login_signup": "साइनअप",
"main_login_heading": "लॉगिन पोर्टल में आपका स्वागत है",
"signup_register_heading": "अपना खाता पंजीकृत करें",
"signup_welcome": "क्रॉप कम्पास में आपका स्वागत है।",
"signup_subtitle": "कृपया अपना नया खाता पंजीकृत करें।",
"signup_first_name_label": "पहला नाम",
"signup_first_name_placeholder": "जॉन",
"signup_last_name_label": "अंतिम नाम",
"signup_last_name_placeholder": "डो",
"signup_email_label": "ईमेल",
"signup_email_placeholder": "user@mail.com",
"signup_password_label": "पासवर्ड",
"signup_password_placeholder": "कम से कम 6 अद्वितीय अक्षर...",
"signup_remember_me": "मुझे याद रखें",
"signup_register_button": "अपना खाता पंजीकृत करें",
"signup_already_have_account": "पहले से खाता है?",
"signup_login": "लॉगिन",
"signup_journey_heading": "अपनी यात्रा शुरू करें",
"signup_with": "के साथ",
"forget_password_heading": "पासवर्ड भूल गए?",
"forget_password_subtitle": "कोई बात नहीं, हम आपको रीसेट निर्देश भेज देंगे।",
"forget_password_email_placeholder": "अपना ईमेल दर्ज करें",
"forget_password_send_email": "ईमेल भेजें",
"forget_password_email_sent": "ईमेल आपके इनबॉक्स में भेजा गया है",
"forget_password_back_to_login": "लॉगिन पेज पर वापस जाएं",
"reset_password_heading": "नया पासवर्ड बनाएं",
"reset_password_subtitle": "यहां अपना नया, अद्वितीय और सुरक्षित पासवर्ड बनाएं।",
"reset_password_new_label": "नया पासवर्ड:",
"reset_password_new_placeholder": "अपना नया पासवर्ड दर्ज करें",
"reset_password_confirm_label": "पासवर्ड की पुष्टि करें:",
"reset_password_confirm_placeholder": "अपना पुष्टि पासवर्ड दर्ज करें",
"reset_password_error": "पासवर्ड और पुष्टि पासवर्ड मेल नहीं खाते। कृपया दोनों फ़ील्ड में समान पासवर्ड दर्ज करें।",
"reset_password_button": "पासवर्ड रीसेट करें",
"reset_password_back_to_login": "लॉगिन पेज पर वापस जाएं",
"hero_one_stop_solution": "हर किसान की ज़रूरत के लिए एक ही समाधान।",
"hero_plant_alt": "पौधा",
"card_with_image_alt": "पौधा",
"card_with_image_title": "हाई टेक, उच्च उत्पादन?",
"card_with_image_body": "केन्या के किसान AI का उपयोग करके उत्पादकता बढ़ा रहे हैं। यह लेख 4 महीने पुराना है। छोटे किसानों में AI ऐप्स गुणवत्ता और मात्रा सुधारने के लिए तेजी से लोकप्रिय हो रहे हैं।",
"card_with_image_read_more": "और पढ़ें",
"card_with_button_title": "AI उपकरणों से छोटे किसानों को सशक्त बनाकर वैश्विक खाद्य सुरक्षा को बढ़ावा",
"card_with_button_body": "AI-संचालित मौसम पूर्वानुमान भारतीय किसानों को बेहतर निर्णय लेने में मदद करते हैं, कर्ज घटाते हैं और बचत बढ़ाते हैं।",
"card_with_button_read_more": "और पढ़ें",
"card_with_only_image_alt": "एग्रीटेक सफलता की कहानी",
"card_only_text_heading1": "कृषि में AI: कैसे भारतीय किसान नवाचार का लाभ उठा रहे हैं",
"card_only_text_body1": "इस कार्यक्रम में भाग लेने वाले किसानों की मिर्च की उपज में प्रति एकड़ 21% वृद्धि, कीटनाशक उपयोग में 9% कमी, उर्वरक उपयोग में 5% कमी और गुणवत्ता सुधार के कारण मूल्य में 8% वृद्धि देखी गई।",
"card_only_text_heading2": "शुगरचेन: कृषि में ब्लॉकचेन तकनीक",
"card_only_text_body2": "ब्लॉकचेन तकनीक के उपयोग से किसान प्रक्रियाओं को उच्च विश्वास के साथ स्वचालित कर सकते हैं, बिचौलियों की भूमिका कम होती है और सही भुगतान सुनिश्चित होता है।",
"customization_schedule": "अपने शेड्यूल के अनुसार अनुकूलित करें",
"customization_tutors_title": "आपकी मदद के लिए प्रतिभाशाली और योग्य शिक्षक",
"customization_paragraph": "हमारी शेड्यूलिंग प्रणाली आपको अपने खाली समय के अनुसार चुनने की सुविधा देती है। छात्रों की कक्षा और ट्यूटरिंग शेड्यूल को ट्रैक करें और कोई भी लेक्चर न छोड़ें। सबसे अच्छा ऑनलाइन कक्षा शेड्यूलिंग सिस्टम।",
"customization_get_started": "शुरू करें",
"customization_image_alt": "इंटरएक्शन चित्रण",
"footer_logo_alt": "क्रॉप कम्पास लोगो",
"footer_brand": "क्रॉप कम्पास",
"footer_rights_reserved": "सभी अधिकार सुरक्षित।",
"hero2_card1_heading": "कृषि में AI: कैसे भारतीय किसान नवाचार का लाभ उठा रहे हैं",
"hero2_card1_body": "इस कार्यक्रम में भाग लेने वाले किसानों की मिर्च की उपज में प्रति एकड़ 21% वृद्धि, कीटनाशक उपयोग में 9% कमी, उर्वरक उपयोग में 5% कमी और गुणवत्ता सुधार के कारण मूल्य में 8% वृद्धि देखी गई।",
"hero2_card2_heading": "शुगरचेन: कृषि में ब्लॉकचेन तकनीक",
"hero2_card2_body": "ब्लॉकचेन तकनीक के उपयोग से किसान प्रक्रियाओं को उच्च विश्वास के साथ स्वचालित कर सकते हैं, बिचौलियों की भूमिका कम होती है और सही भुगतान सुनिश्चित होता है।",
"hero_heading_main": "अपने फसलों और उनकी सेहत के बारे में सब कुछ जानें",
"hero_heading_sub": "आपकी फसलों और उनकी सेहत!",
"hero_image_alt": "पौधा",
"hero_card1_image_alt": "पौधा",
"hero_card1_title": "2021 की उल्लेखनीय टेक्नोलॉजी अधिग्रहण",
"hero_card1_body": "अब तक के सबसे बड़े एंटरप्राइज टेक्नोलॉजी अधिग्रहण, उल्टे कालक्रम में।",
"hero_card1_read_more": "और पढ़ें",
"hero_card2_title": "2021 की उल्लेखनीय टेक्नोलॉजी अधिग्रहण",
"hero_card2_body": "अब तक के सबसे बड़े एंटरप्राइज टेक्नोलॉजी अधिग्रहण, उल्टे कालक्रम में।",
"hero_card3_title": "2021 की उल्लेखनीय टेक्नोलॉजी अधिग्रहण",
"hero_card3_body": "अब तक के सबसे बड़े एंटरप्राइज टेक्नोलॉजी अधिग्रहण, उल्टे कालक्रम में।",
"hero_card3_read_more": "और पढ़ें",
"hero_card4_image_alt": "उत्पाद छवि",
"hero_card5_title": "2021 की उल्लेखनीय टेक्नोलॉजी अधिग्रहण",
"hero_card5_body": "अब तक के सबसे बड़े एंटरप्राइज टेक्नोलॉजी अधिग्रहण, उल्टे कालक्रम में।",
"testimonial_heading": "हमें क्यों चुनें?",
"testimonial_typewriter": "फसलों और खेतों के लिए बेजोड़ प्रबंधन।",
"testimonial_card1_title": "उत्कृष्ट डैशबोर्ड",
"testimonial_card1_body": "हमारे विवरणात्मक डैशबोर्ड आपकी फसलों की स्थिति और खर्चों पर नजर रखते हैं।",
"testimonial_card2_title": "फसल रोग पूर्वानुमान",
"testimonial_card2_body": "दिखाई देने वाले लक्षणों के आधार पर संभावित फसल रोगों की भविष्यवाणी करें।",
"testimonial_card3_title": "फसल योजना",
"testimonial_card3_body": "पिछले सीजन की फसल और उपयोग किए गए उर्वरक और कीटनाशकों के आधार पर, वर्तमान मिट्टी के अनुसार सर्वोत्तम फसल योजना बनाएं।",
"testimonial_check_out": "देखें"
}
-116
View File
@@ -1,116 +0,0 @@
{
"welcome": "क्रॉप कम्पासमध्ये आपले स्वागत आहे",
"dashboard": "डॅशबोर्ड",
"settings": "सेटिंग्ज",
"login_welcome_back": "पुन्हा स्वागत आहे!",
"login_title": "लॉगिन",
"login_subtitle": "पुन्हा स्वागत आहे! कृपया आपल्या खात्यात लॉगिन करा.",
"login_email_label": "ईमेल",
"login_email_placeholder": "username@gmail.com",
"login_password_label": "पासवर्ड",
"login_password_placeholder": "********",
"login_remember_me": "माझी आठवण ठेवा",
"login_forgot_password": "पासवर्ड विसरलात?",
"login_button": "लॉगिन",
"login_new_user": "नवीन वापरकर्ता?",
"login_signup": "नोंदणी करा",
"main_login_heading": "लॉगिन पोर्टलमध्ये आपले स्वागत आहे",
"signup_register_heading": "आपले खाते नोंदणी करा",
"signup_welcome": "क्रॉप कम्पासमध्ये आपले स्वागत आहे.",
"signup_subtitle": "कृपया आपले नवीन खाते नोंदणी करा.",
"signup_first_name_label": "पहिले नाव",
"signup_first_name_placeholder": "जॉन",
"signup_last_name_label": "आडनाव",
"signup_last_name_placeholder": "डो",
"signup_email_label": "ईमेल",
"signup_email_placeholder": "user@mail.com",
"signup_password_label": "पासवर्ड",
"signup_password_placeholder": "किमान 6 अद्वितीय अक्षरे...",
"signup_remember_me": "माझी आठवण ठेवा",
"signup_register_button": "आपले खाते नोंदणी करा",
"signup_already_have_account": "आधीच खाते आहे?",
"signup_login": "लॉगिन",
"signup_journey_heading": "आपली यात्रा सुरू करा",
"signup_with": "सह",
"forget_password_heading": "पासवर्ड विसरलात?",
"forget_password_subtitle": "चिंता करू नका, आम्ही आपल्याला रीसेट करण्याच्या सूचना पाठवू.",
"forget_password_email_placeholder": "आपला ईमेल टाका",
"forget_password_send_email": "ईमेल पाठवा",
"forget_password_email_sent": "ईमेल पाठवला गेला आहे",
"forget_password_back_to_login": "लॉगिन पेजवर परत जा",
"reset_password_heading": "नवीन पासवर्ड तयार करा",
"reset_password_subtitle": "येथे आपला नवीन, सुरक्षित पासवर्ड तयार करा.",
"reset_password_new_label": "नवीन पासवर्ड:",
"reset_password_new_placeholder": "नवीन पासवर्ड टाका",
"reset_password_confirm_label": "पासवर्डची पुष्टी करा:",
"reset_password_confirm_placeholder": "पासवर्डची पुष्टी करा",
"reset_password_error": "पासवर्ड आणि पुष्टी पासवर्ड जुळत नाहीत. कृपया दोन्ही ठिकाणी एकच पासवर्ड टाका.",
"reset_password_button": "पासवर्ड रीसेट करा",
"reset_password_back_to_login": "लॉगिन पेजवर परत जा",
"hero_one_stop_solution": "प्रत्येक शेतकऱ्याच्या गरजेसाठी एकाच ठिकाणी उपाय.",
"hero_plant_alt": "झाड",
"card_with_image_alt": "झाड",
"card_with_image_title": "हाय-टेक, जास्त उत्पादन?",
"card_with_image_body": "केनियातील शेतकरी AI वापरून उत्पादकता वाढवत आहेत. हा लेख ४ महिन्यांपेक्षा जुना आहे. लहान शेतकऱ्यांमध्ये AI अॅप्स अधिक लोकप्रिय होत आहेत.",
"card_with_image_read_more": "अधिक वाचा",
"card_with_button_title": "AI साधनांनी लहान शेतकऱ्यांना सशक्त करून जागतिक अन्न सुरक्षेला चालना",
"card_with_button_body": "AI आधारित हवामान अंदाजामुळे भारतीय शेतकऱ्यांना चांगले निर्णय घेण्यास मदत होते, कर्ज कमी होते आणि बचत वाढते.",
"card_with_button_read_more": "अधिक वाचा",
"card_with_only_image_alt": "अॅग्रीटेक यशोगाथा",
"card_only_text_heading1": "शेतीसाठी AI: भारतीय शेतकरी कसे नवकल्पना करत आहेत",
"card_only_text_body1": "या कार्यक्रमात सहभागी झालेल्या शेतकऱ्यांची मिरची उत्पादनात २१% वाढ, कीटकनाशक वापरात ९% घट, खत वापरात ५% घट, आणि गुणवत्तेमुळे किंमतीत ८% वाढ झाली.",
"card_only_text_heading2": "शुगरचेन: ब्लॉकचेन तंत्रज्ञान आणि शेती",
"card_only_text_body2": "ब्लॉकचेन तंत्रज्ञानामुळे प्रक्रिया स्वयंचलित करता येतात, दलालांची भूमिका कमी होते आणि शेतकऱ्यांना योग्य मोबदला मिळतो.",
"customization_schedule": "आपल्या वेळापत्रकानुसार सानुकूल करा",
"customization_tutors_title": "आपल्याला मदतीसाठी कुशल आणि पात्र शिक्षक",
"customization_paragraph": "आमची वेळापत्रक प्रणाली आपल्याला आपल्या मोकळ्या वेळेनुसार निवडण्याची सुविधा देते. आपले वर्ग व शिकवणीचे वेळापत्रक व्यवस्थापित करा आणि एकही व्याख्यान चुकवू नका.",
"customization_get_started": "सुरू करा",
"customization_image_alt": "इंटरअ‍ॅक्शन प्रतिमा",
"footer_logo_alt": "क्रॉप कम्पास लोगो",
"footer_brand": "क्रॉप कम्पास",
"footer_rights_reserved": "सर्व हक्क राखीव.",
"hero2_card1_heading": "शेतीसाठी AI: भारतीय शेतकरी कसे नवकल्पना करत आहेत",
"hero2_card1_body": "या कार्यक्रमात सहभागी झालेल्या शेतकऱ्यांची मिरची उत्पादनात २१% वाढ, कीटकनाशक वापरात ९% घट, खत वापरात ५% घट, आणि गुणवत्तेमुळे किंमतीत ८% वाढ झाली.",
"hero2_card2_heading": "शुगरचेन: ब्लॉकचेन तंत्रज्ञान आणि शेती",
"hero2_card2_body": "ब्लॉकचेन तंत्रज्ञानामुळे प्रक्रिया स्वयंचलित करता येतात, दलालांची भूमिका कमी होते आणि शेतकऱ्यांना योग्य मोबदला मिळतो.",
"hero_heading_main": "आपल्या पिकांबद्दल सर्व काही जाणून घ्या",
"hero_heading_sub": "आपल्या पिकांची आरोग्य स्थिती!",
"hero_image_alt": "झाड",
"hero_card1_image_alt": "झाड",
"hero_card1_title": "२०२१ मधील उल्लेखनीय तंत्रज्ञान खरेदी",
"hero_card1_body": "२०२१ मधील सर्वात मोठ्या एंटरप्राइज तंत्रज्ञान खरेदी, उलट्या क्रमाने.",
"hero_card1_read_more": "अधिक वाचा",
"hero_card2_title": "२०२१ मधील उल्लेखनीय तंत्रज्ञान खरेदी",
"hero_card2_body": "२०२१ मधील सर्वात मोठ्या एंटरप्राइज तंत्रज्ञान खरेदी, उलट्या क्रमाने.",
"hero_card3_title": "२०२१ मधील उल्लेखनीय तंत्रज्ञान खरेदी",
"hero_card3_body": "२०२१ मधील सर्वात मोठ्या एंटरप्राइज तंत्रज्ञान खरेदी, उलट्या क्रमाने.",
"hero_card3_read_more": "अधिक वाचा",
"hero_card4_image_alt": "उत्पादन प्रतिमा",
"hero_card5_title": "२०२१ मधील उल्लेखनीय तंत्रज्ञान खरेदी",
"hero_card5_body": "२०२१ मधील सर्वात मोठ्या एंटरप्राइज तंत्रज्ञान खरेदी, उलट्या क्रमाने.",
"testimonial_heading": "आम्हाला का निवडाल?",
"testimonial_typewriter": "पिके आणि शेतासाठी उत्कृष्ट व्यवस्थापन.",
"testimonial_card1_title": "उत्कृष्ट डॅशबोर्ड",
"testimonial_card1_body": "आमचे डॅशबोर्ड आपली पिकांची आरोग्य स्थिती व खर्च यांची माहिती देतात.",
"testimonial_card2_title": "पिकांवरील रोगाचे भाकीत",
"testimonial_card2_body": "दिसणाऱ्या लक्षणांच्या आधारे संभाव्य रोगांचे भाकीत करा.",
"testimonial_card3_title": "पीक नियोजन",
"testimonial_card3_body": "मागील हंगामाच्या पिकांवरून व वापरलेल्या खतांवरून योग्य पीक निवडा.",
"testimonial_check_out": "पहा"
}
-2
View File
@@ -27,7 +27,6 @@ import AddFarm from "./pages/UserPanel/Farm/AddFarm.jsx";
import UpdateFarm from "./pages/UserPanel/Farm/UpdateForm.jsx";
import FarmPage from "./pages/UserPanel/Farm/FarmPage.jsx";
import Ai from "./pages/UserPanel/Ai.jsx";
import CropPage from "./pages/UserPanel/Farm/CropPage.jsx";
createRoot(document.getElementById("root")).render(
<StrictMode>
<Provider store={MentifyStore}>
@@ -62,7 +61,6 @@ createRoot(document.getElementById("root")).render(
<Route path="addfarm" element={<AddFarm />} />
<Route path="updatefarm" element={<UpdateFarm />} />
<Route path="farmpage/:farmId" element={<FarmPage />} />
<Route path="croppage/:cropId" element={<CropPage />} />
</Route>
</Route>
</Routes>
+43
View File
@@ -0,0 +1,43 @@
import React from "react";
const About = () => {
return (
<>
<section className="bg-white py-12 w-full flex justify-center">
<div className="flex flex-col md:flex-row justify-between w-10/12 h-auto">
<div className="w-full md:w-4/5 object-contain flex justify-center items-center">
<img src="/images/calender.png" className="w-full h-auto" alt="" />
</div>
<div className="container mx-auto flex flex-col justify-around h-full w-full md:py-10">
<div className="text-center md:text-start flex flex-col justify-around h-full">
<h2 className="text-xl font-bold mb-4 text-yellow-600">
CUSTOMIZE WITH YOUR SCHEDULE
</h2>
<h1 className="text-2xl md:text-4xl md:font-extrabold font-bold mb-4">
Personalized Professional Online Mentor on Your Schedule
</h1>
<p className="text-base mb-8">
Our scheduling system allows you to select based on free time.
Lorem ipsum demo text for template. Keep track of your students
class and mentoring schedules, and never miss your Session. The
best online class scheduling system with easy accessibility.
Lorem ipsum is a placeholder text commonly used to demonstrate
the visual form
</p>
<div className="flex gap-4 justify-center md:justify-start">
<button
type="button"
className="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-base px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"
>
Get started
</button>
</div>
</div>
</div>
</div>
</section>
</>
);
};
export default About;
+57 -86
View File
@@ -1,49 +1,24 @@
import React, { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { t } from "../../service/translation";
export const HeroSecn = ({ language = "en" }) => {
const user = useSelector((store) => store.user);
const dispatch = useDispatch();
const [isLoggedIn, setLoggedIn] = useState(false);
useEffect(() => {
if (user.name !== "Unloggedin User") {
setLoggedIn(true);
}
}, [user]);
const handleUserSession = async (event) => {
event.preventDefault();
const responce = await fetch(`http://localhost:8000/api/v1/me`, {
credentials: "include",
});
const user = await responce.json();
dispatch(userSliceActions.addUser(user.data));
};
import React from "react";
export const HeroSecn = () => {
return (
<section className="py-40 w-full flex justify-center text-gray-100">
<section className=" py-40 w-full flex justify-center text-gray-100">
<div className="flex flex-col-reverse md:flex-row justify-between w-10/12 h-auto">
<div className="container mx-auto flex flex-col justify-between h-full w-full">
<div className="text-center md:text-start flex flex-col justify-around h-full">
<h1 className="text-6xl md:text-6xl md:w-2/3 md:font-extrabold font-bold ">
{t("hero_one_stop_solution", language)}
<h1 className="text-6xl md:text-6xl md:w-2/3 md:font-extrabold font-bold">
Anything and Everything you Need to know About
</h1>
<p className="text-2xl font-semibold mb-8 ">
Your crops and their Health!
</p>
</div>
<button
type="button"
className="text-black w-auto max-w-lg bg-white hover:bg-purple-200 font-medium rounded-full text-sm py-2 px-4 text-center"
></button>
</div>
<div className="w-full md:w-4/5 object-contain flex justify-center items-center">
<img
src="/images/plant.png"
className="w-full h-auto rounded-3xl shadow-xl"
alt={t("hero_plant_alt", language)}
alt="plant"
/>
</div>
</div>
@@ -51,31 +26,34 @@ export const HeroSecn = ({ language = "en" }) => {
);
};
export const CardWithImage = ({ language = "en" }) => {
export const CardWithImage = () => {
return (
<div className="max-w-sm rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<a href="#">
<img
className="rounded-t-lg"
src="https://i.pinimg.com/736x/07/2b/5f/072b5f6a1630d919ceee1a8569683cf7.jpg"
alt={t("card_with_image_alt", language)}
alt="plant"
/>
</a>
<div className="p-6 backdrop-blur-md rounded-b-lg">
<a href="#">
<h5 className="mb-2 text-2xl font-bold tracking-tight text-white dark:text-white">
{t("card_with_image_title", language)}
High tech, high yields?
</h5>
</a>
<p className="mb-3 font-normal text-white dark:text-gray-400">
{t("card_with_image_body", language)}
The Kenyan farmers deploying AI to increase productivity This article
is more than 4 months old. AI apps are increasingly popular among
small-scale farmers seeking to improve the quality and quantity of
their crop.
</p>
<a
href="https://www.theguardian.com/world/2024/sep/30/high-tech-high-yields-the-kenyan-farmers-deploying-ai-to-increase-productivity"
target="_blank"
className="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl "
>
{t("card_with_image_read_more", language)}
Read more
<svg
className="rtl:rotate-180 w-3.5 h-3.5 ms-2"
aria-hidden="true"
@@ -85,9 +63,9 @@ export const CardWithImage = ({ language = "en" }) => {
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M1 5h12m0 0L9 1m4 4L9 9"
/>
</svg>
@@ -97,47 +75,50 @@ export const CardWithImage = ({ language = "en" }) => {
);
};
export const CardOnlyText = ({
headingText,
bodyText,
href,
language = "en",
}) => {
export const CardOnlyText = (props) => {
return (
<div>
<a
href={href}
href={props.href}
target="_blank"
className="block max-w-sm min-h-[275px] p-6 rounded-lg shadow-md backdrop-blur-md dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
className="block max-w-sm p-6 rounded-lg shadow-md backdrop-blur-md dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
>
<h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-50 dark:text-white">
{headingText}
{" "}
{props.headingText}{" "}
</h5>
<p className="font-normal text-gray-50 dark:text-gray-400">
{bodyText}
{" "}
{props.bodyText}{" "}
</p>
</a>
</div>
);
};
export const CardWithButton = ({ language = "en" }) => {
export const CardWithButton = () => {
return (
<div className="max-w-sm min-h-[290px] p-6 backdrop-blur-md rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<a target="_blank" href="#">
<div className="max-w-sm p-6 backdrop-blur-md rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<a
href="https://www.reuters.com/sustainability/land-use-biodiversity/comment-how-empowering-smallholder-farmers-with-ai-tools-can-bolster-global-food-2025-01-10/"
target="_blank"
>
<h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-50 dark:text-white">
{t("card_with_button_title", language)}
Empowering smallholder farmers with AI tools can bolster global food
security
</h5>
</a>
<p className="mb-3 font-normal text-gray-50 dark:text-gray-400">
{t("card_with_button_body", language)}
{" "}
AI-powered weather forecasts help rural Indian farmers make informed
planting decisions, reducing debt and boosting savings.
</p>
<a
href="https://www.reuters.com/sustainability/land-use-biodiversity/comment-how-empowering-smallholder-farmers-with-ai-tools-can-bolster-global-food-2025-01-10/"
target="_blank"
className="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl "
>
{t("card_with_button_read_more", language)}
Read more
<svg
className="rtl:rotate-180 w-3.5 h-3.5 ms-2"
aria-hidden="true"
@@ -147,9 +128,9 @@ export const CardWithButton = ({ language = "en" }) => {
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M1 5h12m0 0L9 1m4 4L9 9"
/>
</svg>
@@ -158,18 +139,17 @@ export const CardWithButton = ({ language = "en" }) => {
);
};
export const CardWithOnlyImage = ({ language = "en" }) => {
export const CardWithOnlyImage = () => {
return (
<div className="w-full h-full object-cover max-w-sm bg-white rounded-lg shadow-xl dark:bg-gray-800 dark:border-gray-700">
<div className="w-full max-w-sm bg-white rounded-lg shadow-xl dark:bg-gray-800 dark:border-gray-700">
<a
href="https://theprint.in/economy/telangana-is-the-success-story-of-indian-agritech-ai-tools-soil-testing-e-commerce-more/1630359/"
target="_blank"
className="w-full h-full"
>
<img
className="rounded-lg"
className=" rounded-lg"
src="https://i.pinimg.com/736x/2b/2a/0f/2b2a0f7003bd3e4201573c1189d600de.jpg"
alt={t("card_with_only_image_alt", language)}
alt="product image"
/>
</a>
</div>
@@ -186,30 +166,21 @@ const cards = [
export default cards;
export const CardLayout = ({ language = "en" }) => {
export const CardLayout = () => {
return (
<div>
<HeroSecn language={language} />
<div className="flex justify-center">
<div className="flex justify-between py-8 w-5/6 ">
<CardWithImage language={language} />
<HeroSecn />
<div className=" flex justify-center">
<div className=" flex justify-between py-8 w-5/6 ">
<cardWithImage />
<div className="flex flex-col gap-10 justify-between ">
<CardOnlyText
headingText={t("card_only_text_heading1", language)}
bodyText={t("card_only_text_body1", language)}
href="https://example.com/article1"
language={language}
/>
<CardWithButton language={language} />
<cardOnlyText />
<cardWithButton />
</div>
<div className="flex flex-col justify-between">
<CardWithOnlyImage language={language} />
<CardOnlyText
headingText={t("card_only_text_heading2", language)}
bodyText={t("card_only_text_body2", language)}
href="https://example.com/article2"
language={language}
/>
<div className=" flex flex-col justify-between">
<cardWithOnlyImage />
<cardOnlyText />
</div>
</div>
</div>
+11 -14
View File
@@ -1,13 +1,6 @@
import React from "react";
import { t } from "../../service/translation";
import { useOutletContext } from "react-router-dom";
const Customization = (props) => {
// Get language from context if available, else from props, default to "en"
const outletContext = useOutletContext?.();
const language =
(outletContext && outletContext.language) || props.language || "en";
const Customization = () => {
return (
<>
<section
@@ -18,20 +11,25 @@ const Customization = (props) => {
<div className="container mx-auto flex flex-col justify-around h-full w-full md:py-10">
<div className="text-center md:text-start flex flex-col justify-around h-full">
<h2 className="text-xl font-bold mb-4 text-yellow-600">
{t("customization_schedule", language)}
CUSTOMIZE WITH YOUR SCHEDULE
</h2>
<h1 className="text-2xl md:text-4xl md:font-extrabold font-bold mb-4">
{t("customization_tutors_title", language)}
Talented and Qualified Tutors to Serve You for Help
</h1>
<p className="text-base mb-8">
{t("customization_paragraph", language)}
Our scheduling system allows you to select based on free time.
Lorem ipsum demo text for template. Keep track of your students
class and tutoring schedules, and never miss your lectures. The
best online class scheduling system with easy accessibility.
Lorem ipsum is a placeholder text commonly used to demonstrate
the visual form
</p>
<div className="flex gap-4 justify-center md:justify-start">
<button
type="button"
className="focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg text-base px-5 py-2.5 mb-2 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900"
>
{t("customization_get_started", language)}
Get started
</button>
</div>
</div>
@@ -40,7 +38,7 @@ const Customization = (props) => {
<img
src="/images/interaction2.png"
className="w-full h-auto"
alt={t("customization_image_alt", language)}
alt=""
/>
</div>
</div>
@@ -50,4 +48,3 @@ const Customization = (props) => {
};
export default Customization;
+161 -14
View File
@@ -1,13 +1,6 @@
import React from "react";
import { t } from "../../service/translation";
import { useOutletContext } from "react-router-dom";
const Footer = (props) => {
// Get language from context if available, else from props, default to "en"
const outletContext = useOutletContext?.();
const language =
(outletContext && outletContext.language) || props.language || "en";
const Footer = () => {
return (
<>
<footer className="text-gray-50">
@@ -18,23 +11,178 @@ const Footer = (props) => {
<img
src="/images/logo.png"
className="h-9 rounded-full"
alt={t("footer_logo_alt", language)}
alt="Logo"
/>
<span className="self-center text-xl font-bold whitespace-nowrap dark:text-white">
{t("footer_brand", language)}
Crop Compass
</span>
</a>
</div>
<div className="grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3">
<div>
<h2 className="mb-6 text-sm font-semibold text-gray-50 uppercase dark:text-white">
Resources
</h2>
<ul className="text-gray-50 dark:text-gray-400 font-medium">
<li className="mb-4">
<a href="https://flowbite.com/" className="hover:underline">
Flowbite
</a>
</li>
<li>
<a
href="https://tailwindcss.com/"
className="hover:underline"
>
Tailwind CSS
</a>
</li>
</ul>
</div>
<div>
<h2 className="mb-6 text-sm font-semibold text-gray-50 uppercase dark:text-white">
Follow us
</h2>
<ul className="text-gray-50 dark:text-gray-400 font-medium">
<li className="mb-4">
<a
href="https://github.com/themesberg/flowbite"
className="hover:underline"
>
Github
</a>
</li>
<li>
<a
href="https://discord.gg/4eeurUVvTy"
className="hover:underline"
>
Discord
</a>
</li>
</ul>
</div>
<div>
<h2 className="mb-6 text-sm font-semibold text-gray-50 uppercase dark:text-white">
Legal
</h2>
<ul className="text-gray-50 dark:text-gray-400 font-medium">
<li className="mb-4">
<a href="#" className="hover:underline">
Privacy Policy
</a>
</li>
<li>
<a href="#" className="hover:underline">
Terms &amp; Conditions
</a>
</li>
</ul>
</div>
</div>
</div>
<hr className="my-6 border-gray-50 sm:mx-auto dark:border-gray-700 lg:my-8" />
<div className="sm:flex sm:items-center sm:justify-between">
<span className="text-sm text-gray-50 sm:text-center dark:text-gray-400">
© 2025{" "}
© 2024{" "}
<a href="/" className="hover:underline">
{t("footer_brand", language)}
Crop Compass
</a>
. {t("footer_rights_reserved", language)}
. All Rights Reserved.
</span>
<div className="flex mt-4 sm:justify-center sm:mt-0">
<a
href="#"
className="text-gray-50 hover:text-gray-900 dark:hover:text-white"
>
<svg
className="w-4 h-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 8 19"
>
<path
fillRule="evenodd"
d="M6.135 3H8V0H6.135a4.147 4.147 0 0 0-4.142 4.142V6H0v3h2v9.938h3V9h2.021l.592-3H5V3.591A.6.6 0 0 1 5.592 3h.543Z"
clipRule="evenodd"
/>
</svg>
<span className="sr-only">Facebook page</span>
</a>
<a
href="#"
className="text-gray-50 hover:text-gray-900 dark:hover:text-white ms-5"
>
<svg
className="w-4 h-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 21 16"
>
<path d="M16.942 1.556a16.3 16.3 0 0 0-4.126-1.3 12.04 12.04 0 0 0-.529 1.1 15.175 15.175 0 0 0-4.573 0 11.585 11.585 0 0 0-.535-1.1 16.274 16.274 0 0 0-4.129 1.3A17.392 17.392 0 0 0 .182 13.218a15.785 15.785 0 0 0 4.963 2.521c.41-.564.773-1.16 1.084-1.785a10.63 10.63 0 0 1-1.706-.83c.143-.106.283-.217.418-.33a11.664 11.664 0 0 0 10.118 0c.137.113.277.224.418.33-.544.328-1.116.606-1.71.832a12.52 12.52 0 0 0 1.084 1.785 16.46 16.46 0 0 0 5.064-2.595 17.286 17.286 0 0 0-2.973-11.59ZM6.678 10.813a1.941 1.941 0 0 1-1.8-2.045 1.93 1.93 0 0 1 1.8-2.047 1.919 1.919 0 0 1 1.8 2.047 1.93 1.93 0 0 1-1.8 2.045Zm6.644 0a1.94 1.94 0 0 1-1.8-2.045 1.93 1.93 0 0 1 1.8-2.047 1.918 1.918 0 0 1 1.8 2.047 1.93 1.93 0 0 1-1.8 2.045Z" />
</svg>
<span className="sr-only">Discord community</span>
</a>
<a
href="#"
className="text-gray-50 hover:text-gray-900 dark:hover:text-white ms-5"
>
<svg
className="w-4 h-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 17"
>
<path
fillRule="evenodd"
d="M20 1.892a8.178 8.178 0 0 1-2.355.635 4.074 4.074 0 0 0 1.8-2.235 8.344 8.344 0 0 1-2.605.98A4.13 4.13 0 0 0 13.85 0a4.068 4.068 0 0 0-4.1 4.038 4 4 0 0 0 .105.919A11.705 11.705 0 0 1 1.4.734a4.006 4.006 0 0 0 1.268 5.392 4.165 4.165 0 0 1-1.859-.5v.05A4.057 4.057 0 0 0 4.1 9.635a4.19 4.19 0 0 1-1.856.07 4.108 4.108 0 0 0 3.831 2.807A8.36 8.36 0 0 1 0 14.184 11.732 11.732 0 0 0 6.291 16 11.502 11.502 0 0 0 17.964 4.5c0-.177 0-.35-.012-.523A8.143 8.143 0 0 0 20 1.892Z"
clipRule="evenodd"
/>
</svg>
<span className="sr-only">Twitter page</span>
</a>
<a
href="#"
className="text-gray-50 hover:text-gray-900 dark:hover:text-white ms-5"
>
<svg
className="w-4 h-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 .333A9.911 9.911 0 0 0 6.866 19.65c.5.092.678-.215.678-.477 0-.237-.01-1.017-.014-1.845-2.757.6-3.338-1.169-3.338-1.169a2.627 2.627 0 0 0-1.1-1.451c-.9-.615.07-.6.07-.6a2.084 2.084 0 0 1 1.518 1.021 2.11 2.11 0 0 0 2.884.823c.044-.503.268-.973.63-1.325-2.2-.25-4.516-1.1-4.516-4.9A3.832 3.832 0 0 1 4.7 7.068a3.56 3.56 0 0 1 .095-2.623s.832-.266 2.726 1.016a9.409 9.409 0 0 1 4.962 0c1.89-1.282 2.717-1.016 2.717-1.016.366.83.402 1.768.1 2.623a3.827 3.827 0 0 1 1.02 2.659c0 3.807-2.319 4.644-4.525 4.889a2.366 2.366 0 0 1 .673 1.834c0 1.326-.012 2.394-.012 2.72 0 .263.18.572.681.475A9.911 9.911 0 0 0 10 .333Z"
clipRule="evenodd"
/>
</svg>
<span className="sr-only">GitHub account</span>
</a>
<a
href="#"
className="text-gray-50 hover:text-gray-900 dark:hover:text-white ms-5"
>
<svg
className="w-4 h-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 0a10 10 0 1 0 10 10A10.009 10.009 0 0 0 10 0Zm6.613 4.614a8.523 8.523 0 0 1 1.93 5.32 20.094 20.094 0 0 0-5.949-.274c-.059-.149-.122-.292-.184-.441a23.879 23.879 0 0 0-.566-1.239 11.41 11.41 0 0 0 4.769-3.366ZM8 1.707a8.821 8.821 0 0 1 2-.238 8.5 8.5 0 0 1 5.664 2.152 9.608 9.608 0 0 1-4.476 3.087A45.758 45.758 0 0 0 8 1.707ZM1.642 8.262a8.57 8.57 0 0 1 4.73-5.981A53.998 53.998 0 0 1 9.54 7.222a32.078 32.078 0 0 1-7.9 1.04h.002Zm2.01 7.46a8.51 8.51 0 0 1-2.2-5.707v-.262a31.64 31.64 0 0 0 8.777-1.219c.243.477.477.964.692 1.449-.114.032-.227.067-.336.1a13.569 13.569 0 0 0-6.942 5.636l.009.003ZM10 18.556a8.508 8.508 0 0 1-5.243-1.8 11.717 11.717 0 0 1 6.7-5.332.509.509 0 0 1 .055-.02 35.65 35.65 0 0 1 1.819 6.476 8.476 8.476 0 0 1-3.331.676Zm4.772-1.462A37.232 37.232 0 0 0 13.113 11a12.513 12.513 0 0 1 5.321.364 8.56 8.56 0 0 1-3.66 5.73h-.002Z"
clipRule="evenodd"
/>
</svg>
<span className="sr-only">Dribbble account</span>
</a>
</div>
</div>
</div>
</footer>
@@ -43,4 +191,3 @@ const Footer = (props) => {
};
export default Footer;
+36 -37
View File
@@ -1,24 +1,18 @@
import React from "react";
import { Link, useOutletContext } from "react-router-dom";
import { t } from "../../service/translation";
const Hero = (props) => {
// Get language from outlet context or props or default to 'en'
const outletContext = useOutletContext?.();
const language =
(outletContext && outletContext.language) || props.language || "en";
import { Link } from "react-router-dom";
const Hero = () => {
return (
<>
<section className="py-12 w-full flex justify-center pt-28 text-gray-100">
<section className=" py-12 w-full flex justify-center pt-28 text-gray-100">
<div className="flex flex-col-reverse md:flex-row justify-between w-10/12 h-auto">
<div className="container mx-auto flex flex-col justify-between h-full w-full">
<div className="text-center md:text-start flex flex-col justify-around h-full">
<h1 className="text-6xl md:text-6xl md:w-2/3 md:font-extrabold font-bold">
{t("hero_heading_main", language)}
Anything and Everything you Need to know About
</h1>
<p className="text-2xl font-semibold mb-8 ">
{t("hero_heading_sub", language)}
Your crops and their Health!
</p>
</div>
</div>
@@ -26,36 +20,37 @@ const Hero = (props) => {
<img
src="/images/plant.png"
className="w-full h-auto rounded-3xl shadow-xl"
alt={t("hero_image_alt", language)}
alt="plant"
/>
</div>
</div>
</section>
<div className="flex justify-center">
<div className="flex justify-between py-8 w-5/6">
<div className=" flex justify-center">
<div className=" flex justify-between py-8 w-5/6 ">
<div className="max-w-sm rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<a href="#">
<img
className="rounded-t-lg"
src="/images/plant.png"
alt={t("hero_card1_image_alt", language)}
alt="plant"
/>
</a>
<div className="p-8 backdrop-blur-md rounded-b-lg">
<a href="#">
<h5 className="mb-2 text-2xl font-bold tracking-tight text-white dark:text-white">
{t("hero_card1_title", language)}
Noteworthy technology acquisitions 2021
</h5>
</a>
<p className="mb-3 font-normal text-white dark:text-gray-400">
{t("hero_card1_body", language)}
Here are the biggest enterprise technology acquisitions of 2021
so far, in reverse chronological order.
</p>
<a
href="#"
className="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl"
className="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl "
>
{t("hero_card1_read_more", language)}
Read more
<svg
className="rtl:rotate-180 w-3.5 h-3.5 ms-2"
aria-hidden="true"
@@ -65,9 +60,9 @@ const Hero = (props) => {
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M1 5h12m0 0L9 1m4 4L9 9"
/>
</svg>
@@ -75,17 +70,18 @@ const Hero = (props) => {
</div>
</div>
<div className="flex flex-col gap-10 justify-between">
<div className="flex flex-col gap-10 justify-between ">
<div>
<a
href="#"
className="block max-w-sm p-6 rounded-lg shadow-md backdrop-blur-md dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
>
<h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-50 dark:text-white">
{t("hero_card2_title", language)}
Noteworthy technology acquisitions 2021
</h5>
<p className="font-normal text-gray-50 dark:text-gray-400">
{t("hero_card2_body", language)}
Here are the biggest enterprise technology acquisitions of
2021 so far, in reverse chronological order.
</p>
</a>
</div>
@@ -93,17 +89,18 @@ const Hero = (props) => {
<div className="max-w-sm p-6 backdrop-blur-md rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700">
<a href="#">
<h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-50 dark:text-white">
{t("hero_card3_title", language)}
Noteworthy technology acquisitions 2021
</h5>
</a>
<p className="mb-3 font-normal text-gray-50 dark:text-gray-400">
{t("hero_card3_body", language)}
Here are the biggest enterprise technology acquisitions of 2021
so far, in reverse chronological order.
</p>
<a
href="#"
className="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl"
className="inline-flex shadow-md backdrop-blur-md bg-gradient-to-tr from-gray-700/20 to-gray-50/20 items-center px-3 py-2 text-sm font-medium text-center text-white rounded-lg hover:backdrop-blur-xl "
>
{t("hero_card3_read_more", language)}
Read more
<svg
className="rtl:rotate-180 w-3.5 h-3.5 ms-2"
aria-hidden="true"
@@ -113,9 +110,9 @@ const Hero = (props) => {
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M1 5h12m0 0L9 1m4 4L9 9"
/>
</svg>
@@ -123,13 +120,13 @@ const Hero = (props) => {
</div>
</div>
<div className="flex flex-col justify-between">
<div className=" flex flex-col justify-between">
<div className="w-full max-w-sm bg-white rounded-lg shadow-xl dark:bg-gray-800 dark:border-gray-700">
<a href="#">
<img
className="rounded-lg"
className=" rounded-lg"
src="/images/plant.png"
alt={t("hero_card4_image_alt", language)}
alt="product image"
/>
</a>
</div>
@@ -140,10 +137,11 @@ const Hero = (props) => {
className="block max-w-sm p-6 backdrop-blur-xl rounded-lg shadow-md dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"
>
<h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-50 dark:text-white">
{t("hero_card5_title", language)}
Noteworthy technology acquisitions 2021
</h5>
<p className="font-normal text-gray-50 dark:text-gray-400">
{t("hero_card5_body", language)}
Here are the biggest enterprise technology acquisitions of
2021 so far, in reverse chronological order.
</p>
</a>
</div>
@@ -156,3 +154,4 @@ const Hero = (props) => {
export default Hero;
// {grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2}
+18 -51
View File
@@ -1,17 +1,7 @@
import React from "react";
import React from 'react'
import { motion } from "framer-motion";
import { useInView } from "react-intersection-observer";
import {
CardOnlyText,
CardWithButton,
CardWithImage,
CardWithOnlyImage,
HeroSecn,
} from "./Cards";
import Testimonial from "./Testimonial";
import Navbar2 from "../../components/Navbar2";
import { t } from "../../service/translation";
import { useOutletContext } from "react-router-dom";
import { CardOnlyText, CardWithButton, CardWithImage, CardWithOnlyImage, HeroSecn, } from "./Cards";
const ScrollReveal = ({ children, direction = "left" }) => {
const { ref, inView } = useInView({ triggerOnce: true, threshold: 0.2 });
@@ -35,57 +25,34 @@ const ScrollReveal = ({ children, direction = "left" }) => {
);
};
function Hero2(props) {
// Get language from context if available, else from props, default to "en"
const outletContext = useOutletContext?.();
const language =
(outletContext && outletContext.language) || props.language || "en";
function Hero2() {
const myRef = document.querySelector('.scrollable-div')
return (
<div>
<ScrollReveal direction="up">
<HeroSecn language={language} />
<ScrollReveal direction='up'>
<HeroSecn />
</ScrollReveal>
<Testimonial language={language} />
<div className="flex justify-center">
<div className="flex justify-between py-8 w-5/6 ">
<ScrollReveal direction="up">
<CardWithImage language={language} />
<div className=" flex justify-center">
<div className=" flex justify-between py-8 w-5/6 ">
<ScrollReveal direction='up'>
<CardWithImage />
</ScrollReveal>
<div className="flex flex-col gap-10 justify-between ">
<ScrollReveal direction="up">
<CardOnlyText
headingText={t("hero2_card1_heading", language)}
bodyText={t("hero2_card1_body", language)}
href="https://www.weforum.org/impact/ai-for-agriculture-in-india/"
language={language}
/>
</ScrollReveal>
<ScrollReveal direction="up">
<CardWithButton language={language} />
</ScrollReveal>
<ScrollReveal direction='up' > <CardOnlyText headingText = {"AI for agriculture: How Indian farmers are harvesting innovation"} bodyText={"Farmers participating in the programme saw a 21% increase in chili yields per acre, a 9% reduction in pesticide use, a 5% decrease in fertilizer usage, and an 8% improvement in unit prices due to quality enhancements."} href={"https://www.weforum.org/impact/ai-for-agriculture-in-india/ "} /> </ScrollReveal>
<ScrollReveal direction='up'> <CardWithButton /> </ScrollReveal>
</div>
<div className="flex flex-col justify-between">
<ScrollReveal direction="up">
<CardOnlyText
headingText={t("hero2_card2_heading", language)}
bodyText={t("hero2_card2_body", language)}
href="https://arxiv.org/abs/2301.08405"
language={language}
/>
</ScrollReveal>
<ScrollReveal direction="up">
<CardWithOnlyImage language={language} />
</ScrollReveal>
<div className=" flex flex-col justify-between">
<ScrollReveal direction='up'> <CardOnlyText headingText={"SugarChain: Blockchain technology meets Agriculture"} bodyText={"The use of blockchain technology can help farmers automate processes with high trust, addressing issues like middlemen involvement and ensuring accurate compensation for their products"} href={"https://arxiv.org/abs/2301.08405"} /> </ScrollReveal>
<ScrollReveal direction='up'> <CardWithOnlyImage /> </ScrollReveal>
</div>
</div>
</div>
</div>
);
)
}
export default Hero2;
export default Hero2

Some files were not shown because too many files have changed in this diff Show More