New changes.

main
nataly 1 year ago
parent 3a9e201250
commit 902e5db0e3

Binary file not shown.

@ -0,0 +1,19 @@
# Generated by Django 4.2.5 on 2024-01-15 10:49
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0046_task_requirement'),
]
operations = [
migrations.AddField(
model_name='task',
name='status_date',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

@ -3,6 +3,7 @@ from django.contrib.auth.models import User
from colorfield.fields import ColorField
from datetime import datetime
from django.db.models import Max
from django.utils import timezone
# Create your models here.
@ -205,6 +206,7 @@ class Task(models.Model):
('Closed', 'Closed')
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
status_date = models.DateTimeField(default=timezone.now)
extra = models.BooleanField(default=False)
description = models.TextField()
start_date = models.CharField(max_length=200)
@ -219,6 +221,12 @@ class Task(models.Model):
max_id = Task.objects.aggregate(models.Max('task_id'))['task_id__max']
new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001' # If no existing records, start with '0001'
self.task_id = 'T' + current_year + new_id # Add 'p' prefix
if self.pk is not None:
original_task = Task.objects.get(pk=self.pk)
if original_task.status != self.status:
self.status_date = timezone.now()
super(Task, self).save(*args, **kwargs)
def formatted_start_date(self):

@ -6,7 +6,7 @@ from django.contrib import messages
from .forms import *
from django.utils import timezone
from django.urls import reverse
from django.http import HttpResponse
from django.http import HttpResponse, HttpResponseServerError, Http404
from django.db.models import Q
from django.http import JsonResponse
from .models import Task, Epic
@ -54,12 +54,11 @@ def home(request, *args, **kwargs):
if request.user.is_superuser:
# Superadmin can see the last 8 tasks for all users
tasks = Task.objects.filter(Q(status='Open') | Q(status='Working On')).order_by('-id')[:8]
tasks = Task.objects.filter(Q(status='Open') | Q(status='Working On')).order_by('-status_date', '-id')[:8]
else:
# Non-superadmin user can only see their assigned tasks
tasks = Task.objects.filter(Q(assigned_to=request.user.staffprofile) & (Q(status='Open') | Q(status='Working On'))).order_by('-id')
tasks = Task.objects.filter(Q(assigned_to=request.user.staffprofile) & (Q(status='Open') | Q(status='Working On'))).order_by('-status_date', '-id')
context = {
'notes': notes,
@ -98,10 +97,10 @@ def my_projects(request, *args, **kwargs):
def my_tasks(request, *args, **kwargs):
if request.user.is_superuser:
# Superadmin can see all projects
my_tasks = Task.objects.all().order_by('-id')
my_tasks = Task.objects.all().order_by('-status_date', '-id')
else:
# Non-superuser, filter projects where the user is either the manager or a member
my_tasks = Task.objects.all().filter(assigned_to=request.user.staffprofile).order_by('-id')
my_tasks = Task.objects.all().filter(Q(assigned_to=request.user.staffprofile)).order_by('-status_date', '-id')
context = {
'my_tasks' : my_tasks
@ -222,8 +221,8 @@ def detailed_project(request, project_id):
epics = Epic.objects.filter(project=project)
latest_epic = Epic.objects.filter(project=project).last()
# if latest_epic:
# epics = epics.exclude(pk=latest_epic.pk)
if latest_epic:
epics = epics.exclude(pk=latest_epic.pk)
selected_epic_id = request.GET.get('epic_id')
@ -536,7 +535,7 @@ def status_mobile_modal (request, *args, **kwargs):
#Fetch EPIC RELATED TASKS
#FETCH EPIC RELATED TASKS
def get_tasks (request, epic_id):
epic = get_object_or_404(Epic, id=epic_id)
related_tasks = Task.objects.filter(epic_id=epic).order_by('-id')
@ -549,6 +548,32 @@ def get_tasks (request, epic_id):
return render(request, 'epic-fetched-tasks.html', context)
# TO FETCH THE LATEST EPIC AND ITS TASKS
def get_latest_epic(request, project_id):
try:
project = get_object_or_404(Project, id=project_id)
latest_epic = Epic.objects.filter(project=project).order_by('-id').first()
if latest_epic:
related_tasks = Task.objects.filter(epic=latest_epic)
else:
related_tasks = []
context = {
'latest_epic': latest_epic,
'related_tasks': related_tasks,
}
return render(request, 'epic-fetched-tasks.html', context)
except Http404:
# Handle case where the specified project does not exist
return HttpResponseServerError("Project not found")
except Exception as e:
# Log the error or return a specific error response
print(f"An error occurred: {str(e)}")
return HttpResponseServerError("Internal Server Error")

@ -51,6 +51,7 @@ urlpatterns = [
#Detail pages urls
path('businesses/<str:business_id>/', views.businessdetails, name='businessdetails'),
path('customers/<str:customer_id>/', views.customerdetails, name='customerdetails'),
@ -63,6 +64,7 @@ urlpatterns = [
#Fetch urls
path('get_tasks/<int:epic_id>/', views.get_tasks, name='get_tasks'),
path('get_latest_epic/<int:project_id>/', views.get_latest_epic, name='get_latest_epic'),
#Modals urls

@ -610,6 +610,12 @@ video {
}
}
@media (min-width: 1600px) {
.container {
max-width: 1600px;
}
}
@media (min-width: 1750px) {
.container {
max-width: 1750px;
@ -981,10 +987,6 @@ video {
width: 25%;
}
.w-\[250px\] {
width: 250px;
}
.w-\[25px\] {
width: 25px;
}
@ -1025,6 +1027,10 @@ video {
width: 45px;
}
.w-\[50\%\] {
width: 50%;
}
.w-\[50px\] {
width: 50px;
}
@ -1262,6 +1268,10 @@ video {
overflow-y: auto;
}
.overflow-x-scroll {
overflow-x: scroll;
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
@ -1284,6 +1294,10 @@ video {
border-radius: 0.375rem;
}
.rounded-none {
border-radius: 0px;
}
.rounded-b-md {
border-bottom-right-radius: 0.375rem;
border-bottom-left-radius: 0.375rem;
@ -2351,6 +2365,14 @@ video {
height: 150px;
}
.md\:h-\[70px\] {
height: 70px;
}
.md\:w-\[160px\] {
width: 160px;
}
.md\:w-\[300px\] {
width: 300px;
}
@ -2359,6 +2381,38 @@ video {
width: -moz-fit-content;
width: fit-content;
}
.md\:flex-row {
flex-direction: row;
}
.md\:py-1 {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
}
@media (min-width: 960px) {
.l\:w-\[160px\] {
width: 160px;
}
.l\:w-\[300px\] {
width: 300px;
}
.l\:w-\[50\%\] {
width: 50%;
}
.l\:w-fit {
width: -moz-fit-content;
width: fit-content;
}
.l\:flex-row {
flex-direction: row;
}
}
@media (min-width: 1110px) {
@ -2373,10 +2427,6 @@ video {
.lg\:hidden {
display: none;
}
.lg\:w-\[75\%\] {
width: 75%;
}
}
@media (min-width: 1200px) {
@ -2384,9 +2434,25 @@ video {
position: fixed;
}
.xlg1\:block {
display: block;
}
.xlg1\:hidden {
display: none;
}
.xlg1\:w-\[300px\] {
width: 300px;
}
.xlg1\:w-\[74\.5\%\] {
width: 74.5%;
}
.xlg1\:w-\[75\%\] {
width: 75%;
}
}
@media (min-width: 1300px) {
@ -2416,3 +2482,36 @@ video {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
@media (min-width: 1536px) {
.xl\:w-\[250px\] {
width: 250px;
}
.xl\:w-fit {
width: -moz-fit-content;
width: fit-content;
}
.xl\:flex-row {
flex-direction: row;
}
}
@media (min-width: 1600px) {
.xll\:mt-1 {
margin-top: 0.25rem;
}
.xll\:flex {
display: flex;
}
.xll\:hidden {
display: none;
}
.xll\:rounded-none {
border-radius: 0px;
}
}

@ -1,41 +1,14 @@
const epicSelect = document.getElementById('epicSelect');
const epicDetails = document.getElementById('epicDetails');
const epicRelatedTasks = document.getElementById('epicRelatedTasks');
const editEpicButton = document.getElementById('editEpicButton');
const createTaskButton = document.getElementById('createTaskButton');
const createStoryButton = document.getElementById('createStoryButton');
const latestEpicDetails = document.getElementById('latestEpicDetails');
epicSelect.addEventListener('change', function () {
if (this.value !== 'EPICS') {
epicDetails.classList.remove('hidden');
epicDetails.classList.add('flex');
epicRelatedTasks.classList.remove('hidden');
editEpicButton.classList.remove('cursor-not-allowed', 'opacity-30');
editEpicButton.classList.add('cursor-pointer');
editEpicButton.removeAttribute('disabled');
createTaskButton.classList.remove('cursor-not-allowed', 'opacity-30');
createTaskButton.classList.add('cursor-pointer');
createTaskButton.removeAttribute('disabled');
createStoryButton.classList.remove('cursor-not-allowed', 'opacity-30');
createStoryButton.classList.add('cursor-pointer');
createStoryButton.removeAttribute('disabled');
latestEpicDetails.classList.add('hidden');
} else {
epicDetails.classList.add('hidden');
epicRelatedTasks.classList.add('hidden');
editEpicButton.classList.add('cursor-not-allowed', 'opacity-30');
editEpicButton.setAttribute('disabled', true);
createTaskButton.classList.add('cursor-not-allowed', 'opacity-30');
createTaskButton.setAttribute('disabled', true);
createStoryButton.classList.add('cursor-not-allowed', 'opacity-30');
createStoryButton.setAttribute('disabled', true);
}
});

@ -30,6 +30,39 @@ $(document).ready(function () {
}
});
// TO FETCH THE LATEST EPIC BY DEFAULT
var projectId = $("#projectId").text().trim();
function fetchLatestEpicTasks(projectId) {
$.ajax({
type: "GET",
url: "/get_latest_epic/" + projectId + "/",
success: function (data) {
var latestEpicId = data.latest_epic ? data.latest_epic.id : null;
if (latestEpicId) {
// Fetch related tasks based on the latest epic
fetchRelatedTasks(latestEpicId);
} else {
// console.log("No latest epic found.");
}
$("#epicRelatedTasksContainer").html(data);
},
error: function (xhr, status, error) {
console.log("Ajax call failed. Error details:");
console.log("XHR Object:", xhr);
console.log("Status:", status);
console.log("Error:", error);
}
});
}
fetchLatestEpicTasks(projectId);
$('#epicSelect').change(function () {
var selectedEpic = $(this).find(':selected');
var startDate = selectedEpic.data('start-date');

@ -0,0 +1,18 @@
// TO OPEN ACTION BUTTONS CONTAINER IN TASKS CONTAINER ON MOBILE
document.addEventListener('DOMContentLoaded', function () {
var actionsButtons = document.querySelectorAll('.actionsButton');
actionsButtons.forEach(function (button) {
button.addEventListener('click', function () {
var arrowDown = button.querySelector('.fa-angle-down');
var arrowUp = button.querySelector('.fa-angle-up');
arrowDown.style.display = arrowDown.style.display === 'none' ? 'inline-block' : 'none';
arrowUp.style.display = arrowUp.style.display === 'none' ? 'inline-block' : 'none';
var actionsContainer = button.nextElementSibling;
actionsContainer.classList.toggle('hidden');
actionsContainer.classList.toggle('grid');
});
});
});

@ -20,6 +20,7 @@ module.exports = {
xxlg1: '1350px',
xxlg: '1390px',
xl: '1536px',
xll: '1600px',
xxl: '1750px',
k: '2400px',
},

@ -2,70 +2,85 @@
{%load static%}
{% block content %}
<style>
/* TO APPLY HOVER EFFECT ON THE CREATE TASK AND STORY BUTTONS WHEN THEY ARE NOT :disabled ANYMORE */
.epicButtons:not([disabled]):hover {
background-color: transparent;
color: #3b82f6;
/* Blue-500 color */
}
</style>
<div class="w-[55px] h-[55px] bg-slate-700 rounded-full fixed xlg1:hidden bottom-3 right-3 p-2 flex justify-center items-center cursor-pointer usersActivityIcon z-20"
data-modal-url="{% url 'getupdatedactivities' %}">
<img src="{% static 'images/usersactivity.png' %}" alt="Users">
</div>
<!-- NOTES SECTION -->
<div class="w-full h-fit flex justify-between items-center px-10 pb-5">
<div class="relative w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex justify-between items-center">
<div>
<div class="w-full px-5 s:px-9 pb-5">
<div class="w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex flex-col s:flex-row justify-between gap-3 s:gap-0 items-center">
<div class="w-full s:w-fit">
<p class="text-base text-gray-500">Recent Note:</p>
<p class="text-slate-700">Send an Email to Salim.</p>
<div class="flex justify-start items-center gap-2">
<div class="w-[13px] h-[13px] bg-red-200 rounded-full"
style="background-color: {{ last_note_color }};">
</div>
<p class="text-slate-700">{{recent_note.text}}</p>
</div>
<div class="flex justify-end items-center gap-4">
</div>
<div class="w-full s:w-fit flex justify-start s:justify-end items-center gap-4">
<button
class="w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
class="w-full s:w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
id="showNotesButton">Show
Notes</button>
<button
class="w-[35px] h-[35px] rounded-full p-2 bg-gray-300 text-white text-[20px] outline-none border-none cursor-pointer flex justify-center items-center shadow-md"
id="addNoteButton" data-modal-url="{% url 'addnote' %}">
class="w-[35px] h-[35px] rounded-full p-2 bg-gray-300 text-white text-[20px] outline-none border-none cursor-pointer flex justify-center items-center shadow-md addNoteButton"
data-modal-url="{% url 'addnote' %}">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
<!-- ALL NOTES CONTAINER (it appears when clicking on the "Show notes" button) -->
<div class="w-full h-fit relative hidden justify-start gap-3 items-center mt-5 overflow-hidden overflow-x-auto"
id="notesContainer">
<div class="w-[16.33%] h-[150px] shadow-xl bg-yellow-200 p-5">
<p class="text-base text-slate-800">Send an Email to Salim.</p>
</div>
<div class="w-full h-fit hidden mt-5" id="notesContainer">
<div class="w-[16.33%] h-[150px] shadow-xl bg-pink-200 top-90 right-10 p-5">
<p class="text-base text-slate-80">Contact the client.</p>
<div class="w-full hidden lg:grid grid-cols-3 xlg:grid-cols-6 gap-3">
{% for note in notes %}
<div class="h-[150px] shadow-sm p-5" style="background-color: {{note.color}}">
<p class="text-base text-slate-800">{{note.text}}</p>
</div>
<div class="w-[16.33%] h-[150px] shadow-xl bg-green-200 top-90 right-10 p-5">
<p class="text-base text-slate-80">Add daily report at the end of the day.</p>
{% endfor %}
</div>
<div class="w-[16.33%] h-[150px] shadow-xl bg-blue-200 top-90 right-10 p-5">
<p class="text-base text-slate-80">Add daily report at the end of the day.</p>
<div class="w-full black lg:hidden">
<div class="swiper-container mt-5">
<div class="swiper-wrapper">
{% for note in notes %}
<div class="swiper-slide">
<div class="w-full h-[150px] p-3 flex justify-start items-start"
style="background-color: {{note.color}}">
{{note.text}}
</div>
</div>
{% endfor %}
</div>
<div class="w-[16.33%] h-[150px] shadow-xl bg-purple-200 top-90 right-10 p-5">
<p class="text-base text-slate-80">Add daily report at the end of the day.</p>
<div class="flex justify-center items-center gap-3 mt-5">
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderLeft">
<i class="fa fa-angle-left"></i>
</div>
<div class="w-[16.33%] h-[150px] shadow-xl bg-yellow-200 top-90 right-10 p-5">
<p class="text-base text-slate-80">Add daily report at the end of the day.</p>
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderRight">
<i class="fa fa-angle-right"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- PROJECT DETAIL AND USERS ACTIVITY SECTION -->
<div class="w-full flex justify-between gap-[2.5%] px-10 pb-5">
<div class="w-full flex justify-between gap-5 px-5 s:px-9 pb-5">
<!-- LEFT SIDE / PROJECT DETAIL SECTION -->
<div class="w-[74.5%] bg-white h-fit rounded-md shadow-md p-5">
<div class="w-full xlg1:w-[74.5%] bg-white h-fit rounded-md shadow-md p-5">
{% if project.status == 'Completed' %}
<div class="w-full bg-green-700 rounded-t-md flex flex-col justify-center items-center py-2">
<h1 class="text-3xl text-white font-semibold">{{project.name}}</h1>
@ -90,33 +105,46 @@
<p class="text-white text-base">{{project.project_id}}</p>
</div>
{% endif %}
<div class="w-full rounded-b-md flex xll:hidden items-center">
<button
class="w-[50%] text-base px-3 py-2 bg-red-500 text-white outline-none border border-red-500 rounded-bl-md cursor-pointer hover:bg-white hover:text-red-500">Delete
Project</button>
<a href="{% url 'editproject' project.project_id %}" class="w-[50%]">
<button
class="w-full text-base px-3 py-2 bg-blue-500 text-white outline-none border border-blue-500 rounded-br-md cursor-pointer hover:bg-white hover:text-blue-500">Edit
Project</button>
</a>
</div>
<p id="projectId" class="hidden">{{project.id}}</p>
<!-- PROJECT PROGRESS BAR -->
<div class="w-full h-[10px] bg-gray-100 shadow-md mt-1 mainBar">
<div class="h-full progressBar">
<div class="w-full h-[10px] bg-gray-100 shadow-md mt-3 xll:mt-1 mainBar rounded-md xll:rounded-none">
<div class="h-full rounded-md xll:rounded-none progressBar">
</div>
</div>
<div class="w-full h-[70px] flex justify-between items-center bg-gray-100 shadow-md rounded-md px-3 py-1 mt-4">
<div class="flex justify-start items-center gap-3">
<a href="{% url 'createepic' project.project_id %}">
<div
class="w-full h-fit md:h-[70px] flex justify-between items-center bg-gray-100 shadow-md rounded-md px-3 py-3 md:py-1 mt-4">
<div class="w-full md:w-fit flex flex-col md:flex-row justify-start items-center gap-3">
<a href="{% url 'createepic' project.project_id %}" class="w-full md:w-fit">
<button
class="w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
Epic</button>
</a>
<a href="{% url 'createtaskproject' project.project_id %}">
<a href="{% url 'createtaskproject' project.project_id %}" class="w-full md:w-fit">
<button
class="w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
Task</button>
</a>
<button
class="w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
Story</button>
<button
class="w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
Milestone</button>
</div>
<div class="flex justify-end items-center gap-3">
<div class="hidden xll:flex justify-end items-center gap-3">
<button
class="w-fit text-base px-3 py-2 bg-red-500 text-white outline-none border border-red-500 rounded-md cursor-pointer hover:bg-white hover:text-red-500">Delete
Project</button>
@ -127,6 +155,7 @@
</a>
</div>
</div>
<div class="w-full flex flex-col gap-4 mt-5">
<div>
<p class="text-gray-500 text-xl">Client: <span
@ -199,10 +228,9 @@
</div>
<!-- REQUIREMENTS -->
<!-- USER STORIES -->
<div class="w-full mt-5">
<div class="overflow-x-auto border border-gray-300 rounded-md mt-5" id="customersContainer">
<div class="overflow-x-auto border border-gray-300 rounded-md mt-5">
<div
class=" bg-slate-700 border border-slate-700 rounded-t-md flex justify-between items-center text-white text-xl font-bold h-[50px]">
<div class="px-3">
@ -236,6 +264,7 @@
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<!-- 1st row -->
{% if project.projectrequirement_set.all %}
{% for requirement in project.projectrequirement_set.all %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
@ -266,71 +295,22 @@
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!-- RELATED FILES -->
<div class="w-full mt-5">
<div class="overflow-x-auto border border-gray-300 rounded-md mt-5" id="customersContainer">
<div
class=" bg-slate-700 border border-slate-700 rounded-t-md flex justify-between items-center text-white text-xl font-bold h-[50px]">
<div class="px-3">
<p class="text-white uppercase font-bold">Related files</p>
</div>
<button
class="h-full rounded-tr-md px-4 bg-gray-300 text-slate-700 text-[18px] outline-none border-none cursor-pointer flex justify-center items-center addFileButton"
data-modal-url="{% url 'addfile' %}">
<i class="fa fa-plus"></i>
</button>
</div>
<table class="min-w-full divide-y">
<!-- TABLE HEADER -->
<thead class="bg-gray-50">
{% else %}
<tr>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
File Name
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
File
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
Date Entered
</th>
</tr>
</thead>
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<!-- 1st row -->
{% for file in project.projectfile_set.all %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-slate-800">{{file.name}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a class="text-slate-800">{{file.file}}</a>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a class="text-slate-800">{{file.date}}</a>
<td colspan="3" class="px-6 py-4 text-center text-sm text-slate-800">
No Requirements at the moment
</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
</div>
<!-- CREDENTIALS -->
<div class="w-full mt-5">
<div class="overflow-x-auto border border-gray-300 rounded-md mt-5" id="customersContainer">
<div class="mt-5 relative">
<div
class=" bg-slate-700 border border-slate-700 rounded-t-md flex justify-between items-center text-white text-xl font-bold h-[50px]">
<div class="px-3">
@ -343,6 +323,8 @@
<i class="fa fa-plus"></i>
</button>
</div>
<div class="overflow-x-auto border border-gray-300 rounded-b-md">
<table class="min-w-full divide-y">
<!-- TABLE HEADER -->
<thead class="bg-gray-50">
@ -365,6 +347,7 @@
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<!-- 1st row -->
{% if project.projectcredential_set.all %}
{% for credential in project.projectcredential_set.all %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
@ -380,11 +363,19 @@
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="3" class="px-6 py-4 text-center text-sm text-slate-800">
No Available Credentials
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
<!-- TAGS -->
<div>
<p class="text-gray-500 text-xl mt-5">Tags:</p>
@ -405,37 +396,45 @@
<!-- RELATED TASK CONTAINER BASED ON THE CHOSEN EPIC -->
<div class="w-full mt-5">
<div class="w-full bg-slate-300 rounded-md shadow-md h-fit p-5 flex justify-between items-center">
<div>
<div
class="w-full bg-slate-300 rounded-md shadow-md h-fit p-5 flex flex-col l:flex-row justify-between items-center gap-3">
<div class="w-full l:w-[50%] xl:w-fit">
<select id="epicSelect" name="epic_id"
class="w-[250px] rounded-md border border-gray-300 p-3 outline-none text-gray-500 cursor-pointer">
<option selected disabled>EPICS</option>
class="w-full xl:w-[250px] rounded-md border border-gray-300 p-3 outline-none text-gray-500 cursor-pointer">
<option selected value="{{latest_epic.id}}" data-start-date="{{ latest_epic.start_date }}"
data-end-date="{{ latest_epic.end_date }}">{{latest_epic.title}}</option>
{% for epic in epics %}
<option class="epic-link" value="{{ epic.id }}" data-start-date="{{ epic.start_date }}"
data-end-date="{{ epic.end_date }}">{{epic.title}}</option>
{% endfor %}
</select>
</div>
<div class="w-fit flex justify-end items-center gap-2">
<div class="w-fit justify-start items-center gap-2 hidden" id="epicDetails">
<div class="w-full l:w-[50%] xl:w-fit flex flex-col xl:flex-row justify-end items-center gap-2">
<div class="w-fit justify-start items-center gap-2" id="epicDetails">
<span id="startDate" class="text-gray-500 font-light"></span>
<span id="endDate" class="text-gray-500 font-light"></span>
</div>
<div class="w-fit flex justify-end items-center gap-2">
<div class="w-fit justify-start items-center gap-2" id="latestEpicDetails">
<span class="text-gray-500 font-light">{{latest_epic.start_date}}</span>
<span class="text-gray-500 font-light">{{latest_epic.end_date}}</span>
</div>
<div class="w-full xl:w-fit flex flex-col xl:flex-row justify-end items-center gap-2">
<!-- <a href="{% url 'createepic' project.project_id %}">
<button
class="w-fit bg-blue-500 border border-blue-500 text-white text-base py-2 px-3 rounded-md hover:bg-transparent hover:text-blue-500 duration-300">Create
Epic</button>
</a> -->
<a href="{% url 'editepic' %}">
<a href="{% url 'editepic' %}" class="w-full xl:w-fit">
<button id="editEpicButton"
class="w-fit bg-blue-500 border border-blue-500 text-white text-base py-2 px-3 rounded-md cursor-not-allowed opacity-30 duration-300 epicButtons"
class="w-full xl:w-fit bg-blue-500 border border-blue-500 text-white cursor-pointer hover:bg-white hover:text-blue-500 text-base py-2 px-3 rounded-md"
disabled>View
Epic</button>
</a>
<a href="{% url 'createtaskepic' %}">
<a href="{% url 'createtaskepic' %}" class="w-full xl:w-fit">
<button id="createTaskButton"
class="w-fit bg-blue-500 border border-blue-500 text-white text-base py-2 px-3 rounded-md cursor-not-allowed opacity-30 duration-300 epicButtons"
class="w-full xl:w-fit bg-blue-500 border border-blue-500 text-white cursor-pointer hover:bg-white hover:text-blue-500 text-base py-2 px-3 rounded-md duration-300"
disabled>Create
Task</button>
</a>
@ -454,7 +453,7 @@
<!-- RIGHT SIDE / USERS ACTIVITY -->
<div class="w-[23%] bg-white h-fit rounded-md shadow-md p-5">
<div class="hidden xlg1:block w-[25%] bg-white h-fit rounded-md shadow-md p-5">
<h1 class="text-2xl text-slate-700 text-center font-semibold">USERS ACTIVITY</h1>
<div class="w-full h-fit mt-2" id="activitiesContainer">

@ -1,6 +1,9 @@
{% load static %}
<!-- TASKS ON DESKTOP -->
<div class="hidden md:block">
<!-- TASKS TABLE -->
{% for task in related_tasks %}
<div class="w-full h-fit bg-white p-3 rounded-md shadow-md mb-5">
<div class="w-full bg-white h-fit rounded-md border border-gray-200">
@ -12,14 +15,9 @@
</div>
<div class="grid grid-cols-3">
{% if task.status == 'Closed' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<p>{{task.status}}</p>
</div>
{% endif %}
@ -31,14 +29,9 @@
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700">
<p>{{task.formatted_start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<p>{{task.formatted_start_date}}</p>
</div>
{% endif %}
@ -50,13 +43,6 @@
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700 rounded-tr-md">
<p>{{task.formatted_end_date}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div
class="flex justify-center items-center border-b border-gray-200 text-white bg-red-500 rounded-tr-md">
@ -114,18 +100,21 @@
<!-- RIGHT SIDE OF TABLE BODY -->
<div class="h-fit bg-white grid grid-cols-3 rounded-br-md">
<button class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500">Close</button>
<button
class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500">Close</button>
<button
class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 updateStatusButton"
data-modal-url="{% url 'updatestatus' task.task_id %}">Update
Status</button>
<button class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 addTimeButton"
<button
class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 addTimeButton"
data-modal-url="{% url 'addtime' %}">Add
Time</button>
<button class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 deleteTaskButton"
<button
class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 deleteTaskButton"
data-modal-url="{% url 'deletetask' %}">Delete</button>
<a href="{% url 'edittask' task.task_id %}">
@ -133,11 +122,13 @@
class="w-full p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500">Edit</button>
</a>
<button class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 showPointsButton"
<button
class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 showPointsButton"
data-modal-url="{% url 'showpoints' task.task_id %}">Show
Points</button>
<button class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 addPointButton"
<button
class="p-2 border border-gray-200 text-base h-[70px] bg-gray-100 text-gray-500 addPointButton"
data-modal-url="{% url 'addpoint' task.task_id %}">Add
Point</button>
@ -154,3 +145,142 @@
</div>
</div>
{% endfor %}
</div>
<!-- TASKS ON MOBILE -->
<div class="block md:hidden">
{% for task in related_tasks %}
<div class="w-full h-fit bg-white p-3 rounded-md shadow-md mb-5">
<div class="border border-gray-200 rounded-t-md">
<div class="w-full rounded-t-md">
{% if task.status == 'Open' %}
<div
class="w-full flex justify-center items-center text-white text-center bg-red-500 rounded-t-md py-5 px-3">
<p>{{task.name}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div
class="w-full flex justify-center items-center text-white text-center bg-orange-500 rounded-t-md py-5 px-3">
<p>{{task.name}}</p>
</div>
{% endif %}
</div>
<div class="grid grid-cols-3 border-t border-gray-200">
{% if task.status == 'Open' %}
<div
class="text-white bg-red-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div
class="text-white bg-orange-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div
class="text-white bg-red-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div
class="text-white bg-orange-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div class="text-white bg-red-500 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.end_date}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div class="text-white bg-orange-500 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.end_date}}</p>
</div>
{% endif %}
</div>
<div class="w-full flex flex-col gap-2 p-3">
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Project:</p>
<p class="text-slate-700 text-base">{{task.project.name}}</p>
</div>
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Epic:</p>
<p class="text-slate-700 text-base">{{task.epic.title}}</p>
</div>
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Assigned To:</p>
<p class="text-slate-700 text-base">{{task.assigned_to.user.first_name}}
{{task.assigned_to.user.last_name}}</p>
</div>
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Extra:</p>
<p class="text-slate-700 text-base">{{task.extra}}</p>
</div>
</div>
<div class="w-full bg-gray-100 flex justify-between items-center py-3 px-3 text-slate-700 actionsButton">
<p>Actions</p>
<i class="fa fa-angle-down" style="font-size: 20px;"></i>
<i class="fa fa-angle-up" style="font-size: 20px; display: none;"></i>
</div>
<div class="grid-cols-3 actionsContainer hidden">
<button class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500">Close</button>
<button class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 updateStatusButton"
data-modal-url="{% url 'updatestatus' task.task_id %}">Update
Status</button>
<button class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 addTimeButton"
data-modal-url="{% url 'addtime' %}">Add
Time</button>
<button class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 deleteTaskButton"
data-modal-url="{% url 'deletetask' %}">Delete</button>
<a href="{% url 'edittask' task.task_id %}">
<button
class="w-full p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500">Edit</button>
</a>
<button class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 showPointsButton"
data-modal-url="{% url 'showpoints' task.task_id %}">Show
Points</button>
<button class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 addPointButton"
data-modal-url="{% url 'addpoint' task.task_id %}">Add
Point</button>
<a href="{% url 'detailed-task' task.task_id %}">
<button
class="w-full p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500">Details</button>
</a>
<button class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 timelineButton"
data-modal-url="{% url 'timeline' %}">Timeline</button>
</div>
</div>
</div>
{% endfor %}
</div>

@ -3,7 +3,7 @@
{% block content %}
<div class="w-[55px] h-[55px] bg-slate-700 rounded-full fixed lg:hidden bottom-3 right-3 p-2 flex justify-center items-center cursor-pointer usersActivityIcon z-20"
<div class="w-[55px] h-[55px] bg-slate-700 rounded-full fixed xlg1:hidden bottom-3 right-3 p-2 flex justify-center items-center cursor-pointer usersActivityIcon z-20"
data-modal-url="{% url 'getupdatedactivities' %}">
<img src="{% static 'images/usersactivity.png' %}" alt="Users">
</div>
@ -80,7 +80,7 @@
<!-- TASKS AND USERS ACTIVITY SECTION -->
<div class="w-full flex justify-between gap-5 px-5 s:px-9 pb-5">
<!-- LEFT SIDE / TASKS SECTION -->
<div class="w-full lg:w-[75%]">
<div class="w-full xlg1:w-[75%]">
<!-- TASKS ON DESKTOP -->
<div class="hidden md:block">
@ -498,26 +498,6 @@
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
var actionsButtons = document.querySelectorAll('.actionsButton');
actionsButtons.forEach(function (button) {
button.addEventListener('click', function () {
var arrowDown = button.querySelector('.fa-angle-down');
var arrowUp = button.querySelector('.fa-angle-up');
arrowDown.style.display = arrowDown.style.display === 'none' ? 'inline-block' : 'none';
arrowUp.style.display = arrowUp.style.display === 'none' ? 'inline-block' : 'none';
var actionsContainer = button.nextElementSibling;
actionsContainer.classList.toggle('hidden');
actionsContainer.classList.toggle('grid');
});
});
});
</script>
<!-- RIGHT SIDE / USERS ACTIVITY -->
<div class="hidden lg:block w-[25%] bg-white h-fit rounded-md shadow-md p-5">
<h1 class="text-2xl text-slate-700 text-center font-semibold">USERS ACTIVITY</h1>

@ -1,11 +1,17 @@
{% extends "main.html" %}
{%load static%}
{% block content %}
<div class="w-[55px] h-[55px] bg-slate-700 rounded-full fixed xlg1:hidden bottom-3 right-3 p-2 flex justify-center items-center cursor-pointer usersActivityIcon z-20"
data-modal-url="{% url 'getupdatedactivities' %}">
<img src="{% static 'images/usersactivity.png' %}" alt="Users">
</div>
<!-- NOTES SECTION -->
<div class="w-full h-fit flex justify-between items-center px-10 pb-5">
<div class="relative w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex justify-between items-center">
<div>
<div class="w-full px-5 s:px-9 pb-5">
<div class="w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex flex-col s:flex-row justify-between gap-3 s:gap-0 items-center">
<div class="w-full s:w-fit">
<p class="text-base text-gray-500">Recent Note:</p>
<div class="flex justify-start items-center gap-2">
<div class="w-[13px] h-[13px] bg-red-200 rounded-full"
@ -15,9 +21,9 @@
<p class="text-slate-700">{{recent_note.text}}</p>
</div>
</div>
<div class="flex justify-end items-center gap-4">
<div class="w-full s:w-fit flex justify-start s:justify-end items-center gap-4">
<button
class="w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
class="w-full s:w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
id="showNotesButton">Show
Notes</button>
<button
@ -29,43 +35,71 @@
</div>
<!-- ALL NOTES CONTAINER (it appears when clicking on the "Show notes" button) -->
<div class="w-full h-fit relative hidden justify-start gap-3 items-center mt-5 overflow-hidden overflow-x-auto"
id="notesContainer">
<div class="w-full h-fit hidden mt-5" id="notesContainer">
<div class="w-full hidden lg:grid grid-cols-3 xlg:grid-cols-6 gap-3">
{% for note in notes %}
<div class="w-[16.33%] h-[150px] shadow-sm p-5" style="background-color: {{note.color}}">
<div class="h-[150px] shadow-sm p-5" style="background-color: {{note.color}}">
<p class="text-base text-slate-800">{{note.text}}</p>
</div>
{% endfor %}
</div>
<div class="w-full black lg:hidden">
<div class="swiper-container mt-5">
<div class="swiper-wrapper">
{% for note in notes %}
<div class="swiper-slide">
<div class="w-full h-[150px] p-3 flex justify-start items-start"
style="background-color: {{note.color}}">
{{note.text}}
</div>
</div>
{% endfor %}
</div>
<div class="flex justify-center items-center gap-3 mt-5">
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderLeft">
<i class="fa fa-angle-left"></i>
</div>
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderRight">
<i class="fa fa-angle-right"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- DAILY REPORTS USERS ACTIVITY SECTION -->
<div class="w-full flex justify-between gap-[2.5%] px-10 pb-5">
<div class="w-full flex justify-between gap-5 px-5 s:px-9 pb-5">
<!-- LEFT SIDE / USERS SECTION -->
<div class="w-[74.5%]">
<div class="w-full xlg1:w-[75%]">
<div class="w-full h-fit bg-white rounded-md shadow-md p-5">
<h1 class="text-slate-800 text-[30px] font-semibold">Daily Report</h1>
<!-- FILTERING -->
<div class="w-full py-4 px-3 bg-gray-200 rounded-md shadow-md mt-4 flex justify-between items-center">
<div class="flex justify-start items-center gap-5">
<div class="relative h-fit w-fit flex items-center">
<div
class="w-full py-4 px-3 bg-gray-200 rounded-md shadow-md mt-4 flex flex-col l:flex-row justify-between gap-3 items-center">
<div class="w-full l:w-fit flex justify-start items-center gap-5">
<div class="relative h-fit w-full l:w-fit flex items-center">
<input type="text" placeholder="Enter Staff Username"
class="py-2 px-3 border border-gray-300 rounded-md outline-none w-[300px] h-[40px] relative">
class="py-2 px-3 border border-gray-300 rounded-md outline-none w-full l:w-[300px] h-[40px] relative">
<button
class="text-gray-500 text-xl outline-none border-none cursor-pointer absolute right-2 bg-white">
<i class="fa fa-search"></i>
</button>
</div>
</div>
<div>
<a href="{% url 'adddailyreport' %}">
<div class="w-full l:w-fit">
<a href="{% url 'adddailyreport' %}" class="w-full l:w-fit">
<button
class="w-fit text-base px-3 py-2 bg-blue-500 text-white outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white hover:text-blue-500">Add
class="w-full l:w-fit text-base px-3 py-2 bg-blue-500 text-white outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white hover:text-blue-500">Add
Daily Report</button>
</a>
</div>
@ -74,20 +108,29 @@
<!-- DAILY REPORTS -->
{% for report in dailyreports %}
<div class="mt-5 w-full h-fit">
<div class="w-full border-x border-t border-gray-300 rounded-t-md ">
<div class="daily-report w-full border-x border-t border-gray-300 rounded-t-md ">
<!-- TABLE HEADER -->
<div
class="w-full flex justify-between items-center h-[60px] border-b border-gray-300 rounded-t-md">
<div class="w-full h-full flex justify-start items-center px-4">
<p class="text-slate-800 text-xl">Report By <span
class="text-blue-500 font-semibold">{{report.staff.user.first_name}}
{{report.user.staff.last_name}}</span> On <span
class="text-blue-500 font-semibold">{{report.date}}</span></p>
class="w-full flex justify-between items-center h-fit border-b border-gray-300 rounded-t-md px-4 py-3">
<div class="w-fit h-full flex justify-start items-center">
<p class="text-slate-800 text-base s:text-xl font-light"><span
class="uppercase font-semibold text-blue-500">{{report.staff.user.first_name}}
{{report.user.staff.last_name}}</span> {{report.date}} - {{report.time}}</p>
</div>
<div>
<button
class="showReportButton w-fit h-fit px-3 py-2 bg-green-700 text-white border border-green-700 cursor-pointer hover:bg-white hover:text-green-700 rounded-md shadow-md">
<i class="fa fa-arrow-down"></i>
</button>
<button
class="w-fit h-fit px-3 py-2 bg-blue-500 text-white border border-blue-500 cursor-pointer hover:bg-white hover:text-blue-500 rounded-md shadow-md">
<i class="fa fa-print"></i>
</button>
</div>
</div>
<!-- TABLE BODY -->
<div class="w-full">
<div class="w-full hidden reportContainer">
<!-- 1st row -->
<div class="w-full h-fit flex justify-between items-center border-b border-gray-300">
<div class="w-full h-full p-5 text-gray-500">
@ -99,13 +142,33 @@
</div>
{% endfor %}
<script>
document.addEventListener("DOMContentLoaded", function () {
// Get references to all showReportButton and reportContainer elements
var showReportButtons = document.querySelectorAll(".showReportButton");
// Iterate through each button and attach the click event
showReportButtons.forEach(function (button) {
button.addEventListener("click", function () {
// Find the related reportContainer based on the button's parent
var reportContainer = button.closest(".daily-report").querySelector(".reportContainer");
// Toggle the visibility of the report container
reportContainer.classList.toggle("hidden");
});
});
});
</script>
</div>
</div>
<!-- RIGHT SIDE / USERS ACTIVITY -->
<div class="w-[23%] bg-white h-fit rounded-md shadow-md p-5">
<div class="hidden xlg1:block w-[25%] bg-white h-fit rounded-md shadow-md p-5">
<h1 class="text-2xl text-slate-700 text-center font-semibold">USERS ACTIVITY</h1>
<div class="w-full h-fit mt-2" id="activitiesContainer">

@ -2,11 +2,18 @@
{%load static%}
{% block title %}My Projects{% endblock %}
{% block content %}
<div class="w-[55px] h-[55px] bg-slate-700 rounded-full fixed xlg1:hidden bottom-3 right-3 p-2 flex justify-center items-center cursor-pointer usersActivityIcon z-20"
data-modal-url="{% url 'getupdatedactivities' %}">
<img src="{% static 'images/usersactivity.png' %}" alt="Users">
</div>
<!-- NOTES SECTION -->
<div class="w-full h-fit flex justify-between items-center px-10 pb-5">
<div class="relative w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex justify-between items-center">
<div>
<div class="w-full px-5 s:px-9 pb-5">
<div class="w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex flex-col s:flex-row justify-between gap-3 s:gap-0 items-center">
<div class="w-full s:w-fit">
<p class="text-base text-gray-500">Recent Note:</p>
<div class="flex justify-start items-center gap-2">
<div class="w-[13px] h-[13px] bg-red-200 rounded-full"
@ -16,9 +23,9 @@
<p class="text-slate-700">{{recent_note.text}}</p>
</div>
</div>
<div class="flex justify-end items-center gap-4">
<div class="w-full s:w-fit flex justify-start s:justify-end items-center gap-4">
<button
class="w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
class="w-full s:w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
id="showNotesButton">Show
Notes</button>
<button
@ -30,32 +37,59 @@
</div>
<!-- ALL NOTES CONTAINER (it appears when clicking on the "Show notes" button) -->
<div class="w-full h-fit relative hidden justify-start gap-3 items-center mt-5 overflow-hidden overflow-x-auto"
id="notesContainer">
<div class="w-full h-fit hidden mt-5" id="notesContainer">
<div class="w-full hidden lg:grid grid-cols-3 xlg:grid-cols-6 gap-3">
{% for note in notes %}
<div class="w-[16.33%] h-[150px] shadow-sm p-5" style="background-color: {{note.color}}">
<div class="h-[150px] shadow-sm p-5" style="background-color: {{note.color}}">
<p class="text-base text-slate-800">{{note.text}}</p>
</div>
{% endfor %}
</div>
<div class="w-full black lg:hidden">
<div class="swiper-container mt-5">
<div class="swiper-wrapper">
{% for note in notes %}
<div class="swiper-slide">
<div class="w-full h-[150px] p-3 flex justify-start items-start"
style="background-color: {{note.color}}">
{{note.text}}
</div>
</div>
{% endfor %}
</div>
<div class="flex justify-center items-center gap-3 mt-5">
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderLeft">
<i class="fa fa-angle-left"></i>
</div>
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderRight">
<i class="fa fa-angle-right"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- PROJECTS AND USERS ACTIVITY SECTION -->
<div class="w-full flex justify-between gap-[2.5%] px-10 pb-5">
<div class="w-full flex justify-between gap-5 px-5 s:px-9 pb-5">
<!-- LEFT SIDE / PROJECTS SECTION -->
<div class="w-[74.5%]">
<div class="w-full xlg1:w-[75%]">
<div class="w-full h-fit bg-white rounded-md shadow-md p-5">
<h1 class="text-slate-800 text-[30px] font-semibold">My Projects</h1>
<!-- PROJECT FILTERING -->
<div class="w-full py-4 px-3 bg-gray-200 rounded-md shadow-md mt-4 flex justify-between items-center">
<div class="flex justify-start items-center gap-3">
<div class="relative h-fit w-fit flex items-center">
<div class="w-full py-4 px-3 bg-gray-200 rounded-md shadow-md mt-4 flex flex-col md:flex-row justify-between items-center gap-3">
<div class="w-full md:w-fit flex flex-col md:flex-row justify-start items-center gap-3">
<div class="relative h-fit w-full md:w-fit flex items-center">
<input type="text" placeholder="Enter Project Name"
class="py-2 px-3 border border-gray-300 rounded-md outline-none w-[300px] h-[40px] relative">
class="py-2 px-3 border border-gray-300 rounded-md outline-none w-full md:w-[300px] h-[40px] relative">
<button
class="text-gray-500 text-xl outline-none border-none cursor-pointer absolute right-2 bg-white">
<i class="fa fa-search"></i>
@ -63,24 +97,24 @@
</div>
<select name="" id=""
class="border border-gray-300 p-2 rounded-md outline-none w-[160px] text-gray-500 h-[40px]">
class="border border-gray-300 p-2 rounded-md outline-none w-full md:w-[160px] text-gray-500 h-[40px]">
<option value="" disabled selected>Status</option>
<option value="">Open</option>
<option value="">Working On</option>
<option value="">Closed</option>
</select>
</div>
<div>
<a href="{% url 'createproject' %}">
<div class="w-full md:w-fit">
<a href="{% url 'createproject' %}" class="w-full md:w-fit">
<button
class="w-fit text-base px-3 py-2 bg-blue-500 text-white outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white hover:text-blue-500">Create
class="w-full md:w-fit text-base px-3 py-2 bg-blue-500 text-white outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white hover:text-blue-500">Create
Project</button>
</a>
</div>
</div>
<div class="overflow-x-auto border border-gray-300 rounded-md mt-5" id="customersContainer">
<div class="overflow-x-auto border border-gray-300 rounded-md mt-5">
<table class="min-w-full divide-y">
<!-- TABLE HEADER -->
<thead class="bg-gray-50">
@ -177,7 +211,7 @@
</div>
<!-- RIGHT SIDE / USERS ACTIVITY -->
<div class="w-[23%] bg-white h-fit rounded-md shadow-md p-5">
<div class="hidden xlg1:block w-[25%] bg-white h-fit rounded-md shadow-md p-5">
<h1 class="text-2xl text-slate-700 text-center font-semibold">USERS ACTIVITY</h1>
<div class="w-full h-fit mt-2" id="activitiesContainer">

@ -1,11 +1,17 @@
{% extends "main.html" %}
{%load static%}
{% block content %}
<div class="w-[55px] h-[55px] bg-slate-700 rounded-full fixed xlg1:hidden bottom-3 right-3 p-2 flex justify-center items-center cursor-pointer usersActivityIcon z-20"
data-modal-url="{% url 'getupdatedactivities' %}">
<img src="{% static 'images/usersactivity.png' %}" alt="Users">
</div>
<!-- NOTES SECTION -->
<div class="w-full h-fit flex justify-between items-center px-10 pb-5">
<div class="relative w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex justify-between items-center">
<div>
<div class="w-full px-5 s:px-9 pb-5">
<div class="w-full h-fit bg-white shadow-md rounded-md p-5">
<div class="w-full flex flex-col s:flex-row justify-between gap-3 s:gap-0 items-center">
<div class="w-full s:w-fit">
<p class="text-base text-gray-500">Recent Note:</p>
<div class="flex justify-start items-center gap-2">
<div class="w-[13px] h-[13px] bg-red-200 rounded-full"
@ -15,9 +21,9 @@
<p class="text-slate-700">{{recent_note.text}}</p>
</div>
</div>
<div class="flex justify-end items-center gap-4">
<div class="w-full s:w-fit flex justify-start s:justify-end items-center gap-4">
<button
class="w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
class="w-full s:w-fit rounded-md py-1 px-3 bg-slate-800 border border-slate-800 text-white hover:bg-white hover:text-slate-800"
id="showNotesButton">Show
Notes</button>
<button
@ -29,32 +35,59 @@
</div>
<!-- ALL NOTES CONTAINER (it appears when clicking on the "Show notes" button) -->
<div class="w-full h-fit relative hidden justify-start gap-3 items-center mt-5 overflow-hidden overflow-x-auto"
id="notesContainer">
<div class="w-full h-fit hidden mt-5" id="notesContainer">
<div class="w-full hidden lg:grid grid-cols-3 xlg:grid-cols-6 gap-3">
{% for note in notes %}
<div class="w-[16.33%] h-[150px] shadow-sm p-5" style="background-color: {{note.color}}">
<div class="h-[150px] shadow-sm p-5" style="background-color: {{note.color}}">
<p class="text-base text-slate-800">{{note.text}}</p>
</div>
{% endfor %}
</div>
<div class="w-full black lg:hidden">
<div class="swiper-container mt-5">
<div class="swiper-wrapper">
{% for note in notes %}
<div class="swiper-slide">
<div class="w-full h-[150px] p-3 flex justify-start items-start"
style="background-color: {{note.color}}">
{{note.text}}
</div>
</div>
{% endfor %}
</div>
<div class="flex justify-center items-center gap-3 mt-5">
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderLeft">
<i class="fa fa-angle-left"></i>
</div>
<div class="w-[35px] h-[35px] bg-slate-700 b rounded-md text-white flex justify-center items-center text-[18px] cursor-pointer z-10"
id="sliderRight">
<i class="fa fa-angle-right"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- TASKS AND USERS ACTIVITY SECTION -->
<div class="w-full flex justify-between gap-[2.5%] px-10 pb-5">
<div class="w-full flex justify-between gap-5 px-5 s:px-9 pb-5">
<!-- LEFT SIDE / TASKS SECTION -->
<div class="w-[74.5%]">
<div class="w-full xlg1:w-[75%]">
<div class="w-full h-fit bg-white rounded-md shadow-md p-5">
<h1 class="text-slate-800 text-[30px] font-semibold">My Tasks</h1>
<!-- TASK FILTERING -->
<div class="w-full py-4 px-3 bg-gray-200 rounded-md shadow-md mt-4 flex justify-between items-center">
<div class="flex justify-start items-center gap-3">
<div class="relative h-fit w-fit flex items-center">
<div class="w-full py-4 px-3 bg-gray-200 rounded-md shadow-md mt-4 flex flex-col l:flex-row justify-between gap-3 items-center">
<div class="w-full l:w-fit flex flex-col l:flex-row justify-start items-center gap-3">
<div class="relative h-fit w-full l:w-fit flex items-center">
<input type="text" placeholder="Enter Project Name"
class="py-2 px-3 border border-gray-300 rounded-md outline-none w-[300px] h-[40px] relative">
class="py-2 px-3 border border-gray-300 rounded-md outline-none w-full l:w-[300px] h-[40px] relative">
<button
class="text-gray-500 text-xl outline-none border-none cursor-pointer absolute right-2 bg-white">
<i class="fa fa-search"></i>
@ -62,7 +95,7 @@
</div>
<select name="" id=""
class="border border-gray-300 p-2 rounded-md outline-none w-[160px] text-gray-500 h-[40px]">
class="border border-gray-300 p-2 rounded-md outline-none w-full l:w-[160px] text-gray-500 h-[40px]">
<option value="" disabled selected>Status</option>
<option value="">Open</option>
<option value="">Working On</option>
@ -70,7 +103,7 @@
</select>
<select name="" id=""
class="border border-gray-300 p-2 rounded-md outline-none w-[160px] text-gray-500 h-[40px]">
class="border border-gray-300 p-2 rounded-md outline-none w-full l:w-[160px] text-gray-500 h-[40px]">
<option value="" disabled selected>Assigned To</option>
<option value="">Nataly</option>
<option value="">Salim</option>
@ -78,19 +111,18 @@
<option value="">Arze</option>
</select>
</div>
<div>
<a href="{% url 'createtask' %}">
<div class="w-full l:w-fit">
<a href="{% url 'createtask' %}" class="w-full l:w-fit">
<button
class="w-fit text-base px-3 py-2 bg-blue-500 text-white outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white hover:text-blue-500">Create
class="w-full l:w-fit text-base px-3 py-2 bg-blue-500 text-white outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white hover:text-blue-500">Create
Task</button>
</a>
</div>
</div>
<!-- ALL TASKS -->
<div class="w-full mt-10">
<!-- TASKS ON DESKTOP -->
<div class="hidden md:block mt-5">
<!-- TASKS TABLE -->
{% for task in my_tasks %}
<div class="w-full h-fit bg-white p-3 rounded-md shadow-md mb-5">
<div class="w-full bg-white h-fit rounded-md border border-gray-200">
@ -102,57 +134,65 @@
</div>
<div class="grid grid-cols-3">
{% if task.status == 'Closed' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-orange-500">
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-orange-500">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700">
<p>{{task.formatted_start_date}}</p>
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-red-500">
<p>{{task.formatted_start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-orange-500">
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-orange-500">
<p>{{task.formatted_start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700 rounded-tr-md">
<p>{{task.formatted_end_date}}</p>
<div
class="flex justify-center items-center border-r border-b border-gray-200 text-white bg-green-700">
<p>{{task.formatted_start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div class="flex justify-center items-center border-b border-gray-200 text-white bg-red-500 rounded-tr-md">
<div
class="flex justify-center items-center border-b border-gray-200 text-white bg-red-500 rounded-tr-md">
<p>{{task.formatted_end_date}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div class="flex justify-center items-center border-b border-gray-200 text-white bg-orange-500 rounded-tr-md">
<div
class="flex justify-center items-center border-b border-gray-200 text-white bg-orange-500 rounded-tr-md">
<p>{{task.formatted_end_date}}</p>
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div
class="flex justify-center items-center border-b border-gray-200 text-white bg-green-700 rounded-tr-md">
<p>{{task.formatted_end_date}}</p>
</div>
{% endif %}
@ -245,14 +285,188 @@
</div>
</div>
{% endfor %}
</div>
<!-- TASKS ON MOBILE -->
<div class="block md:hidden mt-5">
{% for task in my_tasks %}
<div class="w-full h-fit bg-white p-3 rounded-md shadow-md mb-5">
<div class="border border-gray-200 rounded-t-md">
<div class="w-full rounded-t-md">
{% if task.status == 'Open' %}
<div
class="w-full flex justify-center items-center text-white text-center bg-red-500 rounded-t-md py-5 px-3">
<p>{{task.name}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div
class="w-full flex justify-center items-center text-white text-center bg-orange-500 rounded-t-md py-5 px-3">
<p>{{task.name}}</p>
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div
class="w-full flex justify-center items-center text-white text-center bg-green-700 rounded-t-md py-5 px-3">
<p>{{task.name}}</p>
</div>
{% endif %}
</div>
<div class="grid grid-cols-3 border-t border-gray-200">
{% if task.status == 'Closed' %}
<div
class="text-white bg-green-700 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div
class="text-white bg-red-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div
class="text-white bg-orange-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.status}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div
class="text-white bg-red-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div
class="text-white bg-orange-500 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div
class="text-white bg-green-700 border-r border-gray-200 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.start_date}}</p>
</div>
{% endif %}
{% if task.status == 'Open' %}
<div
class="text-white bg-red-500 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.end_date}}</p>
</div>
{% endif %}
{% if task.status == 'Working On' %}
<div
class="text-white bg-orange-500 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.end_date}}</p>
</div>
{% endif %}
{% if task.status == 'Closed' %}
<div
class="text-white bg-green-700 flex justify-center items-center text-center py-3 text-sm">
<p>{{task.end_date}}</p>
</div>
{% endif %}
</div>
<div class="w-full flex flex-col gap-2 p-3">
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Project:</p>
<p class="text-slate-700 text-base">{{task.project.name}}</p>
</div>
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Epic:</p>
<p class="text-slate-700 text-base">{{task.epic.title}}</p>
</div>
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Assigned To:</p>
<p class="text-slate-700 text-base">{{task.assigned_to.user.first_name}}
{{task.assigned_to.user.last_name}}</p>
</div>
<div class="flex justify-start items-center gap-2">
<p class="text-gray-400 text-base">Extra:</p>
<p class="text-slate-700 text-base">{{task.extra}}</p>
</div>
</div>
<div
class="w-full bg-gray-100 flex justify-between items-center py-3 px-3 text-slate-700 actionsButton">
<p>Actions</p>
<i class="fa fa-angle-down" style="font-size: 20px;"></i>
<i class="fa fa-angle-up" style="font-size: 20px; display: none;"></i>
</div>
<div class="grid-cols-3 actionsContainer hidden">
<button
class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500">Close</button>
<button
class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 updateStatusButton"
data-modal-url="{% url 'updatestatus' task.task_id %}">Update
Status</button>
<button
class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 addTimeButton"
data-modal-url="{% url 'addtime' %}">Add
Time</button>
<button
class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 deleteTaskButton"
data-modal-url="{% url 'deletetask' %}">Delete</button>
<a href="{% url 'edittask' task.task_id %}">
<button
class="w-full p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500">Edit</button>
</a>
<button
class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 showPointsButton"
data-modal-url="{% url 'showpoints' task.task_id %}">Show
Points</button>
<button
class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 addPointButton"
data-modal-url="{% url 'addpoint' task.task_id %}">Add
Point</button>
<a href="{% url 'detailed-task' task.task_id %}">
<button
class="w-full p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500">Details</button>
</a>
<button
class="p-2 border border-gray-200 text-sm h-[70px] bg-gray-100 text-gray-500 timelineButton"
data-modal-url="{% url 'timeline' %}">Timeline</button>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<!-- RIGHT SIDE / USERS ACTIVITY -->
<div class="w-[23%] bg-white h-fit rounded-md shadow-md p-5">
<div class="hidden xlg1:block w-[25%] bg-white h-fit rounded-md shadow-md p-5">
<h1 class="text-2xl text-slate-700 text-center font-semibold">USERS ACTIVITY</h1>
<div class="w-full h-fit mt-2" id="activitiesContainer">

@ -360,6 +360,10 @@
<!-- TO RELOAD THE USERS ACTIVITY CONTAINER -->
<script type="text/javascript" src='{% static "js/get-updated-user-activity.js" %}'></script>
<!-- TO OPEN TASKS ACTIONS BUTTONS CONTAINER ON MOBILE -->
<script type="text/javascript" src='{% static "js/tasks.js" %}'></script>
</body>
</html>
Loading…
Cancel
Save