لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 07/03/25 في كل الموقع
-
2 نقاط
-
ماهي المشاريع الاحترافية التي يتم بنائها بستخدام رياكت1 نقطة
-
السلام عليكم, هل هذا مايسمى ب Mad libs Genartor من فضلكم؟ بحثت عن كيف اجعل الضمائر تتغير من المونث الى المدكر- حسب النوع الذي يدخله المستخدم - لكن لم افلح... هل هناك حيلة برمجية لذلك من فضلكم؟ name=input('enter your name:') gender=input('enter your gender:') age=int(input('enter your age:')) favorit_food=input('enter your favorit food:') country=input('enter your country:') country_dream=input('enter wich country you wih you could live:') siblings=input('enter the numer of your siblings:') hobies=input('entre your hobies:') print(f'once upon a time a {gender} whose name is {name}. this {gender} was{age} year old. his favorit food is {favorit_food}. he live in {country} buthe dreams to leave his country and settle in {country_dream}.he had {siblings} siblings. he loves doing in his free time {hobies} .')1 نقطة
-
السلام عليكم ورحمة الله وبركاته اخوك جديد ف اكاديمه وحاب ابداء اي مسار ابداء بيه ارجو نصيحه1 نقطة
-
الاستاذ في كل الدروس يكون محضر نفس الى المشروع او الكود الزي سيكتبه و في الدرس يشرحه و يكتب الكود ولاكن انا في الوضع الحالي وفي المشاريع كيف اعلم ما هي الطريقة التي يجب ان اعمل بها كم من مشروع بداته و ثم بعد ان وصلت للمنتصف وصلت الى طريق مسدود نوعا ما بسبب بداية خطء و لهذا السبب قد اتطر الى العودة الى المشروع من الصفر و هذا ما يجعلني اترك جزء من مشاريعي غير مكتملة فما الحل كيف احضر للمكاتب اللازمة في المشروت كلها و كيف ابني المشروع بشكل متكامل و بخطوات صحيحة1 نقطة
-
1 نقطة
-
1 نقطة
-
توجد مشكلة غريبة في المشروع حيث انا متاكد اني قمت باستيراد العناصر في ملف App لكن لا يتم عرض شيء في المتصفح اي يعني ان تنسيقات css يتم عرضها لكن Html لا يتم عرض اي شيء منها test.zip1 نقطة
-
1 نقطة
-
وعليكم السلام ورحمة الله وبركاته. نعم صحيح ما تقوم بإنشائه يشبه إلى حد ما لعبة "Mad Libs Generator" حيث يتم إنشاء قصة باستخدام مدخلات المستخدم لملء الفراغات في القصة لديك. الأمر أسهل بكثير بالنسبة للغة الإنجليزية أما مثلا في اللغة العربية الأمر صعب وعقد حيث يتم تغير الضماء والأفعال وحتى الصفات لتناسب جنس البيانات المدخلة . أما في الإنجليزية فيمكننا إنشاء متغيرات بناء على الجنس المدخل هكذا مثلا : if gender == 'male': pronoun = 'he' possessive = 'his' elif gender == 'female': pronoun = 'she' possessive = 'her' else: pronoun = 'they' # للتعامل مع حالات الإدخال الخاطئة أو غير المحددة possessive = 'their' ويمكنك إستخدام تلك الضمائر بداخل الجملة هكذا مثلا : name = input('Enter your name: ') gender = input('Enter your gender (male/female): ').lower() age = int(input('Enter your age: ')) favorite_food = input('Enter your favorite food: ') country = input('Enter your country: ') country_dream = input('Enter which country you wish you could live in: ') siblings = input('Enter the number of your siblings: ') hobbies = input('Enter your hobbies: ') if gender == 'male': pronoun = 'he' possessive = 'his' elif gender == 'female': pronoun = 'she' possessive = 'her' else: pronoun = 'they' possessive = 'their' print(f'Once upon a time, there was a person named {name}. This {gender} was {age} years old. ' f'{pronoun.capitalize()} loved eating {favorite_food}. {pronoun.capitalize()} lived in {country} ' f'but dreamed of settling in {country_dream}. {pronoun.capitalize()} had {siblings} siblings ' f'and enjoyed {hobbies} in {possessive} free time.')1 نقطة
-
مزااال لم اشترك في اي دورة ناا اسال اي دوره ابدا بيها1 نقطة
-
1 نقطة
-
هذا لأنك في الصنف في سطر 26 قمت بتعريف فقط طريقة post أى يجب أن يتم إرسال الطلب من خلال نوع post من نموذج form . ولكن لو أردت أن تجعل الطلب get أى يمكنك الوصول إليه من خلال كتابته في المتصفح يجب تغير post إلى get . أو أن تقوم بتعريف دالة get بداخل الصنف وتعيد ما تريد إعادته عند الذهاب إلى العنوان /1 نقطة
-
وعليكم السلام ورحمة الله وبركاته. هل تقصد أنك قمت بالإشتراك في دورة هنا في الأكاديمية ؟ إذا كان كذلك هل يمكنك توضيح أى دورة إشتركت بها لمساعدتك.1 نقطة
-
هل تقوم بالذهاب إلى مسار الرئيسية / ويظهر لك 404 أم تذهب إلى عنوان أخر ؟ أولا غالبا المشكلة بسبب أنك قمت بتعريف app مرتين مرة في سطر 8 ومرة أخرى في سطر 23 . app = Flask(__name__) حيث بسبب هذا بعد أن قمت بكتابة المسار في سطر 10 من خلال app تم إعادة تعينه . لذلك يجب خذف هذا السطر 23 . وأيضا في نهاية الملف لم تستدعي app.run() يجب أن تستديعها هكذا : if __name__ == '__main__': app.run()1 نقطة
-
1 نقطة
-
إن خاصية aspect-ratio في CSS تستخدم لتحديد نسبة العرض إلى الارتفاع لعنصر ما وهو ما يساعد في الحفاظ على أبعاده بشكل متناسق عند تغيير حجم الشاشة أو عندما لا يتم تحديد العرض والارتفاع صراحة. فمثلا في الصور هناك الصورة 3:4 هنا يعني أى العرض هو 3 والطول هو 4 . أى أن الطول سيكون أكبر من العرض .فمثلا أنت لا تعرف ما هو قيمة الطول والعرض الأصلية للصورة أو للعنصر . ولكنك تخبر css أن تحافظ على تلك النسبة أى أن قسمة العرض على الطول يجب أن تكون 3:4 . img { aspect-ratio: 1 / 1; width: 100px; object-fit: cover; } فمثلا في المثال السابق نحن وضعنا النسبة 1 إلى 1 أى أننا نريد صورة الطول والعرض الخاص بها متساويين أى نريد صورة مربعة. وهكذا يمكنك وضع النسبة بناء على ما تريده فلو أردت الطول أكبر من العرض تعطي نسبة أكبر للطول وهكذا فأنت لست مجبرا على معرفة قيمة ال px للصورة .1 نقطة
-
السلام عليكم هل من الممكن شرح فكرة time series في تعلم الآلة لأنه يعتبر مهم جدًا فالكثير من الشركات ولم أجد شرح عنه في دورة الذكاء الاصطناعي1 نقطة
-
هل يمكنكم انشاء لي router من اجل معرفة كيف يتم انشائه لاني حاولت كثيراً ونتيجة هي الفشل في ذلك ارفقت لكم المشروع اريد ملف شريط تنقل يعرض في جميع الصفحات وعند تغيير اي صفحة تتغير المكونات ايضا ملاحظة: تم تنزيل مكتبة راوتر Iphone 15 pro.zip1 نقطة
-
ستحتاج إلى تحديث نماذج المشروع وتحديد العلاقات المناسبة حيث كل بطاقة مرتبطة بحدث واحد، وكل بطاقة يمكن أن تكون مرتبطة بزائر واحد وكل زائر مرتبط بحدث. ثم عليك إنشاء حدث جديد وبطاقةوحدد عدد الدعوات، ثم إنشاء زوار بعدد الدعوات، واربطهم بالحدث، ثم بطاقة لكل زائر واربطها بالحدث والزائر. بعد ذلك أنشئ رابط فريد لكل زائر وأرسله له، وعند دخول الزائر للرابط، تحقق من الحدث والبطاقة الخاصة به. وذلك حتى يتمكن المشرف من تسجيل الدخول من /admin/login للقيام بالتالي: ينشئ حدث جديد يسجل دخول للحدث ينشئ بطاقة ويحدد عدد الدعوات يعرض الدعوات وينسخ الروابط أو يرسلها بالبريد الزوار يستخدمون الروابط للتسجيل يحصلون على بطاقة PDF مع QR code عند الحضور، يتم مسح QR code لتأكيد الحضور أي عليك تحديث models.py إلى: from flask_sqlalchemy import SQLAlchemy from datetime import datetime import secrets db = SQLAlchemy() class Admin(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) email = db.Column(db.String(100), unique=True, nullable=False) password = db.Column(db.String(200), nullable=False) class EVENT(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) email = db.Column(db.String(100), nullable=False) password = db.Column(db.String(100), nullable=False) event_time = db.Column(db.DateTime, nullable=False) cards = db.relationship('CARD', backref='event', lazy=True) invitations = db.relationship('Invitation', backref='event', lazy=True) class CARD(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) image_filename = db.Column(db.String(100)) message = db.Column(db.Text) card_no = db.Column(db.Integer, nullable=False) # عدد الدعوات event_time = db.Column(db.DateTime) created_at = db.Column(db.DateTime, default=datetime.utcnow) event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False) invitations = db.relationship('Invitation', backref='card', lazy=True) class Invitation(db.Model): id = db.Column(db.Integer, primary_key=True) unique_token = db.Column(db.String(100), unique=True, nullable=False) is_used = db.Column(db.Boolean, default=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False) card_id = db.Column(db.Integer, db.ForeignKey('card.id'), nullable=False) visitor_id = db.Column(db.Integer, db.ForeignKey('visitor.id')) class Visitor(db.Model): id = db.Column(db.Integer, primary_key=True) full_name = db.Column(db.String(100), nullable=False) email = db.Column(db.String(100), nullable=False) phone = db.Column(db.String(14)) image_filename = db.Column(db.String(100)) qr_filename = db.Column(db.String(100)) qr_token = db.Column(db.String(100), unique=True) created_at = db.Column(db.DateTime, default=datetime.utcnow) confirmed = db.Column(db.Boolean, default=False) attended = db.Column(db.Boolean, default=False) invitation = db.relationship('Invitation', backref='visitor', uselist=False) وتحديث ملف card.py لإضافة وظيفة إنشاء الروابط: from flask import ( session, Blueprint, flash, redirect, url_for, render_template, request, current_app, ) from helper import login_required_event from datetime import datetime import os import secrets from models import * bp = Blueprint("card", __name__, url_prefix="/event") @bp.route("/dashboard") @login_required_event def event_dashboard(): if "event_id" not in session: flash("يجب تسجيل الدخول أولاً", "warning") return redirect(url_for("auth.login")) event_id = session["event_id"] event = EVENT.query.get(event_id) cards = CARD.query.filter_by(event_id=event_id).all() return render_template("card/dashboard.html", event=event, cards=cards) @bp.route("/card_maker", methods=["POST", "GET"]) @login_required_event def card_maker(): if request.method == "POST": name = request.form["event_name"] message = request.form["message"] card_no = int(request.form["card_no"]) event_time = request.form["event_time"] photo = request.files["photo"] try: event_time = datetime.strptime(event_time, "%Y-%m-%d") except ValueError: flash("صيغة التاريخ غير صحيحة", "danger") return redirect(url_for("card.card_maker")) photo_filename = f"{datetime.now().timestamp()}_{photo.filename}" photo_filepath = os.path.join( current_app.config["UPLOAD_FOLDER"], photo_filename ) photo.save(photo_filepath) event_id = session["event_id"] card = CARD( name=name, image_filename=photo_filename, message=message, card_no=card_no, event_time=event_time, event_id=event_id ) db.session.add(card) db.session.commit() for i in range(card_no): invitation = Invitation( unique_token=secrets.token_urlsafe(32), event_id=event_id, card_id=card.id ) db.session.add(invitation) db.session.commit() flash(f"تم إنشاء البطاقة و {card_no} دعوة بنجاح!", "success") return redirect(url_for("card.card_show")) return render_template("card/card_maker.html") @bp.route("/card-show") @login_required_event def card_show(): event_id = session["event_id"] cards = CARD.query.filter_by(event_id=event_id).all() return render_template("card/card_show.html", cards=cards) @bp.route("/invitations/<int:card_id>") @login_required_event def show_invitations(card_id): card = CARD.query.get_or_404(card_id) if card.event_id != session["event_id"]: flash("ليس لديك صلاحية لعرض هذه الدعوات", "danger") return redirect(url_for("card.event_dashboard")) invitations = Invitation.query.filter_by(card_id=card_id).all() return render_template("card/invitations.html", card=card, invitations=invitations) @bp.route("/visitor-info") @login_required_event def visitor_info(): event_id = session["event_id"] visitors = db.session.query(Visitor).join( Invitation ).filter( Invitation.event_id == event_id, Invitation.visitor_id.isnot(None) ).all() return render_template("card/visitor_info.html", visitors=visitors) @bp.route("/qr-scanning") @login_required_event def qr_scanning(): return render_template("card/scanner.html") وتحديث ملف visitor.py لاستقبال الدعوات: from flask import ( Blueprint, redirect, url_for, render_template, request, flash, current_app, ) import os, qrcode, secrets from weasyprint import HTML from flask_mail import Mail, Message from models import * from datetime import datetime bp = Blueprint("visitor", __name__, url_prefix="/visitor") mail = Mail() @bp.route("/register/<token>", methods=["GET", "POST"]) def register(token): invitation = Invitation.query.filter_by(unique_token=token).first() if not invitation: flash("رابط الدعوة غير صالح", "danger") return redirect(url_for("index")) if invitation.is_used: flash("هذه الدعوة تم استخدامها مسبقاً", "warning") return redirect(url_for("index")) card = invitation.card event = invitation.event if request.method == "POST": full_name = request.form["full_name"] email = request.form["email"] phone = request.form["phone"] photo = request.files["photo"] visitor = Visitor( full_name=full_name, email=email, phone=phone ) if photo and photo.filename: photo_filename = f"{datetime.now().timestamp()}_{photo.filename}" photo_filepath = os.path.join( current_app.config["UPLOAD_FOLDER"], photo_filename ) photo.save(photo_filepath) visitor.image_filename = photo_filename qr_token = secrets.token_urlsafe(16) visitor.qr_token = qr_token db.session.add(visitor) db.session.commit() invitation.visitor_id = visitor.id invitation.is_used = True db.session.commit() confirm_url = url_for("visitor.confirm_attendance", token=qr_token, _external=True) qr_img = qrcode.make(confirm_url) qr_filename = f"qr_{visitor.id}.png" qr_path = os.path.join(current_app.config["UPLOAD_FOLDER"], qr_filename) qr_img.save(qr_path) visitor.qr_filename = qr_filename db.session.commit() pdf_path = generate_pdf(visitor, event, card, confirm_url) send_visitor_email(visitor, event, pdf_path) flash("تم التسجيل بنجاح! تحقق من بريدك الإلكتروني", "success") return redirect(url_for("index")) return render_template("visitor/register.html", event=event, card=card) @bp.route("/confirm_attendance/<token>") def confirm_attendance(token): visitor = Visitor.query.filter_by(qr_token=token).first() if visitor: visitor.attended = True db.session.commit() invitation = visitor.invitation event = invitation.event if invitation else None return render_template("visitor/confirmed.html", visitor=visitor, event=event) else: return "رمز غير صالح", 404 def generate_pdf(visitor, event, card, confirm_url): pdf_filename = f"invitation_{visitor.id}.pdf" pdf_path = os.path.join(current_app.config["UPLOAD_FOLDER"], pdf_filename) image_url = url_for( "static", filename=f"uploads/{visitor.image_filename}", _external=True ) if visitor.image_filename else None qr_url = url_for( "static", filename=f"uploads/{visitor.qr_filename}", _external=True ) if visitor.qr_filename else None card_image_url = url_for( "static", filename=f"uploads/{card.image_filename}", _external=True ) if card.image_filename else None html = render_template( "visitor/invitation_pdf.html", visitor=visitor, event=event, card=card, visitor_image=image_url, qr_image=qr_url, card_image=card_image_url, confirm_url=confirm_url ) base_url = request.host_url HTML(string=html, base_url=base_url).write_pdf(pdf_path) return pdf_path def send_visitor_email(visitor, event, pdf_path): msg = Message( f"دعوتك لحضور {event.name}", sender=current_app.config["MAIL_USERNAME"], recipients=[visitor.email] ) msg.body = f""" مرحباً {visitor.full_name}, يسعدنا دعوتك لحضور {event.name} في تاريخ {event.event_time.strftime('%Y-%m-%d')}. تجد بطاقة الدعوة مرفقة مع هذا البريد. مع أطيب التحيات """ with current_app.open_resource(pdf_path) as pdf: msg.attach(f"invitation_{visitor.id}.pdf", "application/pdf", pdf.read()) mail.send(msg) ثم إنشاء القوالب الجديدة templates/card/invitations.html {% extends "base.html" %} {% block title %}دعوات البطاقة{% endblock %} {% block content %} <div class="container mt-4"> <h2>دعوات البطاقة: {{ card.name }}</h2> <p>عدد الدعوات: {{ card.card_no }}</p> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>#</th> <th>رابط الدعوة</th> <th>الحالة</th> <th>الزائر</th> <th>الإجراءات</th> </tr> </thead> <tbody> {% for invitation in invitations %} <tr> <td>{{ loop.index }}</td> <td> <input type="text" class="form-control form-control-sm" value="{{ url_for('visitor.register', token=invitation.unique_token, _external=True) }}" readonly> </td> <td> {% if invitation.is_used %} <span class="badge bg-success">مستخدمة</span> {% else %} <span class="badge bg-warning">غير مستخدمة</span> {% endif %} </td> <td> {% if invitation.visitor %} {{ invitation.visitor.full_name }} {% else %} - {% endif %} </td> <td> <button class="btn btn-sm btn-primary copy-btn" data-url="{{ url_for('visitor.register', token=invitation.unique_token, _external=True) }}"> نسخ الرابط </button> </td> </tr> {% endfor %} </tbody> </table> </div> <a href="{{ url_for('card.card_show') }}" class="btn btn-secondary">العودة</a> </div> <script> document.querySelectorAll('.copy-btn').forEach(btn => { btn.addEventListener('click', function() { const url = this.getAttribute('data-url'); navigator.clipboard.writeText(url).then(() => { this.textContent = 'تم النسخ!'; setTimeout(() => { this.textContent = 'نسخ الرابط'; }, 2000); }); }); }); </script> {% endblock %} و templates/visitor/register.html {% extends "base.html" %} {% block title %}التسجيل في الحدث{% endblock %} {% block content %} <div class="container mt-4"> <div class="row justify-content-center"> <div class="col-md-6"> <div class="card"> <div class="card-header bg-primary text-white"> <h4>التسجيل في {{ event.name }}</h4> </div> <div class="card-body"> <div class="text-center mb-4"> {% if card.image_filename %} <img src="{{ url_for('static', filename='uploads/' + card.image_filename) }}" alt="شعار الحدث" class="img-fluid" style="max-height: 200px;"> {% endif %} <h5 class="mt-3">{{ card.name }}</h5> <p>{{ card.message }}</p> <p><strong>التاريخ:</strong> {{ event.event_time.strftime('%Y-%m-%d') }}</p> </div> <form method="post" enctype="multipart/form-data"> <div class="mb-3"> <label for="full_name" class="form-label">الاسم الكامل</label> <input type="text" class="form-control" id="full_name" name="full_name" required> </div> <div class="mb-3"> <label for="email" class="form-label">البريد الإلكتروني</label> <input type="email" class="form-control" id="email" name="email" required> </div> <div class="mb-3"> <label for="phone" class="form-label">رقم الهاتف</label> <input type="tel" class="form-control" id="phone" name="phone" required> </div> <div class="mb-3"> <label for="photo" class="form-label">صورة شخصية (اختياري)</label> <input type="file" class="form-control" id="photo" name="photo" accept="image/*"> </div> <button type="submit" class="btn btn-primary w-100">تأكيد التسجيل</button> </form> </div> </div> </div> </div> </div> {% endblock %} و templates/visitor/invitation_pdf.html <!DOCTYPE html> <html lang="ar" dir="rtl"> <head> <meta charset="UTF-8"> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 20px; text-align: center; background-color: #f5f5f5; } .invitation-card { background: white; border: 2px solid #gold; border-radius: 10px; padding: 30px; max-width: 600px; margin: 0 auto; box-shadow: 0 4px 6px rgba(0,0,0,0.1); } .header img { max-width: 150px; margin-bottom: 20px; } .event-name { font-size: 28px; color: #333; margin: 20px 0; } .message { font-size: 18px; color: #666; margin: 20px 0; line-height: 1.6; } .visitor-info { background: #f9f9f9; padding: 15px; border-radius: 5px; margin: 20px 0; text-align: right; } .qr-code { margin: 30px 0; } .qr-code img { width: 200px; height: 200px; } .instructions { text-align: right; margin-top: 30px; padding: 20px; background: #f0f0f0; border-radius: 5px; } .instructions h4 { color: #333; margin-bottom: 15px; } .instructions ol { text-align: right; padding-right: 20px; } .footer { margin-top: 30px; color: #888; font-size: 14px; } </style> </head> <body> <div class="invitation-card"> <div class="header"> {% if card_image %} <img src="{{ card_image }}" alt="شعار الحدث"> {% endif %} </div> <h1 class="event-name">{{ event.name }}</h1> <div class="message"> {{ card.message }} </div> <div class="visitor-info"> <h3>بيانات الضيف</h3> <p><strong>الاسم:</strong> {{ visitor.full_name }}</p> <p><strong>البريد الإلكتروني:</strong> {{ visitor.email }}</p> <p><strong>رقم الهاتف:</strong> {{ visitor.phone }}</p> <p><strong>تاريخ الحدث:</strong> {{ event.event_time.strftime('%Y-%m-%d %H:%M') }}</p> </div> <div class="qr-code"> <h3>رمز الدخول QR</h3> {% if qr_image %} <img src="{{ qr_image }}" alt="QR Code"> {% endif %} <p>يُرجى إبراز هذا الرمز عند الدخول</p> </div> <div class="instructions"> <h4>تعليمات مهمة:</h4> <ol> <li>يُرجى الحضور قبل الموعد بـ 15 دقيقة</li> <li>هذه الدعوة شخصية ولا يمكن تحويلها</li> <li>يُرجى إحضار هذه البطاقة أو إظهارها على الهاتف</li> <li>الدعوة صالحة لشخص واحد فقط</li> </ol> </div> <div class="footer"> <p>نتطلع لرؤيتكم في الحدث</p> <p>{{ event.name }} © 2025</p> </div> </div> </body> </html> بعد ذلك تحديث templates/card/card_show.html {% extends "base.html" %} {% block title %}عرض البطاقات{% endblock %} {% block content %} <div class="container mt-4"> <h2>البطاقات المُنشأة</h2> <div class="row"> {% for card in cards %} <div class="col-md-4 mb-4"> <div class="card"> {% if card.image_filename %} <img src="{{ url_for('static', filename='uploads/' + card.image_filename) }}" class="card-img-top" alt="صورة البطاقة" style="height: 200px; object-fit: cover;"> {% endif %} <div class="card-body"> <h5 class="card-title">{{ card.name }}</h5> <p class="card-text">{{ card.message[:100] }}...</p> وتحديث templates/card/card_show.html {% extends "base.html" %} {% block title %}عرض البطاقات{% endblock %} {% block content %} <div class="container mt-4"> <h2>البطاقات المُنشأة</h2> <div class="row"> {% for card in cards %} <div class="col-md-4 mb-4"> <div class="card"> {% if card.image_filename %} <img src="{{ url_for('static', filename='uploads/' + card.image_filename) }}" class="card-img-top" alt="صورة البطاقة" style="height: 200px; object-fit: cover;"> {% endif %} <div class="card-body"> <h5 class="card-title">{{ card.name }}</h5> <p class="card-text">{{ card.message[:100] }}...</p> <ul class="list-unstyled"> <li><strong>عدد الدعوات:</strong> {{ card.card_no }}</li> <li><strong>التاريخ:</strong> {{ card.event_time.strftime('%Y-%m-%d') }}</li> <li><strong>الدعوات المستخدمة:</strong> {{ card.invitations|selectattr('is_used')|list|length }} من {{ card.card_no }} </li> </ul> <a href="{{ url_for('card.show_invitations', card_id=card.id) }}" class="btn btn-primary">عرض الدعوات</a> </div> </div> </div> {% endfor %} </div> <a href="{{ url_for('card.event_dashboard') }}" class="btn btn-secondary">العودة للوحة التحكم</a> </div> {% endblock %} كذلك تحديث templates/card/visitor_info.html {% extends "base.html" %} {% block title %}معلومات الزوار{% endblock %} {% block content %} <div class="container mt-4"> <h2>الزوار المسجلين</h2> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>الصورة</th> <th>الاسم</th> <th>البريد الإلكتروني</th> <th>الهاتف</th> <th>تاريخ التسجيل</th> <th>الحالة</th> <th>الحضور</th> </tr> </thead> <tbody> {% for visitor in visitors %} <tr> <td> {% if visitor.image_filename %} <img src="{{ url_for('static', filename='uploads/' + visitor.image_filename) }}" alt="صورة الزائر" style="width: 50px; height: 50px; object-fit: cover; border-radius: 50%;"> {% else %} <span class="text-muted">لا توجد صورة</span> {% endif %} </td> <td>{{ visitor.full_name }}</td> <td>{{ visitor.email }}</td> <td>{{ visitor.phone }}</td> <td>{{ visitor.created_at.strftime('%Y-%m-%d %H:%M') }}</td> <td> {% if visitor.confirmed %} <span class="badge bg-success">مؤكد</span> {% else %} <span class="badge bg-warning">غير مؤكد</span> {% endif %} </td> <td> {% if visitor.attended %} <span class="badge bg-success">حضر</span> {% else %} <span class="badge bg-secondary">لم يحضر</span> {% endif %} </td> </tr> {% endfor %} </tbody> </table> </div> {% if not visitors %} <p class="text-center text-muted mt-4">لا يوجد زوار مسجلين حتى الآن</p> {% endif %} <a href="{{ url_for('card.event_dashboard') }}" class="btn btn-secondary mt-3">العودة للوحة التحكم</a> </div> {% endblock %} وتحديث templates/card/dashboard.html {% extends "base.html" %} {% block title %}لوحة التحكم{% endblock %} {% block content %} <div class="container mt-4"> <h1>لوحة تحكم الحدث: {{ event.name }}</h1> <div class="row mt-4"> <div class="col-md-3"> <div class="card text-center"> <div class="card-body"> <h5 class="card-title">البطاقات</h5> <p class="card-text display-4">{{ cards|length }}</p> <a href="{{ url_for('card.card_maker') }}" class="btn btn-primary">إنشاء بطاقة</a> </div> </div> </div> <div class="col-md-3"> <div class="card text-center"> <div class="card-body"> <h5 class="card-title">إجمالي الدعوات</h5> <p class="card-text display-4">{{ cards|sum(attribute='card_no') }}</p> <a href="{{ url_for('card.card_show') }}" class="btn btn-info">عرض البطاقات</a> </div> </div> </div> <div class="col-md-3"> <div class="card text-center"> <div class="card-body"> <h5 class="card-title">الزوار المسجلين</h5> <p class="card-text display-4">{{ event.visitors|length }}</p> <a href="{{ url_for('card.visitor_info') }}" class="btn btn-success">معلومات الزوار</a> </div> </div> </div> <div class="col-md-3"> <div class="card text-center"> <div class="card-body"> <h5 class="card-title">ماسح QR</h5> <i class="fas fa-qrcode display-4"></i> <br><br> <a href="{{ url_for('card.qr_scanning') }}" class="btn btn-warning">فتح الماسح</a> </div> </div> </div> </div> <div class="mt-4"> <h3>معلومات الحدث</h3> <ul class="list-group"> <li class="list-group-item"><strong>اسم الحدث:</strong> {{ event.name }}</li> <li class="list-group-item"><strong>البريد الإلكتروني:</strong> {{ event.email }}</li> <li class="list-group-item"><strong>تاريخ الحدث:</strong> {{ event.event_time.strftime('%Y-%m-%d') }}</li> </ul> </div> <div class="mt-4"> <a href="{{ url_for('auth.logout') }}" class="btn btn-danger">تسجيل الخروج</a> </div> </div> {% endblock %} وستحتاج إلى تحديث helper.py لإضافة دالة مساعدة from models import * from flask import redirect, url_for, g, current_app, session import functools, os def login_required_event(func): @functools.wraps(func) def decorator_func(*args, **kwargs): if 'event_id' not in session: return redirect(url_for("auth.login")) # تحميل بيانات الحدث g.event = EVENT.query.get(session['event_id']) if g.event is None: session.clear() return redirect(url_for("auth.login")) return func(*args, **kwargs) return decorator_func def login_required_admin(view): @functools.wraps(view) def wrapped_view(**kwargs): if g.admin is None: return redirect(url_for("admin_login")) return view(**kwargs) return wrapped_view وإضافة مسار API لإرسال الدعوات في card.py @bp.route("/send_invitations/<int:card_id>", methods=["POST"]) @login_required_event def send_invitations(card_id): card = CARD.query.get_or_404(card_id) if card.event_id != session["event_id"]: return {"error": "غير مصرح"}, 403 emails = request.json.get("emails", []) invitations = Invitation.query.filter_by( card_id=card_id, is_used=False ).limit(len(emails)).all() if len(invitations) < len(emails): return {"error": "عدد الإيميلات أكبر من الدعوات المتاحة"}, 400 for email, invitation in zip(emails, invitations): send_invitation_email(email, invitation, card) return {"success": True, "sent": len(emails)} def send_invitation_email(email, invitation, card): event = card.event invitation_url = url_for('visitor.register', token=invitation.unique_token, _external=True) msg = Message( f"دعوة لحضور {event.name}", sender=current_app.config["MAIL_USERNAME"], recipients=[email] ) msg.html = f""" <div dir="rtl" style="font-family: Arial, sans-serif;"> <h2>دعوة خاصة</h2> <p>يسرنا دعوتكم لحضور {event.name}</p> <p><strong>التاريخ:</strong> {event.event_time.strftime('%Y-%m-%d')}</p> <p>{card.message}</p> <p> <a href="{invitation_url}" style="background-color: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; display: inline-block;"> التسجيل وتأكيد الحضور </a> </p> <p>نتطلع لرؤيتكم في الحدث</p> </div> """ mail.send(msg) وإنشاء صفحة لإرسال الدعوات templates/card/send_invitations.html {% extends "base.html" %} {% block title %}إرسال الدعوات{% endblock %} {% block content %} <div class="container mt-4"> <h2>إرسال دعوات: {{ card.name }}</h2> <div class="card"> <div class="card-body"> <h5>إدخال عناوين البريد الإلكتروني</h5> <p>أدخل عنوان بريد إلكتروني واحد في كل سطر</p> <form id="sendInvitationsForm"> <div class="mb-3"> <textarea class="form-control" id="emails" rows="10" placeholder="example1@email.com example2@email.com example3@email.com"></textarea> </div> <div class="alert alert-info"> <strong>ملاحظة:</strong> لديك {{ available_invitations }} دعوة غير مستخدمة </div> <button type="submit" class="btn btn-primary">إرسال الدعوات</button> <a href="{{ url_for('card.show_invitations', card_id=card.id) }}" class="btn btn-secondary">إلغاء</a> </form> </div> </div> </div> <script> document.getElementById('sendInvitationsForm').addEventListener('submit', async function(e) { e.preventDefault(); const emailsText = document.getElementById('emails').value; const emails = emailsText.split('\n').filter(email => email.trim() !== ''); if (emails.length === 0) { alert('يرجى إدخال عنوان بريد إلكتروني واحد على الأقل'); return; } try { const response = await fetch('{{ url_for("card.send_invitations", card_id=card.id) }}', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ emails: emails }) }); const data = await response.json(); if (response.ok) { alert(`تم إرسال ${data.sent} دعوة بنجاح!`); window.location.href = '{{ url_for("card.show_invitations", card_id=card.id) }}'; } else { alert(`خطأ: ${data.error}`); } } catch (error) { alert('حدث خطأ في إرسال الدعوات'); } }); </script> {% endblock %} ثم عليك حذف قاعدة البيانات القديمة event.db وإنشاء جديدة: python create_superuser.py ثم تشغيل المشروع.1 نقطة
-
تم حل مشكلة شكرا لك لكن ظهرت مشكلة اخرة لقد رفعت المشروع وفتحت المشروع من خلال الهاتف وعند ضغط على اي رابط يظهر نفس الخطأ هذه هو رابط المشروع بعد رفعه https://inspiring-gingersnap-c140fc.netlify.app/1 نقطة
-
1 نقطة