diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index cd6f855..7fb1478 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000..7812d1d Binary files /dev/null and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 9aa598b..403759f 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 1f807fa..7c7ea4c 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 6867ddf..9b008bf 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index 8c38f3f..1f25b5b 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,3 +1,5 @@ from django.contrib import admin +from .models import Lead, Call -# Register your models here. +admin.site.register(Lead) +admin.site.register(Call) diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..76f699f --- /dev/null +++ b/core/forms.py @@ -0,0 +1,12 @@ +from django import forms +from .models import Lead, Call + +class LeadForm(forms.ModelForm): + class Meta: + model = Lead + fields = ['company', 'contact_name', 'phone', 'notes', 'status'] + +class CallForm(forms.ModelForm): + class Meta: + model = Call + fields = ['call_outcome', 'summary', 'developments', 'requirements_raised', 'actions_taken', 'next_followup_date', 'followup_required'] diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..4dd7e7e --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 5.2.7 on 2025-10-28 12:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Lead', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('company', models.CharField(max_length=255)), + ('contact_name', models.CharField(max_length=255)), + ('phone', models.CharField(max_length=20)), + ('notes', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('last_contacted_at', models.DateTimeField(auto_now=True)), + ], + ), + ] diff --git a/core/migrations/0002_call.py b/core/migrations/0002_call.py new file mode 100644 index 0000000..00bc53d --- /dev/null +++ b/core/migrations/0002_call.py @@ -0,0 +1,32 @@ +# Generated by Django 5.2.7 on 2025-10-28 12:12 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Call', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('call_outcome', models.CharField(max_length=255)), + ('summary', models.TextField()), + ('developments', models.TextField()), + ('requirements_raised', models.TextField()), + ('actions_taken', models.TextField()), + ('next_followup_date', models.DateTimeField()), + ('followup_required', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('lead', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='calls', to='core.lead')), + ('sales_rep', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/0003_lead_status.py b/core/migrations/0003_lead_status.py new file mode 100644 index 0000000..849900c --- /dev/null +++ b/core/migrations/0003_lead_status.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2025-10-28 12:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_call'), + ] + + operations = [ + migrations.AddField( + model_name='lead', + name='status', + field=models.CharField(choices=[('New', 'New'), ('Contacted', 'Contacted'), ('In Progress', 'In Progress'), ('Proposal Sent', 'Proposal Sent'), ('Closed Won', 'Closed Won'), ('Closed Lost', 'Closed Lost'), ('No Answer', 'No Answer')], default='New', max_length=50), + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..8ce26e5 Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0002_call.cpython-311.pyc b/core/migrations/__pycache__/0002_call.cpython-311.pyc new file mode 100644 index 0000000..cb401d9 Binary files /dev/null and b/core/migrations/__pycache__/0002_call.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0003_lead_status.cpython-311.pyc b/core/migrations/__pycache__/0003_lead_status.cpython-311.pyc new file mode 100644 index 0000000..50d87cf Binary files /dev/null and b/core/migrations/__pycache__/0003_lead_status.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..11f95ac 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,37 @@ from django.db import models +from django.contrib.auth.models import User -# Create your models here. +class Lead(models.Model): + company = models.CharField(max_length=255) + contact_name = models.CharField(max_length=255) + phone = models.CharField(max_length=20) + notes = models.TextField(blank=True, null=True) + status = models.CharField(max_length=50, choices=[ + ('New', 'New'), + ('Contacted', 'Contacted'), + ('In Progress', 'In Progress'), + ('Proposal Sent', 'Proposal Sent'), + ('Closed Won', 'Closed Won'), + ('Closed Lost', 'Closed Lost'), + ('No Answer', 'No Answer'), + ], default='New') + created_at = models.DateTimeField(auto_now_add=True) + last_contacted_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return self.company + +class Call(models.Model): + lead = models.ForeignKey(Lead, related_name='calls', on_delete=models.CASCADE) + sales_rep = models.ForeignKey(User, on_delete=models.CASCADE) + call_outcome = models.CharField(max_length=255) + summary = models.TextField() + developments = models.TextField() + requirements_raised = models.TextField() + actions_taken = models.TextField() + next_followup_date = models.DateTimeField() + followup_required = models.BooleanField(default=False) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"Call with {self.lead.contact_name} on {self.created_at}" \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 788576e..ba44d35 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -2,10 +2,20 @@ - {% block title %}Knowledge Base{% endblock %} + + {% block title %}Lead Tracker{% endblock %} + {% block head %}{% endblock %} - {% block content %}{% endblock %} + +
+ {% block content %}{% endblock %} +
+ - + \ No newline at end of file diff --git a/core/templates/core/index.html b/core/templates/core/index.html index 0a3f404..3f78462 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,154 +1,61 @@ -{% extends "base.html" %} - -{% block title %}{{ project_name }}{% endblock %} - -{% block head %} -{% if project_description %} - - - -{% endif %} -{% if project_image_url %} - - -{% endif %} - - - - -{% endblock %} +{% extends 'base.html' %} {% block content %} -
-
-

Analyzing your requirements and generating your app…

-
- Loading… +
+
+

Leads

+
-

AppWizzy AI is collecting your requirements and applying the first changes.

-

This page will refresh automatically as the plan is implemented.

-

- Runtime: Django {{ django_version }} · Python {{ python_version }} - — UTC {{ current_time|date:"Y-m-d H:i:s" }} -

-
-
- -{% endblock %} \ No newline at end of file + + + + + + + + + + + + + + + + + {% for lead in leads %} + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
CompanyContact NamePhoneCreated AtLast ContactedStatusNotes
{{ lead.company }}{{ lead.contact_name }}{{ lead.phone }}{{ lead.created_at|date:"Y-m-d H:i" }}{{ lead.last_contacted_at|date:"Y-m-d H:i" }}{{ lead.status }}{{ lead.notes }}
No leads found.
+ +{% endblock %} diff --git a/core/templates/core/lead_detail.html b/core/templates/core/lead_detail.html new file mode 100644 index 0000000..92103bf --- /dev/null +++ b/core/templates/core/lead_detail.html @@ -0,0 +1,50 @@ +{% extends 'base.html' %} + +{% block content %} +
+

{{ lead.company }}

+ +
+
+ Lead Details +
+
+

Contact Name: {{ lead.contact_name }}

+

Phone: {{ lead.phone }}

+

Notes: {{ lead.notes }}

+

Created At: {{ lead.created_at }}

+

Last Contacted At: {{ lead.last_contacted_at }}

+
+
+ +
+
+ Calls +
+
+ {% for call in lead.calls.all %} +
+

{{ call.created_at }} - {{ call.summary }}

+
+ {% empty %} +

No calls logged yet.

+ {% endfor %} +
+
+ +
+
+ Log a New Call +
+
+
+ {% csrf_token %} + {{ form.as_p }} + +
+
+
+ + Back to Leads +
+{% endblock %} diff --git a/core/templates/core/lead_list.html b/core/templates/core/lead_list.html new file mode 100644 index 0000000..29a6c1d --- /dev/null +++ b/core/templates/core/lead_list.html @@ -0,0 +1,59 @@ +{% extends 'base.html' %} + +{% block content %} +
+
+

Leads

+ +
+ + + + + + + + + + + + + + + + {% for lead in leads %} + + + + + + + + + {% empty %} + + + + {% endfor %} + +
CompanyContact NamePhoneCreated AtLast ContactedNotes
{{ lead.company }}{{ lead.contact_name }}{{ lead.phone }}{{ lead.created_at|date:"Y-m-d H:i" }}{{ lead.last_contacted_at|date:"Y-m-d H:i" }}{{ lead.notes }}
No leads found.
+
+{% endblock %} diff --git a/core/urls.py b/core/urls.py index 6299e3d..e8f4131 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,7 +1,7 @@ from django.urls import path - -from .views import home +from . import views urlpatterns = [ - path("", home, name="home"), + path('', views.index, name='index'), + path('lead//', views.lead_detail, name='lead_detail'), ] diff --git a/core/views.py b/core/views.py index c9aed12..afbc3c3 100644 --- a/core/views.py +++ b/core/views.py @@ -1,25 +1,29 @@ -import os -import platform +from django.shortcuts import render, redirect, get_object_or_404 +from .models import Lead, Call +from .forms import LeadForm, CallForm -from django import get_version as django_version -from django.shortcuts import render -from django.utils import timezone +def index(request): + if request.method == 'POST': + form = LeadForm(request.POST) + if form.is_valid(): + form.save() + return redirect('index') + else: + form = LeadForm() + + leads = Lead.objects.all() + return render(request, 'core/index.html', {'form': form, 'leads': leads}) - -def home(request): - """Render the landing screen with loader and environment details.""" - host_name = request.get_host().lower() - agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic" - now = timezone.now() - - context = { - "project_name": "New Style", - "agent_brand": agent_brand, - "django_version": django_version(), - "python_version": platform.python_version(), - "current_time": now, - "host_name": host_name, - "project_description": os.getenv("PROJECT_DESCRIPTION", ""), - "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), - } - return render(request, "core/index.html", context) +def lead_detail(request, lead_id): + lead = get_object_or_404(Lead, pk=lead_id) + if request.method == 'POST': + form = CallForm(request.POST) + if form.is_valid(): + call = form.save(commit=False) + call.lead = lead + call.sales_rep = request.user + call.save() + return redirect('lead_detail', lead_id=lead.id) + else: + form = CallForm() + return render(request, 'core/lead_detail.html', {'lead': lead, 'form': form}) \ No newline at end of file