Anonymous
NextJs; TypingRor: HandleCoplete не является функцией
Сообщение
Anonymous » 13 мар 2025, 16:01
Хотя я правильно передавал реквизит, я продолжаю получать «не функционировать». Я много работал над этим, но я не мог найти решение. Когда я пытаюсь переместить (я выполняю необходимую реализацию) Handlecomplete Функция в productAddtemplate.tsx , на этот раз я получаю setIssubmitting () не ошибкой функции.
https://i.sstatic.net/v8egtedo.png "/> addproduct.tsx:
Код: Выделить всё
"use client";
import React, { useState } from "react";
import PageBreadcrumb from "@/components/common/PageBreadCrumb";
import { ProductAddTemplate } from "../templates/ProductAddTemplate";
import { Product } from "../types/types";
import { Step } from "../types/types";
import { motion } from "framer-motion";
import { FileSpreadsheet, Edit, CheckCircle, ArrowRight } from "lucide-react";
import { ProductService } from "@/utils/api/services/productService";
import {toast} from "sonner";
export default function AddProduct(): React.ReactElement {
const [currentStep, setCurrentStep] = useState(0);
const [selectedMethod, setSelectedMethod] = useState(null);
const [productName, setProductName] = useState("");
const [selectedProducts, setSelectedProducts] = useState([]);
const [isSubmitting, setIsSubmitting] = useState(false);
// Adımları tanımlayalım - renkli ve ikonlu
const steps: Step[] = [
{
id: 0,
title: "Yükleme Yöntemi",
icon: ,
color: "bg-blue-500"
},
{
id: 1,
title: "Ürün Bilgileri",
icon: ,
color: "bg-purple-500"
},
{
id: 2,
title: "Önizleme",
icon: ,
color: "bg-amber-500"
},
{
id: 3,
title: "Tamamlandı",
icon: ,
color: "bg-green-500"
}
];
// Yükleme yöntemini seçme işlevi
const handleSelectMethod = (method: "manual" | "excel"): void => {
setSelectedMethod(method);
// Animasyon için timeout
setTimeout(() => {
setCurrentStep(1); // Bir sonraki adıma geç
}, 300);
};
// Ürün ekleme
const handleAddProduct = (): void => {
if (productName.trim() === "") return;
// Basit bir ürün oluştur (gerçek uygulamada API'den gelecek)
const newProduct: Product = {
id: Date.now(), // Geçici ID
name: productName
};
// Animasyonlu ekleme
setSelectedProducts(prev => [...prev, newProduct]);
setProductName(""); // Input'u temizle
};
// Ürün kaldırma
const handleRemoveProduct = (productId: number): void => {
setSelectedProducts(selectedProducts.filter(p => p.id !== productId));
};
// Sıfırlama işlevi
const handleReset = (): void => {
setCurrentStep(0);
setSelectedProducts([]);
setProductName("");
setSelectedMethod(null);
};
// Son adıma geçildiğinde ürünleri API'ye gönder ve konfeti efekti
// Ürün ekleme işlemini tamamla
// Ürün ekleme işlemini tamamla
const handleComplete = async (): Promise => {
// Ürün kontrolü
if (selectedMethod === "manual" && selectedProducts.length === 0) {
toast.warning('Lütfen en az bir ürün ekleyin.');
return;
}
// Yükleme durumunu başlat
setIsSubmitting(true);
// Ürün verilerini hazırla
interface ProductData {
productNames: string[];
method: "manual" | "excel" | null;
}
const productData: ProductData = {
productNames: selectedProducts.map((product: Product) => product.name),
method: selectedMethod
};
try {
// API çağrısını yap
let success: boolean = false;
if (selectedMethod === "manual") {
// Manuel ekleme için API çağrısı
interface ApiResponse {
isSuccessful: boolean;
errorMessages?: string[];
data?: any;
}
const response: ApiResponse | undefined = await ProductService.create(productData);
success = Boolean(response && response.isSuccessful);
} else {
// Excel yükleme için farklı bir API çağrısı (örnek)
// const response = await ProductService.uploadExcel(excelFile);
// success = Boolean(response && response.isSuccessful);
// Şimdilik Excel yüklemesini başarılı sayalım
success = true;
}
// Sonuca göre işlem yap
if (success) {
// Başarılı olursa son adıma geç
setCurrentStep(3);
// Konfeti efekti
// Başarı mesajı
const productCount: number | string = selectedMethod === "manual"
? selectedProducts.length
: "Excel'den yüklenen";
toast.success(`${productCount} ürün başarıyla eklendi.`);
} else {
// Hata mesajı
toast.error("Ürünler eklenirken bir hata oluştu. Lütfen tekrar deneyin.");
}
} catch (error: unknown) {
// Hata durumunda
console.error("Ürün ekleme işlemi başarısız:", error);
// Hata mesajını daha detaylı göster
if (error instanceof Error) {
toast.error(`Hata: ${error.message}`);
} else {
toast.error("Bir hata oluştu. Lütfen daha sonra tekrar deneyin.");
}
} finally {
// Her durumda yükleme durumunu sonlandır
setIsSubmitting(false);
}
};
return (
);
}< /code>
< /div>
< /div>
productadtemplate.tsx:
import React from "react";
import { StepIndicator } from "../molecules/StepIndicator";
import { MethodSelection } from "../organisms/MethodSelection";
import { StepHeader } from "../organisms/StepHeader";
import { ManualProductEntry } from "../organisms/ManualProductEntry";
import { ExcelUpload } from "../organisms/ExcelUpload";
import { ProductPreview } from "../organisms/ProductPreview";
import { CompletionMessage } from "../organisms/CompletionMessage";
import ComponentCard from "@/components/common/ComponentCard";
import { Step } from "../types/types";
import { Product } from "../types/types";
import { useRouter } from 'next/navigation';
import { motion, AnimatePresence } from "framer-motion";
import { ArrowRight, ArrowLeft, CheckCircle } from "lucide-react";
import {toast} from "sonner";
import ProductService from "@/utils/api/services/productService";
interface ProductAddTemplateProps {
currentStep: number;
steps: Step[];
selectedMethod: "manual" | "excel" | null;
productName: string;
setProductName: (name: string) => void;
selectedProducts: Product[];
handleSelectMethod: (method: "manual" | "excel") => void;
handleAddProduct: () => void;
handleRemoveProduct: (productId: number) => void;
setCurrentStep: (step: number) => void;
handleReset: () => void;
isSubmitting?: boolean;
handleComplete: () => Promise;
}
export const ProductAddTemplate: React.FC = ({
currentStep,
steps,
selectedMethod,
productName,
setProductName,
selectedProducts,
handleSelectMethod,
handleAddProduct,
handleRemoveProduct,
setCurrentStep,
handleReset,
isSubmitting = false,
handleComplete
}) => {
const router = useRouter();
// Adım geçişleri için animasyon varyantları
const variants = {
hidden: { opacity: 0, x: 50 },
visible: { opacity: 1, x: 0 },
exit: { opacity: 0, x: -50 }
};
// Adım başlıklarını ve renklerini belirle
const getStepColor = (stepId: number) => {
const colors = ["bg-blue-500", "bg-purple-500", "bg-amber-500", "bg-green-500"];
return colors[stepId] || colors[0];
};
// Adım 3'e geçiş için işlev - async olarak işaretlendi
const goToFinalStep = async (): Promise => {
console.log("handleComplete type:", typeof handleComplete);
await handleComplete();
};
return (
{/* Adım göstergesi - renkli ve animasyonlu */}
{/* Adım 0: Yükleme Yöntemi Seçimi */}
{currentStep === 0 && (
)}
{/* Adım 1: Ürün Bilgileri */}
{currentStep === 1 && (
setCurrentStep(0)}
/>
{selectedMethod === "manual" ? (
setCurrentStep(2)}
buttonColor={getStepColor(1)}
/>
) : (
setCurrentStep(2)}
buttonColor={getStepColor(1)}
/>
)}
)}
{/* Adım 2: Önizleme */}
{currentStep === 2 && (
setCurrentStep(1)}
/>
setCurrentStep(1)}
onConfirm={goToFinalStep}
buttonColor={getStepColor(2)}
isSubmitting={isSubmitting}
/>
)}
{/* Adım 3: Tamamlandı */}
{currentStep === 3 && (
router.push('/products')}
color={getStepColor(3)}
isProcessing={isSubmitting}
/>
)}
{/* İlerleme göstergesi */}
{currentStep > 0 && currentStep < 3 && (
setCurrentStep(currentStep - 1)}
className="flex items-center text-gray-600 hover:text-gray-900 transition-colors"
disabled={isSubmitting}
>
Geri
)}
Adım {currentStep + 1}/{steps.length}
{currentStep === 3 && (
)}
{currentStep < 2 && currentStep > 0 && (
setCurrentStep(currentStep + 1)}
className="flex items-center text-gray-600 hover:text-gray-900 transition-colors"
disabled={isSubmitting}
>
İleri
)}
);
};
Подробнее здесь:
https://stackoverflow.com/questions/795 ... a-function
1741870883
Anonymous
Хотя я правильно передавал реквизит, я продолжаю получать «не функционировать». Я много работал над этим, но я не мог найти решение. Когда я пытаюсь переместить (я выполняю необходимую реализацию) Handlecomplete Функция в productAddtemplate.tsx , на этот раз я получаю setIssubmitting () не ошибкой функции. https://i.sstatic.net/v8egtedo.png "/> addproduct.tsx: [code]"use client"; import React, { useState } from "react"; import PageBreadcrumb from "@/components/common/PageBreadCrumb"; import { ProductAddTemplate } from "../templates/ProductAddTemplate"; import { Product } from "../types/types"; import { Step } from "../types/types"; import { motion } from "framer-motion"; import { FileSpreadsheet, Edit, CheckCircle, ArrowRight } from "lucide-react"; import { ProductService } from "@/utils/api/services/productService"; import {toast} from "sonner"; export default function AddProduct(): React.ReactElement { const [currentStep, setCurrentStep] = useState(0); const [selectedMethod, setSelectedMethod] = useState(null); const [productName, setProductName] = useState(""); const [selectedProducts, setSelectedProducts] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); // Adımları tanımlayalım - renkli ve ikonlu const steps: Step[] = [ { id: 0, title: "Yükleme Yöntemi", icon: , color: "bg-blue-500" }, { id: 1, title: "Ürün Bilgileri", icon: , color: "bg-purple-500" }, { id: 2, title: "Önizleme", icon: , color: "bg-amber-500" }, { id: 3, title: "Tamamlandı", icon: , color: "bg-green-500" } ]; // Yükleme yöntemini seçme işlevi const handleSelectMethod = (method: "manual" | "excel"): void => { setSelectedMethod(method); // Animasyon için timeout setTimeout(() => { setCurrentStep(1); // Bir sonraki adıma geç }, 300); }; // Ürün ekleme const handleAddProduct = (): void => { if (productName.trim() === "") return; // Basit bir ürün oluştur (gerçek uygulamada API'den gelecek) const newProduct: Product = { id: Date.now(), // Geçici ID name: productName }; // Animasyonlu ekleme setSelectedProducts(prev => [...prev, newProduct]); setProductName(""); // Input'u temizle }; // Ürün kaldırma const handleRemoveProduct = (productId: number): void => { setSelectedProducts(selectedProducts.filter(p => p.id !== productId)); }; // Sıfırlama işlevi const handleReset = (): void => { setCurrentStep(0); setSelectedProducts([]); setProductName(""); setSelectedMethod(null); }; // Son adıma geçildiğinde ürünleri API'ye gönder ve konfeti efekti // Ürün ekleme işlemini tamamla // Ürün ekleme işlemini tamamla const handleComplete = async (): Promise => { // Ürün kontrolü if (selectedMethod === "manual" && selectedProducts.length === 0) { toast.warning('Lütfen en az bir ürün ekleyin.'); return; } // Yükleme durumunu başlat setIsSubmitting(true); // Ürün verilerini hazırla interface ProductData { productNames: string[]; method: "manual" | "excel" | null; } const productData: ProductData = { productNames: selectedProducts.map((product: Product) => product.name), method: selectedMethod }; try { // API çağrısını yap let success: boolean = false; if (selectedMethod === "manual") { // Manuel ekleme için API çağrısı interface ApiResponse { isSuccessful: boolean; errorMessages?: string[]; data?: any; } const response: ApiResponse | undefined = await ProductService.create(productData); success = Boolean(response && response.isSuccessful); } else { // Excel yükleme için farklı bir API çağrısı (örnek) // const response = await ProductService.uploadExcel(excelFile); // success = Boolean(response && response.isSuccessful); // Şimdilik Excel yüklemesini başarılı sayalım success = true; } // Sonuca göre işlem yap if (success) { // Başarılı olursa son adıma geç setCurrentStep(3); // Konfeti efekti // Başarı mesajı const productCount: number | string = selectedMethod === "manual" ? selectedProducts.length : "Excel'den yüklenen"; toast.success(`${productCount} ürün başarıyla eklendi.`); } else { // Hata mesajı toast.error("Ürünler eklenirken bir hata oluştu. Lütfen tekrar deneyin."); } } catch (error: unknown) { // Hata durumunda console.error("Ürün ekleme işlemi başarısız:", error); // Hata mesajını daha detaylı göster if (error instanceof Error) { toast.error(`Hata: ${error.message}`); } else { toast.error("Bir hata oluştu. Lütfen daha sonra tekrar deneyin."); } } finally { // Her durumda yükleme durumunu sonlandır setIsSubmitting(false); } }; return ( ); }< /code> < /div> < /div> productadtemplate.tsx: import React from "react"; import { StepIndicator } from "../molecules/StepIndicator"; import { MethodSelection } from "../organisms/MethodSelection"; import { StepHeader } from "../organisms/StepHeader"; import { ManualProductEntry } from "../organisms/ManualProductEntry"; import { ExcelUpload } from "../organisms/ExcelUpload"; import { ProductPreview } from "../organisms/ProductPreview"; import { CompletionMessage } from "../organisms/CompletionMessage"; import ComponentCard from "@/components/common/ComponentCard"; import { Step } from "../types/types"; import { Product } from "../types/types"; import { useRouter } from 'next/navigation'; import { motion, AnimatePresence } from "framer-motion"; import { ArrowRight, ArrowLeft, CheckCircle } from "lucide-react"; import {toast} from "sonner"; import ProductService from "@/utils/api/services/productService"; interface ProductAddTemplateProps { currentStep: number; steps: Step[]; selectedMethod: "manual" | "excel" | null; productName: string; setProductName: (name: string) => void; selectedProducts: Product[]; handleSelectMethod: (method: "manual" | "excel") => void; handleAddProduct: () => void; handleRemoveProduct: (productId: number) => void; setCurrentStep: (step: number) => void; handleReset: () => void; isSubmitting?: boolean; handleComplete: () => Promise; } export const ProductAddTemplate: React.FC = ({ currentStep, steps, selectedMethod, productName, setProductName, selectedProducts, handleSelectMethod, handleAddProduct, handleRemoveProduct, setCurrentStep, handleReset, isSubmitting = false, handleComplete }) => { const router = useRouter(); // Adım geçişleri için animasyon varyantları const variants = { hidden: { opacity: 0, x: 50 }, visible: { opacity: 1, x: 0 }, exit: { opacity: 0, x: -50 } }; // Adım başlıklarını ve renklerini belirle const getStepColor = (stepId: number) => { const colors = ["bg-blue-500", "bg-purple-500", "bg-amber-500", "bg-green-500"]; return colors[stepId] || colors[0]; }; // Adım 3'e geçiş için işlev - async olarak işaretlendi const goToFinalStep = async (): Promise => { console.log("handleComplete type:", typeof handleComplete); await handleComplete(); }; return ( {/* Adım göstergesi - renkli ve animasyonlu */} {/* Adım 0: Yükleme Yöntemi Seçimi */} {currentStep === 0 && ( )} {/* Adım 1: Ürün Bilgileri */} {currentStep === 1 && ( setCurrentStep(0)} /> {selectedMethod === "manual" ? ( setCurrentStep(2)} buttonColor={getStepColor(1)} /> ) : ( setCurrentStep(2)} buttonColor={getStepColor(1)} /> )} )} {/* Adım 2: Önizleme */} {currentStep === 2 && ( setCurrentStep(1)} /> setCurrentStep(1)} onConfirm={goToFinalStep} buttonColor={getStepColor(2)} isSubmitting={isSubmitting} /> )} {/* Adım 3: Tamamlandı */} {currentStep === 3 && ( router.push('/products')} color={getStepColor(3)} isProcessing={isSubmitting} /> )} {/* İlerleme göstergesi */} {currentStep > 0 && currentStep < 3 && ( setCurrentStep(currentStep - 1)} className="flex items-center text-gray-600 hover:text-gray-900 transition-colors" disabled={isSubmitting} > Geri )} Adım {currentStep + 1}/{steps.length} {currentStep === 3 && ( )} {currentStep < 2 && currentStep > 0 && ( setCurrentStep(currentStep + 1)} className="flex items-center text-gray-600 hover:text-gray-900 transition-colors" disabled={isSubmitting} > İleri )} ); };[/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79506072/nextjs-typeerror-handlecomplete-is-not-a-function[/url]