چگونه با Next.js 13، Typescript و Firebase یک برنامه مدیریت فروش ساختم

در این آموزش، نحوه ساختن یک برنامه مدیریت فروش را به شما توضیح می دهم که به صاحبان فروشگاه یا صندوقداران امکان می دهد با استفاده از Next.js v13، Typescript و Firebase، فروش را ثبت و پیگیری کنند.
پس از تکمیل، میتوانید با استفاده از ویژگیهای شگفتانگیز Firebase، مانند پایگاهداده بلادرنگ و احراز هویت، برنامههای کاربردی وب پیشرفته در دنیای واقعی ایجاد کنید.
💡 PS: این آموزش فرض می کند که شما دانش اولیه React یا Next.js را دارید.
گردش کار برنامه
قبل از شروع کدنویسی، اجازه دهید نحوه عملکرد برنامه را خلاصه کنم. اپلیکیشن موارد زیر را انجام می دهد:
- احراز هویت کاربران از طریق ایمیل و رمز عبور با Firebase،
- به کاربر (صندوقدار یا صاحب فروشگاه) اجازه می دهد تا دسته بندی های مختلفی برای محصولات ایجاد کند،
- افزودن و حذف محصولات از برنامه، و
- فروش روزانه را ثبت و پیگیری کنید.
در اینجا یک نسخه ی نمایشی کوتاه از برنامه است:
https://www.youtube.com/watch?v=Vq1xlL1g9eY
💡 نسخه زنده برنامه را بررسی کنید. نام کاربری است
admin@test.com
و رمز عبور استadmin123
فرآیند طراحی رابط کاربری
در اینجا، من شما را از طریق ایجاد صفحات مورد نیاز برای برنامه وب راهنمایی می کنم.
اول از همه، شما باید یک صفحه ورود ایجاد کنید. شما نیازی به ایجاد یک صفحه ثبت نام ندارید زیرا این صفحه منحصر به فرد کاربر (صندوقدار/صاحب فروشگاه) است.
در مرحله بعد، یک صفحه داشبورد که معیارهای برنامه را نشان می دهد و همچنین شامل پیمایش به صفحات دیگر است.
شما همچنین به یک صفحه محصولات نیاز دارید که در آن کاربر بتواند محصولات جدید را در صورت موجود بودن اضافه کند و در هر زمانی محصولات را حذف کند.
بعد، یک صفحه دستهها ایجاد کنید تا کاربران بتوانند دستهها را اضافه یا حذف کنند.
در نهایت، باید بخش اصلی برنامه – صفحه فروش را ایجاد کنید، جایی که کاربر می تواند فروش های قبلی را مشاهده کند و موارد جدید اضافه کند.
میتوانید یک فیلد ورودی تاریخ را در این صفحه اضافه کنید تا کاربر بتواند فروشهای انجام شده برای هر روز را مانند تصویر زیر واکشی کند.
مولفه افزودن فروش جدید میتواند یک مودال باشد که وقتی کاربر روی آن کلیک میکند نشان داده میشود Add New Sales
دکمه.
در بخشهای آینده، نحوه ایجاد و اتصال پایگاه داده پشتیبان به رابط کاربری و تعامل با Firebase در برنامه Next.js را خواهید آموخت.
Firebase چیست؟
Firebase یک Backend-as-a-Service (Baas) متعلق به گوگل است که به توسعه دهندگان این امکان را می دهد تا در چند دقیقه برنامه های تحت وب کامل را بسازند. خدماتی مانند Firebase ساخت برنامه های کاربردی وب تمام پشته با مهارت های برنامه نویسی کم یا بدون مهارت را برای توسعه دهندگان فرانت اند بسیار آسان می کند.
Firebase روش های مختلف احراز هویت، پایگاه داده NoSQL، پایگاه داده بلادرنگ، ذخیره سازی فایل، توابع ابری، خدمات میزبانی و بسیاری موارد دیگر را ارائه می دهد.
چگونه Firebase را به برنامه Next.js اضافه کنیم
برای افزودن Firebase به برنامه Next.js، مراحل زیر را دنبال کنید:
یک برنامه Next.js 13 ایجاد کنید که از Typescript و the استفاده می کند app
روتر.
npx create-next-app sales-app
از کنسول Firebase دیدن کنید و با یک حساب Gmail وارد شوید.
پس از ورود به سیستم، یک پروژه Firebase ایجاد کنید.
انتخاب کنید </>
برای ایجاد یک برنامه وب Firebase جدید.
نام برنامه خود را وارد کنید و برنامه را ثبت کنید.
با اجرای قطعه کد زیر Firebase SDK را نصب کنید.
npm install firebase
ایجاد یک firebase.ts
فایل را در ریشه پروژه Next.js خود قرار دهید و کد پیکربندی Firebase را برای برنامه خود در فایل کپی کنید.
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
const firebaseConfig = {
apiKey: "*****",
authDomain: "*****",
projectId: "*****",
storageBucket: "*****",
messagingSenderId: "*******",
appId: "********",
measurementId: "********"
};
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
در نهایت، به روز رسانی کنید firebase.ts
حاوی برخی از ماژول های مورد نیاز برای احراز هویت Firebase و پایگاه داده Firestore.
import { initializeApp, getApps } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { EmailAuthProvider } from "firebase/auth";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "AIzaSyCtmI3jLzqDSr3UIwuUdBa5ocsN5vjzpW8",
authDomain: "stock-taking-19198.firebaseapp.com",
projectId: "stock-taking-19198",
storageBucket: "stock-taking-19198.appspot.com",
messagingSenderId: "228033001185",
appId: "1:228033001185:web:b2020053fb824a87d9a9a0",
measurementId: "G-79BQVKMPSR"
};
// Initialize Firebase
let app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
const provider = new EmailAuthProvider();
const db = getFirestore(app);
const auth = getAuth(app);
export { provider, auth };
export default db;
تبریک میگوییم!🎉 شما با موفقیت Firebase را به برنامه Next.js خود اضافه کردید. در مرحله بعد، بیایید ویژگی های Firebase مورد نیاز را تنظیم کنیم.
راه اندازی Firebase Authentication
قبل از اینکه بتوانید احراز هویت Firebase را به برنامه خود اضافه کنید، باید آن را در کنسول خود تنظیم کنید.
در پنل سمت چپ Build را انتخاب کرده و روی Authentication کلیک کنید.
روی دکمه شروع کلیک کنید، روش ایمیل/رمز عبور را فعال کنید و روی ذخیره کلیک کنید.
اگر موفقیت آمیز بود، صفحه شما باید این را نشان دهد:
راه اندازی Firebase Firestore
Firestore Database را از منوی سمت چپ انتخاب کنید و یک پایگاه داده ایجاد کنید.
پایگاه داده را در حالت تست ایجاد کنید و از تنظیمات مکان پیش فرض Cloud Firestore استفاده کنید.
پس از ایجاد پایگاه داده خود را انتخاب کنید Usage
از نوار منوی بالا، قوانین را ویرایش کنید و تغییرات را منتشر کنید. این به شما امکان می دهد برای مدت زمان طولانی تری به پایگاه داده درخواست دهید.
💡 PS: اگر این را به عنوان یک پروژه جانبی نمیسازید، مطمئن شوید که پایگاه داده را به حالت تولید تغییر دهید تا از حملات سایبری برنامه خود جلوگیری کنید.
در نهایت، سه مجموعه پایگاه داده برای دسته ها، محصولات و داده های فروش ایجاد کنید.
تبریک می گویم!🎉 پایگاه داده شما آماده است. به زودی نحوه تعامل با آن را خواهید آموخت.
احراز هویت کاربر با Firebase Auth
در این بخش، شما را با جنبه احراز هویت سیستم مدیریت فروش آشنا خواهم کرد. شما یاد خواهید گرفت که چگونه کاربران را وارد و از برنامه خارج کنید و چگونه از صفحات حاوی داده های محرمانه در برابر کاربران احراز هویت نشده محافظت کنید.
ابتدا a ایجاد کنید utils.ts
فایلی که حاوی توابع و وارد کردن آنها به اجزای مورد نیاز است.
ورود به برنامه
تابع زیر به کاربر امکان دسترسی به برنامه را می دهد. ایمیل و رمز عبور کاربر را می پذیرد و یک شی کاربر حاوی تمام اطلاعات کاربر را برمی گرداند.
می توانید یک کاربر جدید در کنسول Firebase خود ایجاد کنید و هنگام ارسال فرم ورود به سیستم، عملکرد زیر را اجرا کنید.
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context";
import { signInWithEmailAndPassword } from "firebase/auth";
import { auth } from "./firebase";
export const LoginUser = (email: string, password: string, router: AppRouterInstance) => {
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
const user = userCredential.user;
//👇🏻 logs user's details
console.log("User >>", user);
successMessage("Authentication successful 🎉");
router.push("/dashboard");
})
.catch((error) => {
console.error(error);
errorMessage("Incorrect Email/Password ❌");
});
};
قطعه کد بالا اعتبار کاربر را تأیید می کند و یک شی حاوی تمام اطلاعات مربوط به کاربر را برمی گرداند. اگر فرآیند موفقیت آمیز باشد، کاربر را به صفحه داشبورد هدایت می کند. در غیر این صورت یک خطا برمی گرداند.
خروج کاربران از برنامه
Firebase همچنین ارائه می دهد signOut
عملکردی که کاربران را قادر می سازد از برنامه خارج شوند.
هم اکنون به چگونگی کارکرد آن می پردازیم:
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context";
import { signOut } from "firebase/auth";
import { auth } from "./firebase";
export const LogOut = (router: AppRouterInstance) => {
signOut(auth)
.then(() => {
successMessage("Logout successful! 🎉");
router.push("/");
})
.catch((error) => {
errorMessage("Couldn't sign out ❌");
});
};
قطعه کد بالا، کاربران را با دریافت اطلاعات کاربر فعال و خروج آنها از برنامه خارج می کند. signOut
تابع.
محافظت از صفحات در برابر کاربران احراز هویت نشده
برای انجام این کار، میتوانید شی جزئیات کاربر را پس از ورود به سیستم ذخیره کنید یا از Firebase استفاده کنید onAuthStateChanged
قلاب.
با استفاده از onAuthStateChanged
قلاب:
"use client"
import { auth } from '@/firebase'
import { onAuthStateChanged } from "firebase/auth";
import { useState, useCallback, useEffect } from "react"
const isUserLoggedIn = useCallback(() => {
onAuthStateChanged(auth, (user) => {
if (user) {
setUser({ email: user.email, uid: user.uid });
//👉🏻 Perform an authenticated request
} else {
return router.push("/");
}
});
}, [router]);
useEffect(() => {
isUserLoggedIn();
}, [isUserLoggedIn]);
این onAuthStateChanged
hook بررسی می کند که آیا کاربر فعال است یا خیر و شیء حاوی تمام جزئیات کاربر را برمی گرداند. میتوانید این تابع را در بارگذاری صفحه برای همه مسیرها، به جز صفحه ورود، اجرا کنید.
ارتباط بلادرنگ با Firebase: ساختار داده و عملیات CRUD
در این بخش، شما را با راه اندازی ساختار داده برای برنامه کاربردی و تعامل با Firebase آشنا می کنم.
مجموعه دسته ها
اولین صفحه ای که در این برنامه راه اندازی می شود صفحه دسته بندی ها است زیرا زمانی که کاربر محصولی را اضافه می کند، باید تحت یک دسته باشد.
بنابراین صفحه دسته بندی های خود را مشابه تصویر زیر ایجاد کنید.
وقتی کاربر دسته جدیدی را اضافه می کند، قطعه کد زیر را اجرا کنید.
import { collection, addDoc } from "firebase/firestore";
import db from "./firebase";
export const addCategory = async (name: string) => {
try {
await addDoc(collection(db, "categories"), {
name
})
successMessage(`${name} category added! 🎉`)
} catch (err) {
errorMessage("Error! ❌")
console.error(err)
}
}
قطعه کد بالا نام دسته را از قسمت ورودی می پذیرد و یک سند (دسته) جدید در Firebase ایجاد می کند.
برای حذف یک دسته، قطعه کد زیر را زمانی که کاربر روی دکمه حذف کلیک کرد اجرا کنید.
export const deleteCategory = async (id: string, name:string) => {
try {
//👇🏻 deletes the category
await deleteDoc(doc(db, "categories", id));
//👇🏻 delets the products within the category
const q = query(collection(db, "products"), where("category", "==", name));
const unsubscribe = onSnapshot(q, (querySnapshot) => {
querySnapshot.forEach((document) => {
deleteDoc(doc(db, "products", document.id));
});
});
successMessage(`${name} category deleted 🎉`)
} catch (err) {
errorMessage("Encountered an error ❌")
console.log(err)
}
}
این deleteCategory
تابع بالا شناسه و نام دسته انتخابی را می پذیرد، دسته را از لیست حذف می کند و محصولات زیر دسته انتخابی را حذف می کند.
در نهایت، شما باید لیست دسته ها را هنگام بارگیری صفحه از Firebase دریافت کنید. برای این کار تابع زیر را اجرا کنید:
export const getCategories = async (setCategories: any) => {
try {
const unsub = onSnapshot(collection(db, "categories"), doc => {
const docs: any = []
doc.forEach((d: any) => {
docs.push( { ...d.data(), id: d.id })
});
setCategories(docs)
})
} catch (err) {
console.error(err)
setCategories([])
}
}
قطعه کد بالا یک پارامتر به نام را می پذیرد setCategories
– حالت React که شامل همه دسته ها است. سپس درخواستی برای بازیابی لیست دسته ها به Firebase ارسال می کند و آن را به روز می کند setCategories
با داده ها بیان کنید.
مجموعه محصولات
پس از راهاندازی صفحه دستهها، باید به کاربران اجازه دهید تا محصولات را تحت هر دستهبندی موجود اضافه و حذف کنند.
ایجاد یک Products
صفحه مشابه تصویر بالا است و قطعه کد زیر را زمانی که کاربر محصول جدیدی اضافه می کند، اجرا کنید.
export const addProduct = async (name: string, price: number, category: string) => {
try {
await addDoc(collection(db, "products"), {
name, price, category
})
successMessage(`${name} product added! 🎉`)
}
catch (err) {
errorMessage("Error! ❌")
console.error(err)
}
}
قطعه کد بالا نام، قیمت و دسته بندی محصول را از فیلد فرم می پذیرد و به آن اضافه می کند. products
مجموعه.
برای نمایش محصولات در بارگذاری صفحه، این تابع را اجرا کنید.
export const getProducts = async (setProducts: any) => {
try {
const unsub = onSnapshot(collection(db, "products"), doc => {
const docs: any = []
doc.forEach((d: any) => {
docs.unshift( { ...d.data(), id: d.id })
});
setProducts(docs)
})
} catch (err) {
console.error(err)
setProducts([])
}
}
در نهایت، به کاربر اجازه دهید تا محصولات را از قسمت حذف کند products
مجموعه. بنابراین، زمانی که کاربر روی دکمه حذف کلیک می کند، عملکرد زیر را اجرا کنید.
export const deleteProduct = async (id: string, name:string) => {
try {
await deleteDoc(doc(db, "products", id));
successMessage(`${name} deleted 🎉`)
} catch (err) {
errorMessage("Encountered an error ❌")
console.log(err)
}
}
تابع نام و شناسه محصول را می پذیرد، سپس محصول را از طریق شناسه خود از مجموعه حذف می کند.
مجموعه فروش
در اینجا، باید عملکردهایی ایجاد کنید که کاربر را قادر میسازد تا فروش یک روز خاص و کل فروش انجام شده در پلتفرم را اضافه کند و دریافت کند.
export const addSales = async (customerName: string, customerEmail: string, products: Items[], totalAmount: number, setAddNew: any) => {
try {
await addDoc(collection(db, "sales"), {
customerName, customerEmail, products, totalAmount, timestamp: serverTimestamp()
})
successMessage("Sales recorded! 🎉")
setAddNew(false)
} catch (err) {
console.error(err)
errorMessage("Error! Try again ❌")
}
}
تابع زیر جزئیات مشتری و محصولات را می پذیرد، سپس آنها را به آن اضافه می کند sales
مجموعه.
برای دریافت تمام فروش، قطعه کد زیر را در بارگذاری صفحه اجرا کنید. پرس و جو می کند sales
جمع آوری و تمام داده ها را برمی گرداند.
export const getSales = async (setSales: any) => {
try {
const docRef = collection(db, "sales")
const q = query(docRef, orderBy("timestamp"))
onSnapshot(q, (snapshot) => {
const docs: any = []
snapshot.forEach((d: any) => {
docs.unshift( { ...d.data(), id: d.id })
});
setSales(docs)
})
} catch (err) {
console.error(err)
setSales([])
}
}
در صفحه داشبورد، یک کادر کل مبلغ حاصل از فروش را نشان می دهد. قطعه کد زیر کل مبلغ را برمی گرداند.
export const getTotalSales = async (setTotalSales: any) => {
try {
const unsub = onSnapshot(collection(db, "sales"), doc => {
let totalSales:number = 0
doc.forEach((d: any) => {
totalSales += d.data().totalAmount
});
setTotalSales(totalSales)
})
} catch (err) {
console.error(err)
}
}
در نهایت، در صفحه محصولات، ممکن است بخواهید فروش هایی را که فقط در یک روز خاص انجام شده است را نمایش دهید. قطعه کد زیر پرس و جو می کند sales
جمع آوری و بازگرداندن فروش انجام شده در یک روز خاص.
می توانید عملکرد را ویرایش کنید تا فروش هفتگی، ماهانه، سه ماهه یا سالانه را بازگردانید. فقط باید فرمت Date را با مدت زمان مناسب به روز کنید.
export const getSalesForDay = async (date: Date | null, setSales: any) => {
try {
const day = date?.getDate()
const month = date?.getMonth()
const year: number | undefined = date?.getFullYear()
if (day !== undefined && month !== undefined && year !== undefined) {
const startDate = new Date(year, month, day, 0, 0, 0);
const endDate = new Date(year, month, day, 23, 59, 59);
const docRef = collection(db, "sales")
const q = query(docRef, orderBy("timestamp"), where("timestamp", ">=", Timestamp.fromDate(startDate)), where("timestamp", "<=", Timestamp.fromDate(endDate)))
onSnapshot(q, (snapshot) => {
const docs: any = []
snapshot.forEach((d: any) => {
docs.unshift( { ...d.data(), id: d.id })
});
setSales(docs)
})
}
}
catch (err) {
console.error(err)
}
}
نتیجه
تبریک می گویم بابت ساختن آن تا اینجای کار! تو یاد گرفتی
- Firebase چیست،
- چگونه Firebase را به برنامه Next.js اضافه کنیم،
- نحوه کار با Firebase Auth و Firebase Firestore و
- نحوه ساخت اپلیکیشن مدیریت فروش
من یک نسخه زنده از برنامه ساخته ام، آن را بررسی کنید. کد منبع نیز در اینجا موجود است.
Firebase یک ابزار عالی است که تقریباً همه چیزهایی را که برای ساختن یک برنامه وب تمام پشته نیاز دارید را فراهم می کند. اگر می خواهید یک برنامه وب تمام پشته بدون هیچ گونه تجربه برنامه نویسی Backend ایجاد کنید، از Firebase استفاده کنید.
با تشکر از شما برای خواندن! 🎉
باز به کار🙂
آیا از این مقاله لذت بردید یا برای یک نقش از راه دور، تمام وقت یا مبتنی بر قرارداد به یک نویسنده فنی / React Developer با تجربه نیاز دارید؟ هر موقع خواستی با من تماس بگیر.
گیت هاب || لینکدین || توییتر