Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ Thumbs.db # Windows
# Build and output directories
/dist
/build
/out
/out

db.sqlite3
153 changes: 151 additions & 2 deletions core/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.contrib import admin
from .models import FAQ
from .models import Contact, SuccessStory, StoryReaction, Question, Answer, QuestionUpvote, AnswerUpvote
from .models import Contact, SuccessStory, StoryReaction, Question, Answer, QuestionUpvote, AnswerUpvote,Goal,Milestone,StudySession,Achievement,UserStats,WeeklyGoal

@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
Expand Down Expand Up @@ -140,4 +140,153 @@ def answer_author(self, obj):

@admin.register(FAQ)
class FAQAdmin(admin.ModelAdmin):
list_display = ('question', 'answer')
list_display = ('question', 'answer')

# Add these admin configurations to your core/admin.py file

@admin.register(Goal)
class GoalAdmin(admin.ModelAdmin):
list_display = ('title', 'user', 'category', 'priority', 'status', 'progress_percentage', 'target_date', 'is_completed', 'created_at')
list_filter = ('category', 'priority', 'status', 'is_completed', 'created_at')
search_fields = ('title', 'description', 'user__username', 'user__first_name', 'user__last_name')
readonly_fields = ('created_at', 'updated_at', 'completed_at')
list_editable = ('status', 'progress_percentage')
ordering = ('-created_at',)

fieldsets = (
('Goal Information', {
'fields': ('user', 'title', 'description', 'category', 'priority')
}),
('Progress', {
'fields': ('status', 'progress_percentage', 'is_completed', 'target_date')
}),
('Timestamps', {
'fields': ('created_at', 'updated_at', 'completed_at'),
'classes': ('collapse',)
}),
)

@admin.register(Milestone)
class MilestoneAdmin(admin.ModelAdmin):
list_display = ('title', 'goal', 'goal_user', 'is_completed', 'due_date', 'created_at')
list_filter = ('is_completed', 'due_date', 'created_at')
search_fields = ('title', 'description', 'goal__title', 'goal__user__username')
readonly_fields = ('created_at', 'completed_at')
list_editable = ('is_completed',)
ordering = ('-created_at',)

def goal_user(self, obj):
return obj.goal.user.username
goal_user.short_description = 'Goal Owner'

fieldsets = (
('Milestone Information', {
'fields': ('goal', 'title', 'description', 'due_date')
}),
('Status', {
'fields': ('is_completed',)
}),
('Timestamps', {
'fields': ('created_at', 'completed_at'),
'classes': ('collapse',)
}),
)

@admin.register(StudySession)
class StudySessionAdmin(admin.ModelAdmin):
list_display = ('title', 'user', 'subject', 'duration_minutes', 'productivity_rating', 'date', 'created_at')
list_filter = ('subject', 'date', 'productivity_rating', 'created_at')
search_fields = ('title', 'description', 'notes', 'user__username', 'user__first_name', 'user__last_name')
readonly_fields = ('created_at',)
ordering = ('-date', '-created_at')

fieldsets = (
('Session Information', {
'fields': ('user', 'subject', 'title', 'description', 'date')
}),
('Performance', {
'fields': ('duration_minutes', 'productivity_rating')
}),
('Additional', {
'fields': ('goals_related', 'notes'),
'classes': ('collapse',)
}),
('Timestamps', {
'fields': ('created_at',),
'classes': ('collapse',)
}),
)

@admin.register(Achievement)
class AchievementAdmin(admin.ModelAdmin):
list_display = ('title', 'user', 'achievement_type', 'points', 'is_earned', 'earned_at')
list_filter = ('achievement_type', 'is_earned', 'earned_at')
search_fields = ('title', 'description', 'user__username', 'user__first_name', 'user__last_name')
readonly_fields = ('earned_at',)
list_editable = ('is_earned',)
ordering = ('-earned_at',)

fieldsets = (
('Achievement Information', {
'fields': ('user', 'title', 'description', 'achievement_type', 'icon')
}),
('Rewards', {
'fields': ('points', 'is_earned', 'related_goal')
}),
('Timestamps', {
'fields': ('earned_at',)
}),
)

@admin.register(UserStats)
class UserStatsAdmin(admin.ModelAdmin):
list_display = ('user', 'total_study_hours', 'total_goals_completed', 'current_streak_days', 'achievement_points', 'last_activity_date')
search_fields = ('user__username', 'user__first_name', 'user__last_name')
readonly_fields = ('created_at', 'updated_at')
ordering = ('-total_study_hours',)

fieldsets = (
('User', {
'fields': ('user',)
}),
('Study Statistics', {
'fields': ('total_study_hours', 'current_streak_days', 'longest_streak_days', 'last_activity_date')
}),
('Community Statistics', {
'fields': ('total_questions_asked', 'total_answers_given', 'total_success_stories')
}),
('Achievements', {
'fields': ('total_goals_completed', 'achievement_points')
}),
('Timestamps', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',)
}),
)

@admin.register(WeeklyGoal)
class WeeklyGoalAdmin(admin.ModelAdmin):
list_display = ('user', 'week_start', 'target_study_hours', 'actual_study_hours', 'target_sessions', 'actual_sessions', 'progress_percentage', 'is_completed')
list_filter = ('week_start', 'is_completed', 'created_at')
search_fields = ('user__username', 'user__first_name', 'user__last_name')
readonly_fields = ('created_at', 'progress_percentage')
ordering = ('-week_start',)

def progress_percentage(self, obj):
return f"{obj.progress_percentage():.1f}%"
progress_percentage.short_description = 'Progress %'

fieldsets = (
('Weekly Goal', {
'fields': ('user', 'week_start')
}),
('Targets', {
'fields': ('target_study_hours', 'target_sessions')
}),
('Actual Progress', {
'fields': ('actual_study_hours', 'actual_sessions', 'is_completed')
}),
('Timestamps', {
'fields': ('created_at',)
}),
)
176 changes: 174 additions & 2 deletions core/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django import forms
from .models import Contact, SuccessStory, Question, Answer
from .models import Contact, SuccessStory, Question, Answer,Goal, Milestone, StudySession, WeeklyGoal
from .models import FAQ
from django.utils import timezone
from datetime import datetime, timedelta

class ContactForm(forms.ModelForm):
class Meta:
Expand Down Expand Up @@ -125,4 +127,174 @@ def clean_content(self):
class FAQForm(forms.ModelForm):
class Meta:
model = FAQ
fields = ['question', 'answer']
fields = ['question', 'answer']

class GoalForm(forms.ModelForm):
class Meta:
model = Goal
fields = ['title', 'description', 'category', 'priority', 'target_date']
widgets = {
'title': forms.TextInput(attrs={
'class': 'form-input',
'placeholder': 'e.g., Master Python Programming',
'required': True
}),
'description': forms.Textarea(attrs={
'class': 'form-textarea',
'placeholder': 'Describe your goal in detail...',
'rows': 3
}),
'category': forms.Select(attrs={
'class': 'form-input',
'required': True
}),
'priority': forms.Select(attrs={
'class': 'form-input',
'required': True
}),
'target_date': forms.DateInput(attrs={
'class': 'form-input',
'type': 'date'
}),
}

def clean_target_date(self):
target_date = self.cleaned_data.get('target_date')
if target_date and target_date <= timezone.now().date():
raise forms.ValidationError("Target date must be in the future.")
return target_date

class MilestoneForm(forms.ModelForm):
class Meta:
model = Milestone
fields = ['title', 'description', 'due_date']
widgets = {
'title': forms.TextInput(attrs={
'class': 'form-input',
'placeholder': 'e.g., Complete Chapter 1',
'required': True
}),
'description': forms.Textarea(attrs={
'class': 'form-textarea',
'placeholder': 'Describe this milestone...',
'rows': 2
}),
'due_date': forms.DateInput(attrs={
'class': 'form-input',
'type': 'date'
}),
}

class StudySessionForm(forms.ModelForm):
class Meta:
model = StudySession
fields = ['subject', 'title', 'description', 'duration_minutes', 'productivity_rating', 'notes', 'date']
widgets = {
'subject': forms.Select(attrs={
'class': 'form-input',
'required': True
}),
'title': forms.TextInput(attrs={
'class': 'form-input',
'placeholder': 'e.g., Algebra Practice Session',
'required': True
}),
'description': forms.Textarea(attrs={
'class': 'form-textarea',
'placeholder': 'What did you study?',
'rows': 2
}),
'duration_minutes': forms.NumberInput(attrs={
'class': 'form-input',
'placeholder': '60',
'min': '1',
'max': '480',
'required': True
}),
'productivity_rating': forms.NumberInput(attrs={
'class': 'form-input',
'min': '1',
'max': '10',
'value': '5',
'required': True
}),
'notes': forms.Textarea(attrs={
'class': 'form-textarea',
'placeholder': 'Any notes or reflections...',
'rows': 3
}),
'date': forms.DateInput(attrs={
'class': 'form-input',
'type': 'date',
'value': timezone.now().date()
}),
}

def clean_duration_minutes(self):
duration = self.cleaned_data.get('duration_minutes')
if duration and (duration < 1 or duration > 480):
raise forms.ValidationError("Duration must be between 1 and 480 minutes (8 hours).")
return duration

def clean_productivity_rating(self):
rating = self.cleaned_data.get('productivity_rating')
if rating and (rating < 1 or rating > 10):
raise forms.ValidationError("Productivity rating must be between 1 and 10.")
return rating

def clean_date(self):
date = self.cleaned_data.get('date')
if date and date > timezone.now().date():
raise forms.ValidationError("Study session date cannot be in the future.")
return date

class WeeklyGoalForm(forms.ModelForm):
class Meta:
model = WeeklyGoal
fields = ['target_study_hours', 'target_sessions']
widgets = {
'target_study_hours': forms.NumberInput(attrs={
'class': 'form-input',
'placeholder': '10.0',
'step': '0.5',
'min': '0.5',
'max': '60',
'required': True
}),
'target_sessions': forms.NumberInput(attrs={
'class': 'form-input',
'placeholder': '5',
'min': '1',
'max': '20',
'required': True
}),
}

def clean_target_study_hours(self):
hours = self.cleaned_data.get('target_study_hours')
if hours and (hours < 0.5 or hours > 60):
raise forms.ValidationError("Target study hours must be between 0.5 and 60 hours per week.")
return hours

def clean_target_sessions(self):
sessions = self.cleaned_data.get('target_sessions')
if sessions and (sessions < 1 or sessions > 20):
raise forms.ValidationError("Target sessions must be between 1 and 20 sessions per week.")
return sessions

class GoalUpdateForm(forms.ModelForm):
class Meta:
model = Goal
fields = ['progress_percentage', 'status']
widgets = {
'progress_percentage': forms.NumberInput(attrs={
'class': 'form-input',
'min': '0',
'max': '100',
'required': True
}),
'status': forms.Select(attrs={
'class': 'form-input',
'required': True
}),
}
Loading