template tutoring-admin-dashboard v1
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
"""Create tables and seed the DEVTeacher placeholder content on first run.
|
||||
|
||||
Idempotent: if an admin already exists, nothing is seeded. The default admin is
|
||||
username ``DEVTeacher`` / password ``DEVTeacher`` (the teacher changes it).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date
|
||||
|
||||
from sqlalchemy import inspect, text
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import Base, SessionLocal, engine
|
||||
from app.models import (
|
||||
AdminUser,
|
||||
Attendance,
|
||||
Course,
|
||||
DayMark,
|
||||
Enquiry,
|
||||
FeePlan,
|
||||
Profile,
|
||||
Review,
|
||||
ScheduleSlot,
|
||||
SiteSettings,
|
||||
Student,
|
||||
Subject,
|
||||
Testimonial,
|
||||
)
|
||||
from app.security import hash_password
|
||||
|
||||
DEFAULT_ADMIN_USER = "DEVTeacher"
|
||||
DEFAULT_ADMIN_PASS = "DEVTeacher"
|
||||
|
||||
|
||||
def _seed(db: Session) -> None:
|
||||
db.add(AdminUser(username=DEFAULT_ADMIN_USER, password_hash=hash_password(DEFAULT_ADMIN_PASS)))
|
||||
|
||||
db.add(
|
||||
Profile(
|
||||
name="Swati Yadav",
|
||||
tagline="Making learning joyful, clear and exam-ready",
|
||||
bio=(
|
||||
"Hello! I'm Swati Yadav, a passionate tuition teacher with years of experience "
|
||||
"helping students build strong fundamentals and real confidence. I focus on "
|
||||
"concept clarity, regular practice and personal attention so every student can "
|
||||
"reach their full potential — whether the goal is topping the class, cracking "
|
||||
"board exams, or simply falling in love with a subject."
|
||||
),
|
||||
photo_url="",
|
||||
qualifications="M.Sc. Mathematics · B.Ed. · Certified Online Educator",
|
||||
experience_years=10,
|
||||
students_taught=500,
|
||||
achievements=(
|
||||
"95% of students improved by 2+ grades\n"
|
||||
"Mentored 50+ board-exam toppers\n"
|
||||
"Personalised study plans for every learner"
|
||||
),
|
||||
hero_cta="Book a free demo class",
|
||||
)
|
||||
)
|
||||
|
||||
subjects = [
|
||||
("Mathematics", "Class 6–12", "Algebra, geometry, calculus and problem-solving made simple with step-by-step methods.", "📐", 1),
|
||||
("Physics", "Class 9–12", "Concept-first physics with real-life examples, numericals and exam techniques.", "🔬", 2),
|
||||
("Chemistry", "Class 9–12", "Organic, inorganic and physical chemistry taught with clarity and easy recall tricks.", "⚗️", 3),
|
||||
("English", "Class 6–10", "Grammar, comprehension, writing skills and confident communication.", "📖", 4),
|
||||
]
|
||||
for name, level, desc, icon, order in subjects:
|
||||
db.add(Subject(name=name, level=level, description=desc, mode="Online & Offline", icon=icon, sort_order=order))
|
||||
|
||||
courses = [
|
||||
(
|
||||
"Board Exam Crash Course",
|
||||
"Mathematics & Science",
|
||||
"An intensive revision programme covering the complete syllabus with mock tests, doubt-clearing and previous-year papers.",
|
||||
"3 months",
|
||||
"Practice tests every week\nPersonal doubt sessions\nComplete syllabus revision",
|
||||
1,
|
||||
),
|
||||
(
|
||||
"Foundation Builder",
|
||||
"All Subjects",
|
||||
"A steady long-term course for younger students that builds strong basics and study habits from the ground up.",
|
||||
"Full academic year",
|
||||
"Concept-first teaching\nRegular homework & feedback\nMonthly progress reports",
|
||||
2,
|
||||
),
|
||||
(
|
||||
"One-on-One Personal Tuition",
|
||||
"Chosen Subject",
|
||||
"Fully personalised private tuition tailored to a single student's pace, goals and weak areas.",
|
||||
"Flexible",
|
||||
"Completely customised plan\nFlexible timings\nDedicated attention",
|
||||
3,
|
||||
),
|
||||
]
|
||||
for title, subject, desc, duration, highlights, order in courses:
|
||||
db.add(
|
||||
Course(
|
||||
title=title,
|
||||
subject=subject,
|
||||
description=desc,
|
||||
duration=duration,
|
||||
mode="Online & Offline",
|
||||
highlights=highlights,
|
||||
sort_order=order,
|
||||
)
|
||||
)
|
||||
|
||||
fees = [
|
||||
("Group Batch", "₹1,500", "per month", "Small batches (max 8)\n3 classes a week\nWeekly tests\nStudy material included", False, 1),
|
||||
("Premium Batch", "₹2,500", "per month", "Mini batches (max 4)\n5 classes a week\nWeekly tests + doubt sessions\nMonthly progress report", True, 2),
|
||||
("1-on-1 Private", "₹4,000", "per month", "Fully personal tuition\nFlexible timings\nCustom study plan\nUnlimited doubt support", False, 3),
|
||||
]
|
||||
for name, price, period, features, highlighted, order in fees:
|
||||
db.add(FeePlan(name=name, price=price, period=period, features=features, highlighted=highlighted, sort_order=order))
|
||||
|
||||
testimonials = [
|
||||
("Aarav Sharma", "Student", "Swati ma'am made maths so easy to understand. My marks jumped from 62 to 91 in just one year!", 5, 1),
|
||||
("Meena Gupta", "Parent", "My daughter actually looks forward to her classes now. The personal attention is wonderful.", 5, 2),
|
||||
("Rohan Verma", "Student", "The best teacher I've ever had. She explains every concept until it truly clicks.", 5, 3),
|
||||
("Kavita Nair", "Parent", "Very disciplined, caring and result-oriented. Highly recommend to every parent.", 5, 4),
|
||||
]
|
||||
for author, relation, quote, rating, order in testimonials:
|
||||
db.add(Testimonial(author_name=author, relation=relation, quote=quote, rating=rating, sort_order=order))
|
||||
|
||||
db.add(
|
||||
SiteSettings(
|
||||
address="123 Vidya Nagar, Near City Library, Your City, 000000",
|
||||
phone="+91 90000 00000",
|
||||
email="hello@swatiyadav.com",
|
||||
hours="Mon–Sat, 9:00 AM – 8:00 PM",
|
||||
whatsapp="https://wa.me/919000000000",
|
||||
instagram="https://instagram.com/",
|
||||
youtube="https://youtube.com/",
|
||||
facebook="https://facebook.com/",
|
||||
footer_text="Empowering students with knowledge, confidence and care.",
|
||||
)
|
||||
)
|
||||
|
||||
db.add(
|
||||
Enquiry(
|
||||
name="Sample Parent",
|
||||
email="parent@example.com",
|
||||
phone="+91 98765 43210",
|
||||
subject_interest="Mathematics",
|
||||
message="Hi, I'd like to know the timings for the Class 10 maths batch. Thank you!",
|
||||
is_read=False,
|
||||
)
|
||||
)
|
||||
|
||||
reviews = [
|
||||
("Priya Deshmukh", "Parent", 5, "The weekly progress updates keep me informed and my son is far more confident now.", True),
|
||||
("Ananya Rao", "Student", 5, "Doubts are always cleared patiently. Highly recommend her classes!", False),
|
||||
]
|
||||
for author, relation, rating, message, approved in reviews:
|
||||
db.add(Review(author_name=author, relation=relation, rating=rating, message=message, is_approved=approved))
|
||||
|
||||
db.commit()
|
||||
|
||||
_seed_students(db)
|
||||
|
||||
|
||||
def _seed_students(db: Session) -> None:
|
||||
"""Sample students, schedules and a little attendance for this month."""
|
||||
students_data = [
|
||||
# name, phone, parent_name, parent_phone, address, subject, fee, slots
|
||||
(
|
||||
"Aarav Sharma", "+91 98111 22233", "Rakesh Sharma", "+91 98111 00011",
|
||||
"12 Green Park, Your City", "Mathematics · Class 10", 1500,
|
||||
[(0, "16:00", "17:00"), (2, "16:00", "17:00"), (4, "16:00", "17:00")],
|
||||
),
|
||||
(
|
||||
"Isha Verma", "+91 98222 33344", "Sunita Verma", "+91 98222 00022",
|
||||
"45 Lake View, Your City", "Physics · Class 12", 2500,
|
||||
[(1, "17:30", "18:30"), (3, "17:30", "18:30")],
|
||||
),
|
||||
(
|
||||
"Rohan Gupta", "+91 98333 44455", "Manoj Gupta", "+91 98333 00033",
|
||||
"78 Rose Villa, Your City", "Chemistry · Class 11", 2500,
|
||||
[(0, "18:00", "19:00"), (3, "18:00", "19:00"), (5, "10:00", "11:00")],
|
||||
),
|
||||
(
|
||||
"Ananya Nair", "+91 98444 55566", "Kavita Nair", "+91 98444 00044",
|
||||
"9 Sunrise Apartments, Your City", "English · Class 8", 1500,
|
||||
[(1, "16:00", "17:00"), (4, "16:00", "17:00")],
|
||||
),
|
||||
]
|
||||
|
||||
student_objs: list[Student] = []
|
||||
for name, phone, pname, pphone, addr, subj, fee, slots in students_data:
|
||||
s = Student(
|
||||
name=name, phone=phone, parent_name=pname, parent_phone=pphone,
|
||||
address=addr, subject=subj, monthly_fee=fee, start_date=date.today(),
|
||||
is_active=True, notes="",
|
||||
)
|
||||
db.add(s)
|
||||
db.flush()
|
||||
for weekday, start, end in slots:
|
||||
db.add(ScheduleSlot(student_id=s.id, weekday=weekday, start_time=start, end_time=end))
|
||||
student_objs.append(s)
|
||||
|
||||
# A little attendance for the first few days of the current month.
|
||||
today = date.today()
|
||||
statuses = ["present", "present", "absent", "present", "off"]
|
||||
for day in range(1, 6):
|
||||
try:
|
||||
d = date(today.year, today.month, day)
|
||||
except ValueError:
|
||||
continue
|
||||
if d > today:
|
||||
break
|
||||
for i, s in enumerate(student_objs):
|
||||
db.add(Attendance(student_id=s.id, date=d, status=statuses[(day + i) % len(statuses)]))
|
||||
|
||||
# A sample holiday on the 1st (kept only if not in the future).
|
||||
try:
|
||||
first = date(today.year, today.month, 1)
|
||||
db.add(DayMark(date=first, kind="holiday", note="Month start holiday"))
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
db.commit()
|
||||
|
||||
|
||||
def _ensure_columns() -> None:
|
||||
"""Add columns introduced after a table was first created.
|
||||
|
||||
``create_all`` never alters existing tables, so on databases that already
|
||||
have the ``attendance`` table we add the newer ``note`` column by hand.
|
||||
"""
|
||||
inspector = inspect(engine)
|
||||
if "attendance" not in inspector.get_table_names():
|
||||
return
|
||||
cols = {c["name"] for c in inspector.get_columns("attendance")}
|
||||
if "note" not in cols:
|
||||
default = "''" if engine.dialect.name != "sqlite" else "''"
|
||||
with engine.begin() as conn:
|
||||
conn.execute(
|
||||
text(f"ALTER TABLE attendance ADD COLUMN note TEXT NOT NULL DEFAULT {default}")
|
||||
)
|
||||
|
||||
|
||||
def init_db() -> None:
|
||||
Base.metadata.create_all(bind=engine)
|
||||
_ensure_columns()
|
||||
db = SessionLocal()
|
||||
try:
|
||||
if db.query(AdminUser).count() == 0:
|
||||
_seed(db)
|
||||
finally:
|
||||
db.close()
|
||||
Reference in New Issue
Block a user