diff --git a/Puddle/puddle/converstation/__init__.py b/Puddle/puddle/converstation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Puddle/puddle/converstation/admin.py b/Puddle/puddle/converstation/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..5faba50abe29744c8a80b51f9284bbebe18b00fa --- /dev/null +++ b/Puddle/puddle/converstation/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin + +from .models import Conversation, ConversationMessage + +admin.site.register(Conversation) +admin.site.register(ConversationMessage) diff --git a/Puddle/puddle/converstation/apps.py b/Puddle/puddle/converstation/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..a3a1cdcd28c9cd8002b3bb94c54e2932b4ed2269 --- /dev/null +++ b/Puddle/puddle/converstation/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ConverstationConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'converstation' diff --git a/Puddle/puddle/converstation/forms.py b/Puddle/puddle/converstation/forms.py new file mode 100644 index 0000000000000000000000000000000000000000..3f9ac18bdafea723f7dea61e1d146fb5e2aca198 --- /dev/null +++ b/Puddle/puddle/converstation/forms.py @@ -0,0 +1,13 @@ +from django from django import forms + +from .models import ConversationMessage + +class ConversationMessageForm(forms.ModelForm): + class Meta: + model = ConversationMessage + fields = ('content',) + widgets = { + 'content': forms.Textarea(attrs={ + 'class': 'w-full py-4 px-6 rounded-xl border' + }) + } \ No newline at end of file diff --git a/Puddle/puddle/converstation/migrations/__init__.py b/Puddle/puddle/converstation/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Puddle/puddle/converstation/models.py b/Puddle/puddle/converstation/models.py new file mode 100644 index 0000000000000000000000000000000000000000..544bb851e53cdfdc6ad73ddf97d1809ec8c1f2d4 --- /dev/null +++ b/Puddle/puddle/converstation/models.py @@ -0,0 +1,19 @@ +from django.cotrib.auth.models import User +from django.db import models + +from item.models import Item + +class Conversation(models.Model): + item = models.ForeignKey(Item, related_name='conversations', on_delete=models.CASCADE) + members = models.ManyToManyField(User, related_name='conversations') + created_at = models.DateTimeField(auto_now_add=True) + modified_at = models.DateTimeField(auto_now=True) + + class Meta: + ordering = ('-modified_at',) + +class ConversationMessage(models.Model): + conversation = models.ForeignKey(Conversation, related_name='messages', on_delete=models.CASCADE) + content = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + created_by = models.ForeignKey(User, related_name='created_messages', on_delete=models.CASCADE) diff --git a/Puddle/puddle/converstation/templates/conversation/detail.html b/Puddle/puddle/converstation/templates/conversation/detail.html new file mode 100644 index 0000000000000000000000000000000000000000..1a58a5aaa785e2df96183351af35fdca5749ae87 --- /dev/null +++ b/Puddle/puddle/converstation/templates/conversation/detail.html @@ -0,0 +1,26 @@ +{% extends 'core/base.html' %} + +{% block title %}Conversation{% endblock %} + +{% block content %} +<h1 class="mb-6 text-3xl">Conversation</h1> + +<div class="space-y-6"> + {% for message in conversation.messages.all %} + <div class="pr-6 flex {% if message.created_by == request.user %}bg-blue-100{% else %}bg-gray-100{% endif %} rounded-xl"> + <div> + <p class="mb-4"><strong>{{ message.created_by.username }}</strong> @ {{ message.created_at }}</p> + <p>{{ mesage.content }}</p> + </div> + </div> + {% endfor %} +</div> + +<form method="post" action="." class="mt-6"> + {% csrf_token %} + + {{ form.as_p }} + + <button class="py-4 px-8 text-lg bg-teal-500 hover:bg-teal-700 roundex-xl text-white">Send</button> +</form> +{% endblock %} \ No newline at end of file diff --git a/Puddle/puddle/converstation/templates/conversation/inbox.html b/Puddle/puddle/converstation/templates/conversation/inbox.html new file mode 100644 index 0000000000000000000000000000000000000000..b6c2e2c57f0fa0cc1790a65af973c7e66b602e46 --- /dev/null +++ b/Puddle/puddle/converstation/templates/conversation/inbox.html @@ -0,0 +1,29 @@ +{% extends 'core/base.html' %} + +{% block title %}Inbox{% endblock %} + +{% block content %} +<h1 class="mb-6 text-3xl">Inbox</h1> + +<div class="space-y-6"> + {% for conversation in conversations %} + <a href="{% url 'conversation:detail' conversation.id %}"> + <div class="pr-6 flex bg-gray-100 rounded-xl"> + <div class="pr-6"> + <img src="{{ conversation.item.image.url }}" class="w-20 rounded-xl"> + </div> + + <div> + {% for member in conversation.members.all %} + {% if member != request.user %} + <p class="mb-4"><strong>{{ member.username }}</strong> | {{ conversation.modified_at }}</p> + <p>{{ conversation.item.name }}</p> + {% endif %} + {% endfor %} + </div> + + </div> + </a> + {% endfor %} +</div> +{% endblock %} \ No newline at end of file diff --git a/Puddle/puddle/converstation/templates/conversation/new.html b/Puddle/puddle/converstation/templates/conversation/new.html new file mode 100644 index 0000000000000000000000000000000000000000..e884249604d5b44311e5c3b14c14772d4db1e932 --- /dev/null +++ b/Puddle/puddle/converstation/templates/conversation/new.html @@ -0,0 +1,27 @@ +{% extends 'core/base.html' %} + +{% block title %}New conversation{% endblock %} + +{% block content %} +<h1 class="mb-6 text-3xl">New conversation</h1> + +<form method="post" action="."> + {% csrf_token %} + + <div class="space-y-4"> + {{ form.as_p }} + </div> + + {% if form.errors or form.non_field_errors %} + <div class="mb-3 p-6 bg-red-100 rounded-xl"> + {% for field in form %} + {{ field.errors }} + {% endfor %} + + {{ form.non_field_errors }} + </div> + {% endif %} + + <button class="mt-6 py-4 px-8 text-lg bg-teal-500 hover:bg-teal-700 rounded-xl text-white">Send</button> +</form> +{% endblock %} \ No newline at end of file diff --git a/Puddle/puddle/converstation/tests.py b/Puddle/puddle/converstation/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6 --- /dev/null +++ b/Puddle/puddle/converstation/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/Puddle/puddle/converstation/urls.py b/Puddle/puddle/converstation/urls.py new file mode 100644 index 0000000000000000000000000000000000000000..9a4b18a3e9f65d6c025eb9196737ca6ab28f6543 --- /dev/null +++ b/Puddle/puddle/converstation/urls.py @@ -0,0 +1,11 @@ +from django.urls import path + +from . import views + +app_name = 'conversation' + +urlpatterns = [ + path('', views.inbox, name='inbox'), + path('<int:pk/', views.detail, name='detail'), + path('new/int:item_pk>/', views.new_conversation, name='new'), +] diff --git a/Puddle/puddle/converstation/views.py b/Puddle/puddle/converstation/views.py new file mode 100644 index 0000000000000000000000000000000000000000..d816a02578967d60a3b1989f5a6be7a5297e915a --- /dev/null +++ b/Puddle/puddle/converstation/views.py @@ -0,0 +1,73 @@ +from django.contrib.auth.decorators import login_required +from django.shortcuts import render, get_object_or_404 + +from item.models import Item + +from .forms import ConversationMessageForm +from .models import Conversation + +@login_required +def new_coversation(request, item_pk): + item = get_object_or_404(Item, pk=item_pk) + + if item.created_by == request.user: + return redirect('dashboard:index') + + conversations = Conversation.objects.filter(item=item).filter(members_in=[request.user.id]) + + if conversations: + return redirect('conversation:detail', pk=conversations.first().id) + + if request.method == 'POST': + from = ConversationMessageForm(request.POST) + + if form.is_valid(): + conversation = Conversation.objects.create(item=item) + conversation.members.add(request.user) + conversation.members.add(item.created_by) + conversation.save() + + conversation_message = form.save(comit=False) + conversation_message.conversation = conversation + conversation_message.created_by = request.user + conversation_message.save() + + return redirect('item:detail', pk=item_pk) + else: + form = ConversationMessageForm() + + return render(request, 'conversation/new.html', { + 'form': form + }) + +@login_required +def inbox(request): + conversations = Conversation.objects.filter(members_in=[request.user.id]) + + return render(request, 'conversation/inbox.html', { + 'conversation': conversations + }) + +@login_required +def detail(request, pk): + conversation = Conversation.objects.filter(members_in=[request.user.id]).get(pk=pk) + + if request.method == 'POST': + form = ConversationMessageForm(request.POST) + + if form.is_valid(): + conversation_message = form.save(comit=False) + conversation_message.conversation = conversation + conversation_message.created_by = request.user + conversation_message.save() + + conversation_message.save() + + return redirect('conversatio:detail', pk=pk) + else: + form = ConversationMessageForm() + + return render(request, 'conversation/detail.html'{ + 'conversation':conversation, + 'form': form + }) diff --git a/Puddle/puddle/core/templates/core/base.html b/Puddle/puddle/core/templates/core/base.html index a316d5bbf925e45496bc8c6b2f09a337b945843b..d7c48f5437c2eb8fa2016964fc8d9a6f360af100 100644 --- a/Puddle/puddle/core/templates/core/base.html +++ b/Puddle/puddle/core/templates/core/base.html @@ -19,7 +19,7 @@ <a href"{% url 'item:items' %}" class="text-lg font-semibold hover:text-gray-500">Browse</a> {% if request.user.is_authenticated %} - <a href="#" class="px-6 py-3 text-lg font-semibold bg-teal-500 text-white rounded-xl hover:bg-teal-700">Inbox</a> + <a href="{% url 'conversation:inbox' %}" class="px-6 py-3 text-lg font-semibold bg-teal-500 text-white rounded-xl hover:bg-teal-700">Inbox</a> <a href="{% url 'dashboard:index' %}" class="px-6 py-3 text-lg font-semibold bg-gray-500 text-white rounded-xl hover:bg-gray-700">Dashboard</a> {% else %} <a href="{% url 'core:signup' %}" class="px-6 py-3 text-lg font-semibold bg-teal-500 text-white rounded-xl hover:bg-teal-700">Sign up</a> diff --git a/Puddle/puddle/core/templates/core/signup.html b/Puddle/puddle/core/templates/core/signup.html index 2dff038cbcb06c9bbd770fad4801b1b2b16b0ac9..a115343cc8d3e14a9de33553f02e3cd532429ad3 100644 --- a/Puddle/puddle/core/templates/core/signup.html +++ b/Puddle/puddle/core/templates/core/signup.html @@ -27,10 +27,7 @@ <div class="mb-3"> <label class="inline-block mb-2">Repeat password</label><br> {{ form.password2 }} - - <div class="mb-3"> - <label class="inline-block mb-2">Deploy product</label><br> - {{ form.password2 }} + {% if form.errors or form.non_field_errors %} <div class="mb-3 p-6 bg-red-100 rounded-xl"> diff --git a/Puddle/puddle/core/templates/core/signup2.html b/Puddle/puddle/core/templates/core/signup2.html deleted file mode 100644 index 277b2d7cda92ecf871251799e09a33345984714c..0000000000000000000000000000000000000000 --- a/Puddle/puddle/core/templates/core/signup2.html +++ /dev/null @@ -1,44 +0,0 @@ -{% extends 'core/base.html' %} - -{% block title %}Sign up{% endblock %} - -{% block content %} -<div class="w-1/2 my-6 mx-auto p-6 bg-gray-100 rounded-xl"> - <h1 class="mb-6 text-3xl">Sign up</h1> - - <form method="post" action="."> - {% csrf_token %} - - <div class="mb-3"> - <label class="inline-block mb-2">Username</label><br> - {{ form.username }} - </div> - - <div class="mb-3"> - <label class="inline-block mb-2">Email</label><br> - {{ form.email }} - </div> - - <div class="mb-3"> - <label class="inline-block mb-2">Password</label><br> - {{ form.password1 }} - </div> - - <div class="mb-3"> - <label class="inline-block mb-2">Repeat password</label><br> - {{ form.password2 }} - - {% if form.errors or form.non_field_errors %} - <div class="mb-3 p-6 bg-red-100 rounded-xl"> - {% for field in form %} - {{ field.errors }} - {% endfor %} - - {{ form.non_field_errors }} - </div> - {% endif %} - - <button class="py-4 px-8 text-lg bg-teal-500 hover:bg-teal-700 roundex-xl text-white">Submit</button> - </form> -</div> -{% endblock %} diff --git a/Puddle/puddle/item/__pycache__/views.cpython-310.pyc b/Puddle/puddle/item/__pycache__/views.cpython-310.pyc index 13b092dc77a85afa71db3e75571da754b16824c7..61178a5dfaf750db98d1fc7ddbc8d33330769988 100644 Binary files a/Puddle/puddle/item/__pycache__/views.cpython-310.pyc and b/Puddle/puddle/item/__pycache__/views.cpython-310.pyc differ diff --git a/Puddle/puddle/item/templates/item/detail.html b/Puddle/puddle/item/templates/item/detail.html index 7c84c65345fe8d2590698231e286d334efdc870c..043132ef4c0c6d0ef924d12dac55d210785095ca 100644 --- a/Puddle/puddle/item/templates/item/detail.html +++ b/Puddle/puddle/item/templates/item/detail.html @@ -28,7 +28,7 @@ <a href="{% url 'item:delete' item.id %}" class="inline-block mt-6 px-6 py-3 text-lg font-semibold bg-red-500 text-white rounded-xl">Delete</a> </div> {% else %} - <a href="#" class="inline-block mt-6 px-6 py-3 text-lg font-semibold bg-teal-500 text-white rounded-xl hover:bg-teal-700">Contact seller</a> + <a href="{% url 'conversation:new' item.id %}" class="inline-block mt-6 px-6 py-3 text-lg font-semibold bg-teal-500 text-white rounded-xl hover:bg-teal-700">Contact seller</a> {% endif %} </div> </div> diff --git a/Puddle/puddle/puddle/__pycache__/settings.cpython-310.pyc b/Puddle/puddle/puddle/__pycache__/settings.cpython-310.pyc index 10c4e91d953ecd3221331f3f2f162f847ba61aac..a7768af01b320d9f512447fa41c32749a118e653 100644 Binary files a/Puddle/puddle/puddle/__pycache__/settings.cpython-310.pyc and b/Puddle/puddle/puddle/__pycache__/settings.cpython-310.pyc differ diff --git a/Puddle/puddle/puddle/settings.py b/Puddle/puddle/puddle/settings.py index ef74a572e68d6c9aef9688d0fb896ed070de0b45..089bf59f08a714d0345fc59d8ab16e052dc20df6 100644 --- a/Puddle/puddle/puddle/settings.py +++ b/Puddle/puddle/puddle/settings.py @@ -41,6 +41,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'conversation', 'core', 'dashboard', 'item', diff --git a/Puddle/puddle/puddle/urls.py b/Puddle/puddle/puddle/urls.py index ce9b9866293a08552cb8e5f90d3c889800838118..f3354549f8cf272504c0b0256c5299a68d4eddbf 100644 --- a/Puddle/puddle/puddle/urls.py +++ b/Puddle/puddle/puddle/urls.py @@ -9,5 +9,6 @@ urlpatterns = [ path('', include('core.urls')), path('items/', include('item.urls')), path('dashboard/', include('dashboard.urls')), + path('inbox/' include('conversation.urls')), path('admin/', admin.site.urls), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/env/pyvenv.cfg b/env/pyvenv.cfg index 158aefdb5751378d14d4b24d2fe9b670698118df..ed41b9b92685d598caa5f256ecffa254a144a489 100644 --- a/env/pyvenv.cfg +++ b/env/pyvenv.cfg @@ -1,3 +1,3 @@ -home = /Library/Frameworks/Python.framework/Versions/3.10/bin +home = /Users/home/teamb/.venv/bin include-system-site-packages = false -version = 3.10.7 +version = 3.10. \ No newline at end of file