-
المساهمات
944 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
37
نوع المحتوى
ريادة الأعمال
البرمجة
التصميم
DevOps
التسويق والمبيعات
العمل الحر
البرامج والتطبيقات
آخر التحديثات
قصص نجاح
أسئلة وأجوبة
كتب
دورات
كل منشورات العضو Zen Eddin Allaham
-
عم سوي مقارنة بين Express & Nest. صار يجيني علامات استفهام. ليش Nest معقد هيك. import { Body, Controller, Get, Post, Req, Res } from '@nestjs/common'; import { AppService } from './app.service'; import type { Request , Response } from 'express'; export interface IUser { name: string; age: number; freamwork: string } @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get() getHello(): string { return this.appService.getHello(); } @Post('/nest') postHello(@Body('name') name:IUser, @Req() req:Request , @Res() res:Response) { return this.appService.getHelloWorld(name); } } import express from 'express'; const app = express(); app.use(express.json()); app.get('/', (req, res) => res.send('Hello')); app.post('/nest', (req, res) => { const name = req.body.name; res.send(`Hello ${name}`); }); app.listen(3000);
- 3 اجابة
-
- 2
-
-
انا قمت ب اضافة مشروع في مستقل هل اذا تركته اسبوع فقط بدون اي موافقة سيتم حذفه من طرف مستقل
- 2 اجابة
-
- 1
-
-
هل يمكنكم مساعدتي ب تحسين README بشكل احترافي https://github.com/ZenZN99/Movies-api # 🎬 Movies API ## 📝 About Movies API is a backend project developed using Node.js and Express.js to provide a professional system for managing and displaying movies. The project allows users to create accounts, log in, watch movies, and like or unlike them. It also provides admin-specific interfaces for managing movies, including creating new movies, updating, deleting, and uploading images via Cloudinary. The project uses MongoDB for data storage and JWT for user authentication and securing sensitive operations. It follows best programming practices to create a robust, secure, and user-friendly API. --- ## ⚡ How does the project work? ### 1. Register a new user: #### POST/api/auth/register This is a process that allows the user to create an account. You must enter all the required fields (username, email, password, confirmPassword). Make sure to add valid information such as a valid email address and a password that is at least 8 characters long and must match the confirmed password. ### Headers: Content-Type : application/json ### body: { "username": "your_name", "email": "youremail@gmail.com", "password": "12345678", "confirmPassword": "12345678" } ### response: { "success": "Account created successfully", "user": { "\_id": "user.\_id", "username": "yourname", "email": "youremail@gmail.com" }, "token": "<token>" } ### 2. Login: #### POST/api/auth/login After creating an account, you only need to enter an email address and password, and these must match the email address and password you used to create the account. ### Headers : Content-Type : application/json ### body : { "email": "youremail@gmail.com", "password": "12345678", } ### response: { "success": "Logged in successfully", "user": { "\_id": "user.\_id", "username": "yourname", "email": "youremail@gmail.com" }, "token": "<token>" } ### 3. Fetch user data : #### GET/api/auth/me Now you can see your data here, such as (username, email) ### Headers : Authorization : Bearer <your token> ## Movies Routes : ### 4. Get all the movies : #### GET/api/movie This route allows you to view all movies uploaded by the admin. If no movies exist, it will show 'No movies found yet' ### 5. Get movie by id : #### GET/api/movie/id This route allows you to view a single movie by its ID. If the movie does not exist, it will show 'Movie not found'. ### Headers : Authorization : Bearer <your token> ### 6. create movie : #### POST/api/movie This path allows you to upload a new movie, but only administrators can do so after registering with the administrator email address admin@admin.com and the password provided in the .env file ADMIN_PASSWORD. Placing the token inside the Header Authorization Bearer token will then allow you to create a movie. ### Headers : Authorization : Bearer <your token> ### body => form-data : title => TEXT MOVIE Name required content => TEXT MOVIE Content required image => FILE MOVIE Image required director => TEXT Director's Name required date => TEXT MOVIE Date required genre => TEXT MOVIE Genre required ### responsive : { "success": "Movie created successfully", "movie": { "title": "your title", "content": "your content", "image": "url cloudinary image", "director": "your director", "date": "your date", "genre": "your genre", "userId": "user.id", "likes": 0, "likedBy": [], "\_id": "movie id", "createdAt": "Creation time", "updatedAt": "Update time", "\_\_v": 0 } } ### 7. update movie : #### PUT/api/movie/id Here you will edit, and you must be an administrator to edit. You will enter all fields except for the image. ### Headers : Authorization : Bearer <your token> ### body : title , content, director, date , genre ### 8. delete movie : #### DELETE/api/movie/id Here you can delete, but you must be an administrator. ### Headers : Authorization : Bearer <your token> ### 9. GET movie admin : #### GET/api/movie/admin/movies ### Headers : Authorization : Bearer <your token> Here you will find all the movies uploaded by the administrator. ### 10. Like Movie : #### POST/api/movie/like/id Here you can like the app; if you don't like it, it will increase by one, otherwise it will decrease by one. It doesn't matter if you are a user or an administrator. ### Headers : Authorization : Bearer <your token> --- ## How to Run the Project ### 1. Clone the repository ```bash git clone https://github.com/ZenZN99/Movies-api.git cd backend npm install npm run start ```
- 3 اجابة
-
- 1
-
-
شكرا لكم لان صراحة مللت من فرونت اند😅 هل يمكنني عرض مشاريعي برمجية في Github README مع شرح
- 6 اجابة
-
- 1
-
-
بهي حالة اقدر اشتغل في شركات لان انا احببت باك اند بشكل كبير وفرنت اند اصبح ممل لان كله تصميم واحس انه ليس مجال برمجة
-
هلق انا بدي اركز على باك اند وانهي فرونت اند اذا فعلت ذالك كيف يمكنني عرض مشاريعي برمجية BackEnd APIs بدون FrontEnd
- 6 اجابة
-
- 2
-
-
هل في احتمال تنقرض لغة PHP لان لغة بطيئة جداً (Synchronous) وانا اشك ان JavaScript احتلت مكانها بشكل كامل وهي الاسرع لانها تدعم (Asynchronous)
- 5 اجابة
-
- 3
-
-
اريد شراء دورة لكن محتار بين دورتين دورة بايثون و دورة ذكاء اصطناعي
- 5 اجابة
-
- 1
-
-
بالنسبة ل php لا أحبها لأنها قديمة هل دورة بايثون ب تفيدني للعلم انا أصبحت مطور ويب كامل من خلال جافا سكريبت وانا لا اريد تعلم PHP Laravel لأنها ابطئ من Node.js ومشان هيك حاليا عم فكرة ب دورة بايثون فما رأيكم الان انا محتار بين دورة تطوير تطبيقات باستخدام لغة بايثون ولا دورة ذكاء الاصطناعي
- 5 اجابة
-
- 1
-
-
انا اكملت دورة جافا سكريبت واريد شراء دورة اخرى وانا مختص في تطوير ويب ماهي الدورة التي تنصحوني ب شرائها كي ادمجها مع مهاراتي في JavaScript
- 5 اجابة
-
- 1
-
-
انا قمت بطباعة شهادتي من اكاديمية حسوب لكن اريد اعرف شهادة في جهة خلفية لها تصميم ام بيضاء فارغة
- 2 اجابة
-
- 2
-
-
ماهو نوع الخط المستخدم في موقع اكاديمية حسوب
- 5 اجابة
-
- 5
-
-
- 2 اجابة
-
- 2
-
-
الحمدلله وبفضل الله تعالى حصلت على شهادة دورة تطوير تطبيقات باستخدام لغة جافا سكريبت كيف يمكنني العثور على عمل أو اول عميل بعد ما حصلت على شهادة
- 3 اجابة
-
- 2
-
-
هل تعلمي للغة Golang سوف تفيدني في مجتمع عربي
- 4 اجابة
-
- 1
-
-
ليش خادم ريندر توقف حيث عندما رفعته Netlify+ render اشتغل لكن بعد نصف ساعة توقف
- 2 اجابة
-
- 2
-
-
انا تعلمت Bun.js وتركت Node.js هل بهي حالة لح اخسر شغل في شركات او عمل حر
- 3 اجابة
-
- 3
-
-
حليت مشكلة المشكلة كانت غريبة هي بسبب GitHub حيث في مستودع قمت برفعه قبل رفع على ريندر وبذالك الاكواد في جيت هب كانت localhost
-
تمام حليت مشكلة
-
- 6 اجابة
-
- 1
-
-
انا انتهيت من مشروعي Fullstack بستخدام Bun.js Express react ورفعت مشروع على render واخدت رابط وحطيته ب fetch API وفي cors قبل رفع على ريندر انا حاطت رابط مشروع وMongoDB atlas IP عالمي ورفعت مشروع على نتليفاي بعد بنائه ولم يعمل خادم رابط خادم https://pinterest-clone-3ans.onrender.com رابط مشروع https://www-pinterest-clone.netlify.app/ import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import "./profile.css"; import { FaDeleteLeft, FaPenClip } from "react-icons/fa6"; import { useNavigate } from "react-router-dom"; interface Image { _id: string; title: string; description: string; imageUrl: string; } const Profile = () => { const [images, setImages] = useState<Image[]>([]); const [loading, setLoading] = useState(false); const [modalOpen, setModalOpen] = useState(false); const [editingImage, setEditingImage] = useState<Image | null>(null); const [newTitle, setNewTitle] = useState(""); const [newDescription, setNewDescription] = useState(""); const [newFile, setNewFile] = useState<File | null>(null); const navigate = useNavigate(); const token = localStorage.getItem("token"); useEffect(() => { const token = localStorage.getItem("token"); if (!token) { toast.error("You must log in first"); navigate("/login"); return; } }); const fetchImages = async () => { if (!token) return; setLoading(true); try { const res = await fetch("https://pinterest-clone-3ans.onrender.com/api/image/imageme", { credentials: "include", method: "GET", headers: { Authorization: `Bearer ${token}` }, }); const data = await res.json(); setImages(data); } catch (err) { console.error(err); toast.error("Failed to load images"); } finally { setLoading(false); } }; useEffect(() => { fetchImages(); }, []); const handleDelete = async (id: string) => { if (!token) return; try { const res = await fetch(`https://pinterest-clone-3ans.onrender.com/api/image/${id}`, { credentials: "include", method: "DELETE", headers: { Authorization: `Bearer ${token}` }, }); const data = await res.json(); if (res.ok) { toast.success(data.success); setImages(images.filter((img) => img._id !== id)); } else toast.error(data.error); } catch (err) { console.error(err); toast.error("Failed to delete image"); } }; const openEditModal = (img: Image) => { setEditingImage(img); setNewTitle(img.title); setNewDescription(img.description); setModalOpen(true); }; const handleUpdate = async () => { if (!token || !editingImage) return; try { const res = await fetch( `https://pinterest-clone-3ans.onrender.com/api/image/${editingImage._id}`, { credentials: "include", method: "PUT", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ title: newTitle, description: newDescription, }), } ); const data = await res.json(); if (res.ok) { toast.success(data.success); fetchImages(); setModalOpen(false); setNewTitle(""); setNewDescription(""); } else toast.error(data.error); } catch (err) { console.error(err); toast.error("Failed to update image"); } }; const handleUpload = async () => { if (!token || !newTitle || !newDescription || !newFile) { return toast.error("All fields are required for upload"); } if (newDescription.length > 60) { return toast.error("Maximum description: 60 characters"); } const formData = new FormData(); formData.append("title", newTitle); formData.append("description", newDescription); formData.append("image", newFile); try { const res = await fetch("https://pinterest-clone-3ans.onrender.com/api/image/upload", { credentials: "include", method: "POST", headers: { Authorization: `Bearer ${token}` }, body: formData, }); const data = await res.json(); if (res.ok) { toast.success(data.success); fetchImages(); setNewTitle(""); setNewDescription(""); setNewFile(null); } else toast.error(data.error); } catch (err) { console.error(err); toast.error("Failed to upload image"); } }; return ( <div className="profile-page"> <h2>Your Images</h2> <div className="upload-section"> <input type="text" placeholder="Title" value={newTitle} onChange={(e) => setNewTitle(e.target.value)} /> <input type="text" placeholder="Description" value={newDescription} onChange={(e) => setNewDescription(e.target.value)} /> <input type="file" onChange={(e) => setNewFile(e.target.files?.[0] || null)} /> <button onClick={handleUpload}>Upload Image</button> </div> {loading && <p className="no-images">Loading...</p>} {images.length === 0 && !loading && ( <p className="no-images">No images uploaded yet.</p> )} <div className="image-grid"> {images.map((img) => ( <div key={img._id} className="image-card"> <img src={img.imageUrl} alt={img.title} /> <h3>{img.title}</h3> <p>{img.description}</p> <div className="image-actions"> <button onClick={() => openEditModal(img)}> <FaPenClip /> Edit </button> <button onClick={() => handleDelete(img._id)}> <FaDeleteLeft /> Delete </button> </div> </div> ))} </div> {modalOpen && editingImage && ( <div className="modal"> <div className="modal-content"> <h3>Edit Image</h3> <input type="text" value={newTitle} onChange={(e) => setNewTitle(e.target.value)} /> <input type="text" value={newDescription} onChange={(e) => setNewDescription(e.target.value)} /> <div className="modal-actions"> <button onClick={handleUpdate}>Save</button> <button onClick={() => setModalOpen(false)}>Cancel</button> </div> </div> </div> )} </div> ); }; export default Profile; import express from 'express'; import dotenv from 'dotenv'; import cors from 'cors'; import { connectDB } from './utils/db'; import userRouter from './routes/user.routes'; import imageRouter from './routes/image.routes'; dotenv.config(); const app = express(); const port = process.env.PORT || 3000; connectDB(); app.use(cors({ origin: 'https://www-pinterest-clone.netlify.app', credentials: true, })); app.use(express.json()); app.get('/', (req, res) => { res.send('Hello Bun!'); }); app.use('/api/auth', userRouter); app.use('/api/image', imageRouter); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
- 6 اجابة
-
- 1
-
-
هي ب نسبة ل رابط ريندر لكنه لا يعمل مع مشروعي https://www-movies-app.netlify.app/ هاد رابط مستودع https://github.com/ZenZN99/Movies-App import React, { useEffect, useState } from "react"; import "./register.css"; import toast from "react-hot-toast"; import { useNavigate } from "react-router-dom"; import AOS from "aos"; import "aos/dist/aos.css"; const Register = () => { const [form, setForm] = useState({ username: "", email: "", password: "", }); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const navigate = useNavigate(); const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { setForm({ ...form, [e.target.name]: e.target.value }); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); setError(""); try { const res = await fetch("https://movies-app-2-19xd.onrender.com/api/auth/register", { method: "post", headers: { "Content-Type": "application/json", }, body: JSON.stringify(form), }); const data = await res.json(); if (!res.ok) { setError(data.error || "Something went wrong!"); } else { localStorage.setItem("token", data.token); localStorage.setItem("username", data.user.username); toast.success(`Welcome ${data.user.username}`); setForm({ username: "", email: "", password: "" }); navigate("/"); } } catch (error) { console.log(error); setError("Network error. Please try again later."); } finally { setLoading(false); } }; useEffect(() => { if (error) { const timer = setTimeout(() => { setError(""); }, 5000); return () => clearTimeout(timer); } }, [error]); useEffect(() => { const token = localStorage.getItem("token"); if (token) { navigate("/"); toast("You are logged in with action", {duration:3000}); return; } }, []); useEffect(() => { AOS.init({ duration: 2000 }); }, []); return ( <div className="register-container" data-aos="fade-up"> <div className="register-wrapper"> <div className="register-card"> <h1 className="register-title">Create Account</h1> <p className="register-subtitle">Join our community today</p> <form onSubmit={handleSubmit} className="register-form"> {error && <p className="error-message">{error}</p>} <input type="text" name="username" placeholder="Username" value={form.username} onChange={handleChange} required /> <input type="email" name="email" placeholder="Email Address" value={form.email} onChange={handleChange} required /> <input type="password" name="password" placeholder="Password" value={form.password} onChange={handleChange} required /> <button type="submit" className="register-btn"> {loading ? "Creating an account..." : "Register"} </button> </form> <p className="register-footer"> Already have an account? <a href="/login">Login</a> </p> </div> </div> </div> ); }; export default Register; import express from "express"; import dotenv from "dotenv"; import userRouter from "./routes/user.route"; import cors from "cors"; dotenv.config(); const app = express(); const port = process.env.PORT || 3000; app.use( cors({ origin: "https://www-movies-app.netlify.app", credentials: true, }) ); app.use(express.json()); app.use("/api/auth", userRouter); app.get("/", (req, res) => { res.send("Hello Bun!"); }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
-
log في ريندر مافيه اي مشاكل ورابط شغال لكن عند استخدامه في fetch لا يعمل وحتى مع app.use(cors());
