template tutoring-admin-dashboard v1
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
"""SQLAlchemy ORM models for the SwatiYadav tuition website.
|
||||
|
||||
Every public section is a table so the teacher can edit it from admin. The
|
||||
public site reads these; the admin panel writes them.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date, datetime, timezone
|
||||
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
Date,
|
||||
DateTime,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
String,
|
||||
Text,
|
||||
UniqueConstraint,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.db import Base
|
||||
|
||||
|
||||
def _now() -> datetime:
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
|
||||
class AdminUser(Base):
|
||||
__tablename__ = "admin_user"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
username: Mapped[str] = mapped_column(String(80), unique=True, nullable=False)
|
||||
password_hash: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
|
||||
|
||||
class Profile(Base):
|
||||
__tablename__ = "profile"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String(160), default="")
|
||||
tagline: Mapped[str] = mapped_column(String(255), default="")
|
||||
bio: Mapped[str] = mapped_column(Text, default="")
|
||||
photo_url: Mapped[str] = mapped_column(Text, default="")
|
||||
qualifications: Mapped[str] = mapped_column(Text, default="")
|
||||
experience_years: Mapped[int] = mapped_column(Integer, default=0)
|
||||
students_taught: Mapped[int] = mapped_column(Integer, default=0)
|
||||
achievements: Mapped[str] = mapped_column(Text, default="")
|
||||
hero_cta: Mapped[str] = mapped_column(String(120), default="Book a free demo")
|
||||
|
||||
|
||||
class Subject(Base):
|
||||
__tablename__ = "subject"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String(120), default="")
|
||||
level: Mapped[str] = mapped_column(String(120), default="")
|
||||
description: Mapped[str] = mapped_column(Text, default="")
|
||||
mode: Mapped[str] = mapped_column(String(60), default="Online & Offline")
|
||||
icon: Mapped[str] = mapped_column(String(20), default="📘")
|
||||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
|
||||
class Course(Base):
|
||||
__tablename__ = "course"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
title: Mapped[str] = mapped_column(String(160), default="")
|
||||
subject: Mapped[str] = mapped_column(String(120), default="")
|
||||
description: Mapped[str] = mapped_column(Text, default="")
|
||||
duration: Mapped[str] = mapped_column(String(120), default="")
|
||||
mode: Mapped[str] = mapped_column(String(60), default="Online & Offline")
|
||||
highlights: Mapped[str] = mapped_column(Text, default="") # newline-separated
|
||||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
|
||||
class FeePlan(Base):
|
||||
__tablename__ = "fee_plan"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String(120), default="")
|
||||
price: Mapped[str] = mapped_column(String(60), default="")
|
||||
period: Mapped[str] = mapped_column(String(60), default="per month")
|
||||
features: Mapped[str] = mapped_column(Text, default="") # newline-separated
|
||||
highlighted: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
|
||||
class Testimonial(Base):
|
||||
__tablename__ = "testimonial"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
author_name: Mapped[str] = mapped_column(String(120), default="")
|
||||
relation: Mapped[str] = mapped_column(String(60), default="Student")
|
||||
quote: Mapped[str] = mapped_column(Text, default="")
|
||||
rating: Mapped[int] = mapped_column(Integer, default=5)
|
||||
sort_order: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
|
||||
class SiteSettings(Base):
|
||||
__tablename__ = "site_settings"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
address: Mapped[str] = mapped_column(Text, default="")
|
||||
phone: Mapped[str] = mapped_column(String(60), default="")
|
||||
email: Mapped[str] = mapped_column(String(160), default="")
|
||||
hours: Mapped[str] = mapped_column(String(255), default="")
|
||||
whatsapp: Mapped[str] = mapped_column(String(160), default="")
|
||||
instagram: Mapped[str] = mapped_column(String(160), default="")
|
||||
youtube: Mapped[str] = mapped_column(String(160), default="")
|
||||
facebook: Mapped[str] = mapped_column(String(160), default="")
|
||||
footer_text: Mapped[str] = mapped_column(Text, default="")
|
||||
|
||||
|
||||
class Review(Base):
|
||||
__tablename__ = "review"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
author_name: Mapped[str] = mapped_column(String(160), default="")
|
||||
relation: Mapped[str] = mapped_column(String(60), default="Student")
|
||||
rating: Mapped[int] = mapped_column(Integer, default=5)
|
||||
message: Mapped[str] = mapped_column(Text, default="")
|
||||
is_approved: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now)
|
||||
|
||||
|
||||
class Enquiry(Base):
|
||||
__tablename__ = "enquiry"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String(160), default="")
|
||||
email: Mapped[str] = mapped_column(String(160), default="")
|
||||
phone: Mapped[str] = mapped_column(String(60), default="")
|
||||
subject_interest: Mapped[str] = mapped_column(String(160), default="")
|
||||
message: Mapped[str] = mapped_column(Text, default="")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now)
|
||||
is_read: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
|
||||
|
||||
# ---- Student management (admin-only, private) ----
|
||||
|
||||
|
||||
class Student(Base):
|
||||
__tablename__ = "student"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String(160), default="")
|
||||
phone: Mapped[str] = mapped_column(String(60), default="")
|
||||
parent_name: Mapped[str] = mapped_column(String(160), default="")
|
||||
parent_phone: Mapped[str] = mapped_column(String(60), default="")
|
||||
address: Mapped[str] = mapped_column(Text, default="")
|
||||
subject: Mapped[str] = mapped_column(String(160), default="")
|
||||
monthly_fee: Mapped[int] = mapped_column(Integer, default=0)
|
||||
start_date: Mapped[date] = mapped_column(Date, default=date.today)
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
notes: Mapped[str] = mapped_column(Text, default="")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now)
|
||||
|
||||
slots: Mapped[list["ScheduleSlot"]] = relationship(
|
||||
back_populates="student",
|
||||
cascade="all, delete-orphan",
|
||||
)
|
||||
|
||||
|
||||
class ScheduleSlot(Base):
|
||||
__tablename__ = "schedule_slot"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
student_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("student.id", ondelete="CASCADE"), nullable=False, index=True
|
||||
)
|
||||
weekday: Mapped[int] = mapped_column(Integer, default=0) # 0=Mon .. 6=Sun
|
||||
start_time: Mapped[str] = mapped_column(String(5), default="") # "HH:MM"
|
||||
end_time: Mapped[str] = mapped_column(String(5), default="")
|
||||
|
||||
student: Mapped["Student"] = relationship(back_populates="slots")
|
||||
|
||||
|
||||
class Attendance(Base):
|
||||
__tablename__ = "attendance"
|
||||
__table_args__ = (UniqueConstraint("student_id", "date", name="uq_attendance_student_date"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
student_id: Mapped[int] = mapped_column(
|
||||
ForeignKey("student.id", ondelete="CASCADE"), nullable=False, index=True
|
||||
)
|
||||
date: Mapped[date] = mapped_column(Date, nullable=False, index=True)
|
||||
status: Mapped[str] = mapped_column(String(10), default="present") # present|absent|off
|
||||
note: Mapped[str] = mapped_column(Text, default="") # why absent / off
|
||||
|
||||
|
||||
class DayMark(Base):
|
||||
__tablename__ = "day_mark"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
date: Mapped[date] = mapped_column(Date, unique=True, nullable=False, index=True)
|
||||
kind: Mapped[str] = mapped_column(String(12), default="holiday") # holiday|class_off
|
||||
note: Mapped[str] = mapped_column(String(255), default="")
|
||||
Reference in New Issue
Block a user