emile 1 year ago
parent 3e79d5b4e2
commit bff4bfacac

@ -19,9 +19,9 @@
<div class="w=full mt-5">
<p class="text-secondosiblue text-xl">Services</p>
<div class="w-full grid grid-cols-1 md:grid-cols-2 l:grid-cols-3 gap-5 mt-3">
<div class="w-full shadow-md">
<div class="w-full shadow-md border border-gray-200 rounded-t-md ">
<div
class="w-ful py-9 px-5 flex justify-center items-center text-center text-secondosiblue bg-gray-100 rounded-t-md">
class="w-ful py-9 px-5 flex justify-center items-center text-center text-secondosiblue bg-white rounded-t-md">
<p>Service Name</p>
</div>
<div

@ -3,6 +3,8 @@ from .models import *
# Register your models here.
admin.site.register(Ticket)
admin.site.register(TicketStatusUpdate)
admin.site.register(TicketRead)
admin.site.register(TicketUpdate)
admin.site.register(TicketAttachment)
admin.site.register(TicketReaction)

@ -1,12 +1,23 @@
from billing.models import *
from osinacore.models import *
from customercore.models import *
from django.db.models import Count, Q
def utilities(request):
active_subscriptions = None
customer_open_tickets = None
if request.user.is_authenticated and CustomerProfile.objects.filter(user=request.user):
customer = request.user.customerprofile
active_subscriptions = OrderItem.objects.filter(active=True, order__customer=customer)
customer_open_tickets = Ticket.objects.filter(
Q(status__in=['Open', 'Working On']) & Q(customer=request.user.customerprofile)
).order_by('-id')
for ticket in customer_open_tickets:
unread_updates_count = 0
for ticket_update in ticket.ticketupdate_set.all():
if not TicketRead.objects.filter(ticket_update=ticket_update, user=request.user, read=True).exists():
unread_updates_count += 1
ticket.unread_updates_count = unread_updates_count
return {'active_subscriptions': active_subscriptions,}
return {'active_subscriptions': active_subscriptions, 'customer_open_tickets': customer_open_tickets}

@ -0,0 +1,26 @@
# Generated by Django 4.2.5 on 2024-04-25 15:32
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('customercore', '0004_ticket_ticket_number_and_more'),
]
operations = [
migrations.CreateModel(
name='TicketStatusUpdate',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(choices=[('Open', 'Open'), ('Working On', 'Working On'), ('Closed', 'Closed')], max_length=50, null=True)),
('date_added', models.DateTimeField()),
('added_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticket')),
],
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-04-25 16:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('customercore', '0005_ticketstatusupdate'),
]
operations = [
migrations.AddField(
model_name='ticketupdate',
name='read',
field=models.BooleanField(default=False, null=True),
),
]

@ -0,0 +1,29 @@
# Generated by Django 4.2.5 on 2024-04-25 18:16
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('customercore', '0006_ticketupdate_read'),
]
operations = [
migrations.RemoveField(
model_name='ticketupdate',
name='read',
),
migrations.CreateModel(
name='TicketUpdateReadStatus',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('read', models.BooleanField(default=False)),
('ticket_update', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='customercore.ticketupdate')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

@ -0,0 +1,19 @@
# Generated by Django 4.2.5 on 2024-04-25 18:25
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('customercore', '0007_remove_ticketupdate_read_ticketupdatereadstatus'),
]
operations = [
migrations.RenameModel(
old_name='TicketUpdateReadStatus',
new_name='TicketRead',
),
]

@ -39,6 +39,19 @@ class Ticket(models.Model):
super().save(*args, **kwargs)
class TicketStatusUpdate(models.Model):
STATUS_CHOICES = (
('Open', 'Open'),
('Working On', 'Working On'),
('Closed', 'Closed'),
)
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
status = models.CharField(max_length=50, choices=STATUS_CHOICES, null=True)
added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
date_added = models.DateTimeField()
class TicketUpdate(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
description = models.TextField(null=True, blank=True)
@ -46,6 +59,11 @@ class TicketUpdate(models.Model):
date_added = models.DateTimeField()
class TicketRead(models.Model):
ticket_update = models.ForeignKey(TicketUpdate, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
read = models.BooleanField(default=False)
class TicketAttachment(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
ticket_update = models.ForeignKey(TicketUpdate, on_delete=models.CASCADE, null=True, blank=True)

@ -6,10 +6,10 @@
<div class="w-full px-5 s:px-9 flex flex-col gap-3">
<div class="w-full bg-white rounded-md h-fit shadow-md p-5">
<div class="w-full h-fit flex flex-col gap-2 bg-gray-100 shadow-md rounded-md px-3 py-3">
<p class="text-secondosiblue text-xl">Ticket: <span class="font-semibold">#2226663535</span></p>
<p class="text-secondosiblue text-xl">Ticket <span class="font-semibold">{{ticket.ticket_number}}</span></p>
<div class="flex justify-start items-center gap-1">
<div class="w-[16px] h-[16px] rounded-full bg-red-200 border border-red-500 shadow-md"></div>
<div class="w-[16px] h-[16px] rounded-full bg-red-200 border shadow-md"></div>
<p class="text-secondosiblue font-light">Closed by Linode at 20-4-24 16:30</p>
</div>
</div>
@ -17,69 +17,41 @@
<div class="w-full flex flex-col gap-8 mt-5 s:mt-10">
<!-- REPLY 1 -->
{% for update in ticket_updates %}
<div class="flex gap-3">
<div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
<img src="{% static 'images/ositcom_logos/full-logo.png' %}"
{% if update.added_by.customerprofile %}
{% if update.added_by.customerprofile.image %}
<img src="{{update.added_by.customerprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
</div>
</div>
<div class="w-full replyContainer shadow-md">
{% else %}
<div
class="w-full bg-gray-100 flex justify-between items-center gap-3 px-3 py-3 cursor-pointer rounded-t-md toggleReply">
<p class="text-secondosiblue font-light text-sm s:text-base"><span class="font-semibold">Ositcom
Ltd</span>
commented 2024-04-17 12:19</p>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4 text-secondosiblue arrowUp">
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4 text-secondosiblue arrowDown hidden">
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg>
class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
<div class="w-full bg-white p-5 flex flex-col gap-3 reply">
<p class="text-gray-500 font-light leading-8 text-[15px]">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur
magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique
varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus
a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices
turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta
et purus. Aliquam at nunc sit amet tortor lacinia porttitor. Proin auctor, eros ac
sollicitudin iaculis, felis quam vulputate ante, eu varius dolor arcu non enim. Vestibulum
ornare dapibus risus, id eleifend ipsum. Aliquam metus urna, bibendum quis cursus vitae,
placerat sit amet felis. Aliquam tellus ex, pretium id gravida id, vulputate et velit.
Phasellus leo felis, lobortis ut dolor eget, viverra aliquet ligula. Aliquam molestie ac
eros et fermentum.
</p>
{% endif %}
{% elif update.added_by.staffprofile %}
{% if update.added_by.staffprofile.image %}
<img src="{{update.added_by.staffprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
{% else %}
<div
class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
{% endif %}
{% endif %}
</div>
</div>
<!-- CUSTOMER SUPPORT REPLY 2 -->
<div class="flex gap-3">
<div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
<img src="{% static 'images/netcommerce-logo.png' %}"
class="w-full h-full rounded-full object-cover">
</div>
</div>
<div class="w-full replyContainer shadow-md">
<div
class="w-full bg-gray-100 flex justify-between items-center gap-3 px-3 py-3 cursor-pointer rounded-t-md toggleReply">
<p class="text-secondosiblue font-light text-sm s:text-base"><span
class="font-semibold">Scott</span>
Customer Support commented 2024-04-17 12:19</p>
<p class="text-secondosiblue font-light text-sm s:text-base"><span class="font-semibold">{{update.added_by.first_name}}</span>
replied {{update.date_added}}</p>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4 text-secondosiblue arrowUp">
@ -93,22 +65,20 @@
</svg>
</div>
<div class="w-full bg-white flex flex-col gap-5 p-5 reply">
<div class="w-full bg-white p-5 flex flex-col gap-3 reply">
<p class="text-gray-500 font-light leading-8 text-[15px]">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur
magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique
varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus
a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices
turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta
et purus.
{{update.description}}
</p>
<div class="w-full border-t border-gray-200 pt-5 flex justify-start items-center gap-3">
</div>
{% if update.added_by.staffprofile %}
<div class="w-full border-t border-gray-200 pt-5 flex justify-start items-center gap-3 p-5">
<a class="text-secondosiblue font-light cursor-pointer hover:text-gray-500 duration-300">How
did I do?</a>
<div class="flex justify-start items-center gap-2">
<div class="w-fit h-fit rounded-full border-4 border-secondosiblue">
<div class="w-fit h-fit rounded-full border-2 border-secondosiblue">
<img src="{% static 'images/icons/happy-icon.png' %}" class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform">
</div>
@ -121,26 +91,48 @@
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
<!-- REPLYING SECTION -->
<div class="flex gap-3">
<form class="flex gap-3" method="POST" action="{% url 'customeraddticketupdate' ticket.id %}" enctype="multipart/form-data">
{% csrf_token %}
<div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
<img src="{% static 'images/ositcom_logos/full-logo.png' %}"
{% if request.user.customerprofile %}
{% if request.user.customerprofile.image %}
<img src="{{request.user.customerprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
{% else %}
<div
class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
{% endif %}
{% elif request.user.staffprofile %}
{% if request.user.staffprofile.image %}
<img src="{{request.user.staffprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
{% else %}
<div
class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
{% endif %}
{% endif %}
</div>
</div>
<div class="w-full flex flex-col gap-3">
<textarea
<textarea name="description"
class="w-full bg-white px-3 py-3 border border-gray-200 rounded-md outline-none text-gray-500 resize-none"
rows="8" placeholder="Reply to Ositcom Ltd..."></textarea>
rows="8" placeholder="Add Comment..."></textarea>
<div class="w-full flex flex-col s:flex-row justify-end items-center gap-3">
@ -160,7 +152,7 @@
</div>
</div>
</form>
</div>
</div>
</div>

@ -11,8 +11,8 @@
<div class="w-full flex flex-col gap-3 mt-4">
<div class="w-full bg-gray-200 rounded-md shadow-md h-fit p-3 flex items-center justify-between gap-5">
<div class="flex items-center gap-5 text-[17px]">
<p class="text-secondosiblue font-semibold cursor-pointer">Open Ticktes</p>
<p class="text-gray-500 cursor-pointer">Closed Ticktes</p>
<p class="text-secondosiblue font-semibold cursor-pointer">Open Tickets</p>
<p class="text-gray-500 cursor-pointer">Closed Tickets</p>
</div>
@ -59,7 +59,7 @@
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a href="{% url 'customerticketdetails' %}">
<a href="">
<p class="text-secondosiblue cursor-pointer hover:text-gray-500 duration-300">My Account Balance</p>
</a>
</td>

@ -7,7 +7,8 @@ urlpatterns = [
path('redirect-osicard/', views.redirect_osicard, name='redirectosicard'),
# ADD
path('customer-add-ticket/', views.customer_add_ticket, name='customeraddticket'),
path('add/ticket/', views.customer_add_ticket, name='customeraddticket'),
path('customer/add/ticketupdate/<int:ticket_id>/', views.customer_add_ticket_update, name='customeraddticketupdate'),
# LISTING
@ -18,7 +19,7 @@ urlpatterns = [
# DETAILS
path('inner-customer-ticket/', views.customer_ticket_details, name='customerticketdetails'),
path('my-tickets/<int:ticket_number>/', views.customer_ticket_details, name='customerticketdetails'),
# PRODUCTS URL

@ -62,13 +62,20 @@ def customer_add_ticket(request, *args, **kwargs):
opened_date = datetime.now()
)
ticket.save()
ticket_status_update = TicketStatusUpdate(
ticket = ticket,
status = 'Open',
added_by = request.user,
date_added = datetime.now()
)
ticket_status_update.save()
for file in request.FILES.getlist('files'):
ticket_attachment = TicketAttachment(
ticket=ticket,
file=file
)
ticket_attachment.save()
return redirect('customertickets')
return redirect('customerticketdetails', ticket_number=ticket.ticket_number)
context = {
'customer_products': customer_products,
@ -79,6 +86,35 @@ def customer_add_ticket(request, *args, **kwargs):
return render(request, 'add_templates/customer-add-ticket.html', context)
@customer_login_required
def customer_add_ticket_update(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id)
if request.method == 'POST':
ticket_update = TicketUpdate(
ticket = ticket,
description = request.POST.get('description'),
added_by = request.user,
date_added = datetime.now(),
)
ticket_update.save()
for file in request.FILES.getlist('files'):
ticket_attachment = TicketAttachment(
ticket_update=ticket_update,
file=file
)
ticket_attachment.save()
return redirect('customerticketdetails', ticket_number=ticket.ticket_number)
context = {
'ticket': ticket,
}
return render(request, 'add_templates/customer-add-ticket.html', context)
# LISTING
@customer_login_required
@ -132,10 +168,16 @@ def customer_tickets(request, *args, **kwargs):
# DETAILS
def customer_ticket_details(request, *args, **kwargs):
def customer_ticket_details(request, ticket_number):
ticket = get_object_or_404(Ticket, ticket_number=ticket_number)
ticket_updates = TicketUpdate.objects.filter(ticket=ticket).order_by('id')
for update in ticket_updates:
if not TicketRead.objects.filter(ticket_update=update, user=request.user).exists():
TicketRead.objects.create(ticket_update=update, user=request.user, read=True)
context = {
'ticket': ticket,
'ticket_updates': ticket_updates,
}
return render(request, 'details_templates/inner-customer-ticket.html', context)

Binary file not shown.

@ -27,7 +27,8 @@ urlpatterns = [
path('reference/', views.add_reference_modal, name='addreferencemodal'),
path('tag/', views.add_tag_modal, name='addtagmodal'),
path('reaction/<int:status_id>/<str:emoji>/', views.add_reaction, name='add_reaction'),
path('add-ticket/<int:customer_id>/', views.add_ticket, name='addticket'),
path('ticket/<int:customer_id>/', views.add_ticket, name='addticket'),
path('ticketupdate/<int:ticket_id>/', views.add_ticket_update, name='addticketupdate'),
]

@ -8,6 +8,7 @@ from datetime import date
from django.http import JsonResponse
from osinacore.decorators import *
from billing.models import *
from customercore.models import *
@ -601,18 +602,90 @@ def add_reaction(request, status_id, emoji):
@staff_login_required
def add_ticket(request, customer_id):
customer= get_object_or_404(CustomerProfile, id=customer_id)
customer_products = OrderItem.objects.filter(order__status='Completed', active__in=[True, None], item__type='Product', order__customer=customer).values()
customer_products = OrderItem.objects.filter(order__status='Completed', active__in=[True, None], item__type='Product', order__customer=customer)
customer_projects = Project.objects.filter(customer=customer)
departments = Department.objects.all().order_by('name')
if request.method == 'POST':
project = None
product = None
department_id = request.POST.get('department')
department = get_object_or_404(Department, id=department_id)
regarding = 'General/Account/Billing'
if request.POST.get('project'):
project = get_object_or_404(Project, id=request.POST.get('project'))
department = project.project_type.department
regarding = 'Project/Product'
elif request.POST.get('product'):
product = get_object_or_404(Item, id=request.POST.get('product'))
department = product.item_type.department
regarding = 'Project/Product'
ticket = Ticket(
status = 'Open',
customer = customer,
title = request.POST.get('title'),
description = request.POST.get('description'),
regarding = regarding,
project = project,
product = product,
department = department,
opened_by = request.user,
opened_date = datetime.now()
)
ticket.save()
ticket_status_update = TicketStatusUpdate(
ticket = ticket,
status = 'Open',
added_by = request.user,
date_added = datetime.now()
)
ticket_status_update.save()
for file in request.FILES.getlist('files'):
ticket_attachment = TicketAttachment(
ticket=ticket,
file=file
)
ticket_attachment.save()
return redirect('ticketdetails', ticket_number=ticket.ticket_number)
context = {
'customer_products' : customer_products,
'customer_projects' : customer_projects,
'customer': customer,
'departments' : departments
}
return render(request, 'add_templates/add-ticket.html', context)
@staff_login_required
def add_ticket_update(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id)
if request.method == 'POST':
ticket_update = TicketUpdate(
ticket = ticket,
description = request.POST.get('description'),
added_by = request.user,
date_added = datetime.now(),
)
ticket_update.save()
for file in request.FILES.getlist('files'):
ticket_attachment = TicketAttachment(
ticket_update=ticket_update,
file=file
)
ticket_attachment.save()
return redirect('ticketdetails', ticket_number=ticket.ticket_number)
context = {
'ticket': ticket,
}
return render(request, 'add_templates/customer-add-ticket.html', context)

@ -8,7 +8,7 @@
Add Ticket for {{customer.user.first_name}} {{customer.user.last_name}}
</h1>
<form class="w-full flex flex-col gap-5 justify-center items-center mt-5" method="POST" action="">
<form class="w-full flex flex-col gap-5 justify-center items-center mt-5" method="POST" action="{% url 'addticket' customer.id %}" enctype="multipart/form-data">
{% csrf_token %}
<div class="w-full">
@ -19,7 +19,7 @@
<div class="w-full">
<label class="text-gray-500">What is this regarding?</label>
<select class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md mt-1"
<select name="regarding" class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md mt-1"
id="regardingSelectTag">
<option value="General/Account/Billing">General/Account/Billing</option>
<option value="Product">Product</option>
@ -28,26 +28,48 @@
</div>
<!-- Projects Select Tag -->
<select class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md hidden"
id="projectsSelectTag">
<option selected disabled>Choose one of your projects</option>
<div class="w-full hidden" id="projectsSelectTag">
<label class="text-gray-500">Choose one of {{customer.user.first_name}}'s projects:</label>
<select name="project" class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md mt-1">
{% if not customer_projects %}
<option value="" selected disabled>Select Project</option>
{% else %}
{% for customer_project in customer_projects %}
<option value="">{{customer_project.title}}</option>
<option value="{{customer_project.id}}">{{customer_project.title}}</option>
{% endfor %}
{% endif %}
</select>
</div>
<!-- Products Select Tag -->
<select class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md hidden"
id="productsSelectTag">
<option selected disabled>Choose one of your products</option>
<div class="w-full hidden" id="productsSelectTag">
<label class="text-gray-500">Choose one of {{customer.user.first_name}}'s products/subscriptions:</label>
<select name="product" class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md mt-1" >
{% if not customer_products %}
<option value="" selected disabled>Select Product</option>
{% else %}
{% for customer_product in customer_products %}
<option value="">{{customer_product.item.title}}</option>
<option value="{{customer_product.item.id}}">{{customer_product.item.title}}</option>
{% endfor %}
{% endif %}
</select>
</div>
<div class="w-full">
<label class="text-gray-500">Department:</label>
<select name="department" class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md mt-1" >
<option value="" selected disabled>Select Department</option>
{% for department in departments %}
<option value="{{department.id}}">{{department.name}}</option>
{% endfor %}
</select>
</div>
<div class="w-full">
<label class="text-gray-500">Desceription:</label>
<label class="text-gray-500">Description:</label>
<textarea required name="description"
class="w-full py-1 px-3 border border-gray-300 outline-none rounded-md mt-1 resize-none"
rows="8"></textarea>
@ -57,7 +79,7 @@
<label class="text-gray-500">Attach Files:</label>
<div class="inbox-box border border-gray-300 w-full rounded-md px-3 mt-1">
<div class="flex items-center justify-between">
<input name="" type="file" class="file-input" hidden multiple />
<input name="files" type="file" class="file-input" hidden multiple />
<span class="file-name text-gray-500 text-base focus:outline-none outline-none">Upload
Document(s)</span>
<label

@ -76,34 +76,34 @@
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Regarding
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Date Created
</th>
<th scope="col" class="px-6 py-3 text-sm font-medium text-gray-500 border-r border-gray-300 uppercase whitespace-nowrap">
Last Updated
</th>
<th scope="col" class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
<th scope="col" class="px-6 py-3 text-sm font-medium text-gray-500 border-r border-gray-300 uppercase whitespace-nowrap">
Updated By
</th>
<th scope="col" class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
Unread
</th>
</tr>
</thead>
<!-- TABLE BODY -->
{% for ticket in customer_open_tickets %}
<tbody class="bg-white divide-y divide-gray-200">
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a href="{% url 'customerticketdetails' %}">
<p class="text-secondosiblue cursor-pointer hover:text-gray-500 duration-300">My Account Balance</p>
<a href="{% url 'customerticketdetails' ticket.ticket_number %}">
<p class="text-secondosiblue cursor-pointer hover:text-gray-500 duration-300">{{ticket.title}}</p>
</a>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">22666766</p>
<p class="text-secondosiblue">{{ticket.ticket_number}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">Django</p>
<p class="text-secondosiblue">{{ticket.regarding}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
@ -111,73 +111,19 @@
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">20-2-2024</p>
</td>
<td class="px-6 py-4 text-center text-sm">
<p class="text-secondosiblue">Ositcom Ltd</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- INVOICESS -->
<div class="w-full h-fit bg-white rounded-md shadow-md p-5">
<h1 class="text-secondosiblue text-[25px]">Invoices</h1>
<div class="overflow-x-auto border border-gray-300 rounded-md mt-3">
<table class="min-w-full divide-y">
<!-- TABLE HEADER -->
<thead class="bg-gray-50">
<tr>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Due Date
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Title
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Description
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Status
</th>
<th scope="col" class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
Amount
</th>
</tr>
</thead>
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">20-2-2024</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">Invoice 1</p>
</td>
<td class="px-6 py-4 text-center items-center text-sm border-r border-gray-300 bg-secondosiblue">
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">Invoice description section</p>
</td>
<p class="text-white"> {{ticket.unread_updates_count}} </p>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300 bg-yellow-500">
<p class="text-white">Pending</p>
</td>
<td class="px-6 py-4 text-center text-sm">
<p class="text-secondosiblue">200</p>
</td>
<!-- {{ticket.unread_updates_count}} -->
</tr>
</tbody>
{% endfor %}
</table>
</div>
</div>
@ -185,7 +131,7 @@
<div class="w-full h-fit bg-white rounded-md shadow-md p-5">
<h1 class="text-secondosiblue text-[25px]">Other Ways to Get Help</h1>
<h1 class="text-secondosiblue text-[25px]">Ways to Get Help</h1>
<div class="w-full grid grid-cols-1 s:grid-cols-2 gap-5 mt-5">
<div class="flex flex-col gap-3 justify-center items-center bg-gray-50 border border-gray-100 shadow-md rounded-md px-5 py-10">

@ -28,7 +28,7 @@
<div class="w-full md:w-fit flex flex-col md:flex-row justify-end items-center gap-3">
<a href="{% url 'addticket' customer.id %}">
<button
class="w-full md:w-fit text-base px-3 py-2 bg-osiblue text-white outline-none border border-osiblue rounded-md cursor-pointer hover:bg-white hover:text-osiblue duration-300">Open
class="w-full md:w-fit text-base px-3 py-2 bg-osiblue text-white outline-none border border-osiblue rounded-md cursor-pointer hover:bg-white hover:text-osiblue duration-300">Add
Ticket</button>
</a>

@ -4,10 +4,10 @@
<div class="w-full xxlg1:w-[75%] bg-white h-fit rounded-md shadow-md p-5">
<div class="w-full h-fit flex flex-col gap-2 bg-gray-100 shadow-md rounded-md px-3 py-3">
<p class="text-secondosiblue text-xl">Ticket: <span class="font-semibold">#2226663535</span></p>
<p class="text-secondosiblue text-xl">Ticket: <span class="font-semibold">{{ticket.ticket_number}}</span></p>
<div class="flex justify-start items-center gap-1">
<div class="w-[16px] h-[16px] rounded-full bg-red-200 border border-red-500 shadow-md"></div>
<div class="w-[16px] h-[16px] rounded-full bg-red-200 shadow-md"></div>
<p class="text-secondosiblue font-light">Closed by Linode at 20-4-24 16:30</p>
</div>
</div>
@ -15,69 +15,40 @@
<div class="w-full flex flex-col gap-8 mt-5 s:mt-10">
<!-- REPLY 1 -->
{% for update in ticket_updates %}
<div class="flex gap-3">
<div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
<img src="{% static 'images/ositcom_logos/full-logo.png' %}"
{% if update.added_by.customerprofile %}
{% if update.added_by.customerprofile.image %}
<img src="{{update.added_by.customerprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
</div>
</div>
<div class="w-full replyContainer shadow-md">
{% else %}
<div
class="w-full bg-gray-100 flex justify-between items-center gap-3 px-3 py-3 cursor-pointer rounded-t-md toggleReply">
<p class="text-secondosiblue font-light text-sm s:text-base"><span class="font-semibold">Ositcom
Ltd</span>
commented 2024-04-17 12:19</p>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4 text-secondosiblue arrowUp">
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4 text-secondosiblue arrowDown hidden">
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg>
class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
<div class="w-full bg-white p-5 flex flex-col gap-3 reply">
<p class="text-gray-500 font-light leading-8 text-[15px]">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur
magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique
varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus
a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices
turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta
et purus. Aliquam at nunc sit amet tortor lacinia porttitor. Proin auctor, eros ac
sollicitudin iaculis, felis quam vulputate ante, eu varius dolor arcu non enim. Vestibulum
ornare dapibus risus, id eleifend ipsum. Aliquam metus urna, bibendum quis cursus vitae,
placerat sit amet felis. Aliquam tellus ex, pretium id gravida id, vulputate et velit.
Phasellus leo felis, lobortis ut dolor eget, viverra aliquet ligula. Aliquam molestie ac
eros et fermentum.
</p>
{% endif %}
{% elif update.added_by.staffprofile %}
{% if update.added_by.staffprofile.image %}
<img src="{{update.added_by.staffprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
{% else %}
<div
class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
{% endif %}
{% endif %}
</div>
</div>
<!-- CUSTOMER SUPPORT REPLY 2 -->
<div class="flex gap-3">
<div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
<img src="{% static 'images/netcommerce-logo.png' %}"
class="w-full h-full rounded-full object-cover">
</div>
</div>
<div class="w-full replyContainer shadow-md">
<div
class="w-full bg-gray-100 flex justify-between items-center gap-3 px-3 py-3 cursor-pointer rounded-t-md toggleReply">
<p class="text-secondosiblue font-light text-sm s:text-base"><span
class="font-semibold">Scott</span>
Customer Support commented 2024-04-17 12:19</p>
<p class="text-secondosiblue font-light text-sm s:text-base"><span class="font-semibold">{{update.added_by.first_name}}</span>
replied {{update.date_added}}</p>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-4 h-4 text-secondosiblue arrowUp">
@ -91,84 +62,79 @@
</svg>
</div>
<div class="w-full bg-white flex flex-col gap-5 p-5 reply">
<div class="w-full bg-white p-5 flex flex-col gap-3 reply">
<p class="text-gray-500 font-light leading-8 text-[15px]">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus non purus consectetur
magna sodales fringilla. Suspendisse non imperdiet metus. Curabitur feugiat tristique
varius. Curabitur fermentum sapien nisi, sed suscipit odio luctus sed. Mauris pretium risus
a tincidunt facilisis. Aliquam quis odio in mi aliquet scelerisque et ut urna. Ut ultrices
turpis odio, id hendrerit lectus dignissim in. Donec at tortor quis dui auctor sodales porta
et purus.
{{update.description}}
</p>
<div class="w-full border-t border-gray-200 pt-5 flex justify-start items-center gap-3">
<a class="text-secondosiblue font-light cursor-pointer hover:text-gray-500 duration-300">How
did I do?</a>
<div class="flex justify-start items-center gap-2">
<div class="w-fit h-fit rounded-full border-4 border-secondosiblue">
<img src="{% static 'images/icons/happy-icon.png' %}"
class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform">
</div>
<div class="w-fit h-fit rounded-full">
<img src="{% static 'images/icons/neutral-icon.png' %}"
class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform">
</div>
<div class="w-fit h-fit rounded-full">
<img src="{% static 'images/icons/unhappy-icon.png' %}"
class="w-[30px] h-[30px] rounded-full cursor-pointer hover:scale-105 duration-300 transition-transform">
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
<!-- REPLYING SECTION -->
<div class="flex gap-3">
<form class="flex gap-3" method="POST" action="{% url 'customeraddticketupdate' ticket.id %}" enctype="multipart/form-data">
{% csrf_token %}
<div>
<div class="w-[45px] s:w-[60px] h-[45px] s:h-[60px] rounded-full shadow-md border border-gray-100">
<img src="{% static 'images/ositcom_logos/full-logo.png' %}"
{% if request.user.customerprofile %}
{% if request.user.customerprofile.image %}
<img src="{{request.user.customerprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
{% else %}
<div
class="w-full h-full border border-secondosiblue bg-secondosiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
{% endif %}
{% elif request.user.staffprofile %}
{% if request.user.staffprofile.image %}
<img src="{{request.user.staffprofile.image.url}}"
class="w-full h-full rounded-full object-cover">
{% else %}
<div
class="w-full h-full border border-osiblue bg-osiblue text-white uppercase rounded-full flex justify-center items-center p-1 shadow-md">
{{ request.user.first_name.0 }}{{ request.user.last_name.0 }}
</div>
{% endif %}
{% endif %}
</div>
</div>
<div class="w-full flex flex-col gap-3">
<textarea
<textarea name="description"
class="w-full bg-white px-3 py-3 border border-gray-200 rounded-md outline-none text-gray-500 resize-none"
rows="8" placeholder="Reply to Ositcom Ltd..."></textarea>
rows="8" placeholder="Add Comment..."></textarea>
<div class="w-full flex flex-col s:flex-row justify-end items-center gap-3">
<div
class="w-full s:w-[50px] h-[50px] rounded-md bg-gray-50 shadow-md border border-gray-100 flex justify-center items-center p-2 cursor-pointer relative hover:scale-105 duration-300 transition-transform">
<div class="w-full s:w-[50px] h-[50px] rounded-md bg-gray-50 shadow-md border border-gray-100 flex justify-center items-center p-2 cursor-pointer relative hover:scale-105 duration-300 transition-transform">
<input type="file" name="file" id="fileInput" class="opacity-0">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
stroke="currentColor" class="w-5 h-5 text-secondosiblue z-10 absolute pointer-events-none">
<path stroke-linecap="round" stroke-linejoin="round"
d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13" />
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 text-secondosiblue z-10 absolute pointer-events-none">
<path stroke-linecap="round" stroke-linejoin="round" d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13" />
</svg>
</div>
<button
class="w-full s:w-fit bg-secondosiblue border border-secondosiblue text-gray-200 rounded-md cursor-pointer hover:bg-white hover:text-secondosiblue duration-300 px-9 py-3">
class="w-full s:w-fit bg-white border border-secondosiblue text-secondosiblue rounded-md cursor-pointer hover:bg-white hover:text-secondosiblue duration-300 px-9 py-3">
Send as Note
</button>
<button
class="w-full s:w-fit bg-gray-100 border border-secondosiblue text-secondosiblue hover:bg-secondosiblue hover:text-gray-200 rounded-md cursor-pointer duration-300 px-9 py-3">
Send as Reply
class="w-full s:w-fit bg-secondosiblue border border-secondosiblue text-white rounded-md cursor-pointer hover:bg-white hover:text-secondosiblue duration-300 px-9 py-3">
Send
</button>
</div>
</div>
</form>
</div>
</div>
</div>

@ -26,8 +26,8 @@
<div class="w-full flex flex-col gap-3 mt-5">
<div class="w-full bg-gray-200 rounded-md shadow-md h-fit p-3 flex items-center justify-between gap-5">
<div class="flex items-center gap-5 text-[17px]">
<p class="text-secondosiblue font-semibold cursor-pointer">Open Ticktes</p>
<p class="text-gray-500 cursor-pointer">Closed Ticktes</p>
<p class="text-secondosiblue font-semibold cursor-pointer">Open Tickets</p>
<p class="text-gray-500 cursor-pointer">Closed Tickets</p>
</div>
</div>
@ -49,10 +49,6 @@
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Regarding
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
Date Created
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 border-r border-gray-300 uppercase whitespace-nowrap">
Last Updated
@ -89,17 +85,13 @@
<p class="text-secondosiblue">20-2-2024</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">20-2-2024</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">Ositcom Ltd</p>
</td>
<td class="px-6 py-4 text-center text-sm">
<div class="flex justify-center items-center gap-3">
<a href="{% url 'ticketdetails' %}">
<a href="">
<div class="text-[15px] text-blue-500 cursor-pointer">
<i class="fa fa-eye"></i>
</div>

@ -54,7 +54,7 @@ urlpatterns = [
#Details Templates
path('customers/<str:customer_id>/', views.customerdetails, name='customerdetails'),
path('ticket-details/', views.ticket_details, name='ticketdetails'),
path('ticket/<str:ticket_number>/', views.ticket_details, name='ticketdetails'),
path('businesses/<str:business_id>/', views.businessdetails, name='businessdetails'),
path('staffs/<str:staff_id>/', views.staffdetails, name='userdetails'),
path('projectdetails/<str:project_id>/', views.projectdetails, name='detailed-project'),

@ -20,7 +20,7 @@ from django.core.mail import send_mail
from django.conf import settings
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from customercore .models import *
def login_with_email(request, email, key):
@ -451,9 +451,16 @@ def customerdetails(request, customer_id):
@staff_login_required
def ticket_details(request):
def ticket_details(request, ticket_number):
ticket = get_object_or_404(Ticket, ticket_number=ticket_number)
ticket_updates = TicketUpdate.objects.filter(ticket=ticket).order_by('id')
for update in ticket_updates:
if not TicketRead.objects.filter(ticket_update=update, user=request.user).exists():
TicketRead.objects.create(ticket_update=update, user=request.user, read=True)
context = {
'ticket' : ticket,
'ticket_updates': ticket_updates,
}

@ -1,5 +1,5 @@
/*
! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com
! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com
*/
/*
@ -32,11 +32,9 @@
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
6. Use the user's configured `sans` font-variation-settings by default.
7. Disable tap highlights on iOS
*/
html,
:host {
html {
line-height: 1.5;
/* 1 */
-webkit-text-size-adjust: 100%;
@ -46,14 +44,12 @@ html,
-o-tab-size: 4;
tab-size: 4;
/* 3 */
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
/* 4 */
font-feature-settings: normal;
/* 5 */
font-variation-settings: normal;
/* 6 */
-webkit-tap-highlight-color: transparent;
/* 7 */
}
/*
@ -125,10 +121,8 @@ strong {
}
/*
1. Use the user's configured `mono` font-family by default.
2. Use the user's configured `mono` font-feature-settings by default.
3. Use the user's configured `mono` font-variation-settings by default.
4. Correct the odd `em` font sizing in all browsers.
1. Use the user's configured `mono` font family by default.
2. Correct the odd `em` font sizing in all browsers.
*/
code,
@ -137,12 +131,8 @@ samp,
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
/* 1 */
font-feature-settings: normal;
/* 2 */
font-variation-settings: normal;
/* 3 */
font-size: 1em;
/* 4 */
/* 2 */
}
/*
@ -1406,7 +1396,7 @@ video {
}
.max-w-0 {
max-width: 0px;
max-width: 0rem;
}
.max-w-2xl {
@ -3225,6 +3215,11 @@ video {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.hover\:bg-gray-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
}
.hover\:bg-gray-50:hover {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
@ -3322,6 +3317,13 @@ video {
color: rgb(255 255 255 / var(--tw-text-opacity));
}
@media (prefers-color-scheme: dark) {
.dark\:text-gray-600 {
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity));
}
}
@media (min-width: 650px) {
.s\:mt-10 {
margin-top: 2.5rem;
@ -3823,10 +3825,3 @@ video {
font-size: 70px;
}
}
@media (prefers-color-scheme: dark) {
.dark\:text-gray-600 {
--tw-text-opacity: 1;
color: rgb(75 85 99 / var(--tw-text-opacity));
}
}

@ -17,6 +17,12 @@ selectRegarding.addEventListener('change', function() {
projectsSelectTag.classList.remove('hidden');
projectsSelectTag.required = true;
productsSelectTag.required = false;
productsSelectTag.classList.add('hidden');
} else if (selectedOption === 'General/Account/Billing') {
projectsSelectTag.classList.add('hidden');
projectsSelectTag.required = true;
productsSelectTag.required = false;
productsSelectTag.classList.add('hidden');
}

Loading…
Cancel
Save