Add IntelliJ IDEA project configuration files

This commit adds IntelliJ IDEA-specific configuration files for the project, including module setup, version control integration, inspection profiles, and workspace settings. These files facilitate development environment configuration for contributors using IntelliJ IDEA.
master
kikimor 8 months ago
parent 72e0fc963c
commit daba5a8438

@ -31,13 +31,16 @@ ALLOWED_HOSTS = []
# Application definition
PROJECT_APPS = [
"common",
'accounts',
"booking",
"common",
"containers",
'preinfo',
]
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
@ -101,7 +104,9 @@ DATABASES = {
# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
# AUTH_USER_MODEL = 'users.CustomUser'
AUTH_USER_MODEL = 'accounts.DepotUser'
LOGIN_URL = '/user/login/'
AUTH_PASSWORD_VALIDATORS = [
{
@ -118,6 +123,9 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
]
# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/

@ -14,12 +14,14 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
# from django.contrib import admin
from django.urls import path, include
urlpatterns = [
# path("admin/", admin.site.urls),
path("admin/", admin.site.urls),
path('', include('common.urls')),
path('user/', include('users.urls')),
path('user/', include('accounts.urls')),
path('preinfo/', include('preinfo.urls')),
path('container/', include('containers.urls')),
]

@ -0,0 +1,34 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import DepotUser
@admin.register(DepotUser)
class DepotUserAdmin(UserAdmin):
# Add your custom fields to the fieldsets
fieldsets = UserAdmin.fieldsets + (
('Additional Info', {'fields': (
'phone_number',
'company',
'line',
'company_permissions',
'new_field1',
'is_company_admin',
)}),
)
# Add fields to display in list view
list_display = UserAdmin.list_display + ('phone_number', 'company', 'line', 'is_company_admin')
# Add fields to the add form
add_fieldsets = UserAdmin.add_fieldsets + (
('Additional Info', {'fields': (
'email',
'phone_number',
'company',
'line',
'company_permissions',
'new_field1',
'is_company_admin',
)}),
)

@ -3,4 +3,4 @@ from django.apps import AppConfig
class UsersConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "users"
name = "accounts"

@ -0,0 +1,16 @@
from django.contrib.auth.backends import ModelBackend
class CompanyUserBackend(ModelBackend):
def get_user_permissions(self, user_obj, obj=None):
if not user_obj.is_active or user_obj.is_anonymous:
return set()
if user_obj.is_superuser:
return super().get_user_permissions(user_obj, obj)
perms = super().get_user_permissions(user_obj, obj)
if user_obj.company and user_obj.company.is_client:
# Filter permissions based on client company context
perms = {p for p in perms if p.startswith('accounts.client_')}
return perms

@ -0,0 +1,7 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
field_order = ['username', 'password']
class Meta:
model = get_user_model()

@ -0,0 +1,44 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
class ClientPermission(models.Model):
class Meta:
managed = True
default_permissions = ()
permissions = (
('can_book_container', 'Can book container'),
('can_view_bookings', 'Can view bookings'),
('can_manage_company_users', 'Can manage company users'),
)
class DepotUser(AbstractUser):
phone_number = models.CharField(max_length=15, blank=True, null=True)
email = models.EmailField(unique=True, blank=False, null=False)
company = models.ForeignKey(
'common.CompanyModel',
on_delete=models.CASCADE,
related_name='user_lines',
blank=True,
null=True
)
line = models.ForeignKey(
'common.LinesModel',
on_delete=models.CASCADE,
related_name='user_lines',
blank=True,
null=True
)
company_permissions = models.ManyToManyField('ClientPermission')
new_field1 = models.BooleanField(default=False)
is_company_admin = models.BooleanField(default=False)
def has_company_perm(self, perm_codename):
if self.is_superuser:
return True
return self.company_permissions.filter(
codename=perm_codename,
is_client_permission=self.company
).exists()

@ -0,0 +1,8 @@
from django.urls import path
from django.contrib.auth import views as auth_views
from accounts import views
urlpatterns = [
path('login/', views.DepotLoginView.as_view(), name='login'),
path('relogin/', auth_views.logout_then_login, name='relogin'),
]

@ -0,0 +1,17 @@
from django.contrib.auth.views import LoginView
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import TemplateView, FormView
from accounts.forms import LoginForm
# Create your views here.
class DepotLoginView(LoginView):
template_name = 'registration/login.html'
# success_url = reverse_lazy('dashboard')
form_class = LoginForm
next_page = reverse_lazy('dashboard')

@ -1,61 +0,0 @@
# Generated by Django 5.2.3 on 2025-06-25 12:33
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("common", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="BookingModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("number", models.CharField(max_length=50, unique=True)),
("vehicles", models.CharField(blank=True, null=True)),
("container_count", models.IntegerField()),
("carrier", models.CharField(blank=True, max_length=100, null=True)),
("visible", models.BooleanField(default=True)),
("is_new", models.BooleanField(default=True)),
(
"container_number",
models.CharField(blank=True, max_length=11, null=True),
),
("vehicles_left", models.IntegerField(blank=True, null=True)),
("created_on", models.DateTimeField(auto_now_add=True)),
("created_by", models.IntegerField()),
("updated_on", models.DateTimeField(auto_now=True)),
("updated_by", models.IntegerField()),
(
"container_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="booking_container_types",
to="common.containertypemodel",
),
),
(
"line",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="booking_lines",
to="common.linesmodel",
),
),
],
),
]

@ -1,5 +1,5 @@
from django.db import models
from common.models import ContainerTypeModel, LinesModel, OperationModel, PayerModel
from common.models import ContainerTypeModel, LinesModel, OperationModel
# Create your models here.
class BookingModel(models.Model):

@ -1,3 +1,14 @@
from django.shortcuts import render
from django.views.generic import CreateView
# Create your views here.
class CreateBookingView(CreateView):
template_name = 'create-booking.html'
extra_context = {
'title': 'Create Booking',
'description': 'This is the create booking page.',
}
def get(self, request, *args, **kwargs):
return render(request, self.template_name, self.extra_context)

@ -1,132 +0,0 @@
# Generated by Django 5.2.3 on 2025-06-25 12:33
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="ContainerKindModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=100, unique=True)),
("short_name", models.CharField(max_length=5, unique=True)),
("description", models.TextField(blank=True, null=True)),
],
options={
"ordering": ["name"],
"abstract": False,
},
),
migrations.CreateModel(
name="OperationModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=100, unique=True)),
("short_name", models.CharField(max_length=5, unique=True)),
("description", models.TextField(blank=True, null=True)),
],
options={
"ordering": ["name"],
"abstract": False,
},
),
migrations.CreateModel(
name="PayerModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=100, unique=True)),
("short_name", models.CharField(max_length=5, unique=True)),
("description", models.TextField(blank=True, null=True)),
],
options={
"ordering": ["name"],
"abstract": False,
},
),
migrations.CreateModel(
name="ContainerTypeModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=6, unique=True)),
("length", models.IntegerField()),
("height", models.BooleanField()),
("deleted", models.BooleanField(default=False)),
(
"container_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="container_type_container_kinds",
to="common.containerkindmodel",
),
),
],
),
migrations.CreateModel(
name="LinesModel",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=100, unique=True)),
("short_name", models.CharField(max_length=5, unique=True)),
("description", models.TextField(blank=True, null=True)),
(
"payer",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="line_payers",
to="common.payermodel",
),
),
],
options={
"ordering": ["name"],
"abstract": False,
},
),
]

@ -3,7 +3,7 @@ from django.db import models
# Create your models here.
class NomenclatureBaseModel(models.Model):
name = models.CharField(max_length=100, unique=True)
short_name = models.CharField(max_length=5, unique=True)
short_name = models.CharField(max_length=5, null=True, blank=True)
description = models.TextField(blank=True, null=True)
class Meta:
@ -13,14 +13,16 @@ class NomenclatureBaseModel(models.Model):
def __str__(self):
return self.name
class PayerModel(NomenclatureBaseModel):
class CompanyModel(NomenclatureBaseModel):
...
class LinesModel(NomenclatureBaseModel):
payer = models.ForeignKey(
PayerModel,
company = models.ForeignKey(
'common.CompanyModel',
on_delete=models.CASCADE,
related_name='line_payers'
related_name='line_company'
)
class OperationModel(NomenclatureBaseModel):
@ -34,8 +36,11 @@ class ContainerTypeModel(models.Model):
length = models.IntegerField()
height = models.BooleanField()
container_type = models.ForeignKey(
ContainerKindModel,
'common.ContainerKindModel',
on_delete=models.CASCADE,
related_name='container_type_container_kinds'
)
deleted = models.BooleanField(default=False)
def __str__(self):
return self.name

@ -4,6 +4,7 @@ from common import views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('client/dashboard/', views.ClientDashboardView.as_view(), name='client_dashboard'),
path ('client/preinfo/', views.ClientPreinfoView.as_view(), name='client_preinfo'),
path('barrier/dashboard/', views.BarrierDashboardView.as_view(), name='barrier_dashboard'),
path('dashboard/', views.DashboardRedirectView.as_view(), name='dashboard'),
]

@ -0,0 +1,39 @@
from containers.models import Container
from preinfo.models import Preinfo
def filter_queryset_by_user(queryset, user):
"""
Filters the queryset based on the user's line or company.
If the user has a line, it filters by that line.
If the user has a company, it filters by all lines associated with that company.
"""
if user.line:
return queryset.filter(line=user.line)
elif user.company:
company_lines = user.company.line_company.all()
return queryset.filter(line__in=company_lines)
return queryset
def get_preinfo_by_number(number):
"""
Retrieves a PreinfoModel instance by its container number.
Returns None if no matching PreinfoModel is found.
"""
try:
return Preinfo.objects.get(container_number=number, received=False)
except Preinfo.DoesNotExist:
return None
def get_container_by_number(number):
"""
Retrieves a Container instance by its number.
Returns None if no matching Container is found.
"""
try:
return Container.objects.get(number=number, expedited=False)
except Container.DoesNotExist:
return None

@ -1,6 +1,6 @@
from django.urls import reverse_lazy
from django.views.generic import TemplateView, RedirectView
from django.shortcuts import render, redirect
from django.shortcuts import render
# Create your views here.
@ -20,13 +20,18 @@ class DashboardRedirectView(RedirectView):
is_permanent = False
def get_redirect_url(self, *args, **kwargs):
if 1==1:
return reverse_lazy('client_dashboard')
return reverse_lazy('client_dashboard')
# if self.request.user.is_authenticated:
if self.request.user.username == 'client':
return reverse_lazy('client_dashboard')
elif self.request.user.username == 'clientadmin':
return reverse_lazy('client_dashboard')
elif self.request.user.username == 'barrier':
return reverse_lazy('barrier_dashboard')
return reverse_lazy('index')
class ClientDashboardView(TemplateView):
template_name = 'client-dashboard.html'
template_name = 'client-dashboard-content.html'
extra_context = {
'title': 'Client Dashboard',
'description': 'This is the client dashboard page.',
@ -35,12 +40,22 @@ class ClientDashboardView(TemplateView):
def get(self, request, *args, **kwargs):
return render(request, self.template_name, self.extra_context)
class ClientPreinfoView(TemplateView):
template_name = 'client-preinfo.html'
class BarrierDashboardView(TemplateView):
template_name = 'barrier-dashboard.html'
extra_context = {
'title': 'Client Preinfo',
'description': 'This is the client preinfo page.',
'title': 'Client Dashboard',
'description': 'This is the client dashboard page.',
}
def get(self, request, *args, **kwargs):
return render(request, self.template_name, self.extra_context)
# class ClientPreinfoView(TemplateView):
# template_name = 'client-preinfo-content.html'
#
#
#
# def get(self, request, *args, **kwargs):
# return render(request, self.template_name, self.extra_context)

@ -0,0 +1,33 @@
from django.forms import ModelForm
from containers.models import Container
class ContainerBaseForm(ModelForm):
class Meta:
model = Container
fields = '__all__'
class ContainerReceiveForm(ContainerBaseForm):
"""
Form for creating a new Container instance.
Inherits from ContainerBaseForm.
"""
class Meta(ContainerBaseForm.Meta):
fields = ['number', 'receive_vehicle', 'damages', 'heavy_damaged', 'position',]
class ContainerExpeditionForm(ContainerBaseForm):
"""
Form for updating an existing Container instance.
Inherits from ContainerBaseForm.
"""
class Meta(ContainerBaseForm.Meta):
exclude = ['created_on',
'created_by',
'deleted',
'deleted_on',
'deleted_by',
'received'] # Exclude fields that should not be set by the user

@ -1,112 +0,0 @@
# Generated by Django 5.2.3 on 2025-06-25 12:33
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("booking", "0001_initial"),
("common", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="Container",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("number", models.CharField(max_length=11)),
("received_on", models.DateTimeField(auto_now_add=True)),
("received_by", models.IntegerField()),
(
"receive_vehicles",
models.CharField(blank=True, max_length=100, null=True),
),
("damages", models.TextField(blank=True, null=True)),
("heavy_damaged", models.BooleanField(default=False)),
("position", models.CharField(blank=True, max_length=100, null=True)),
("swept", models.BooleanField(default=False)),
("swept_on", models.DateTimeField(blank=True, null=True)),
("swept_by", models.IntegerField(blank=True, null=True)),
("washed", models.BooleanField(default=False)),
("washed_on", models.DateTimeField(blank=True, null=True)),
("washed_by", models.IntegerField(blank=True, null=True)),
("expedited", models.BooleanField(default=False)),
("expedited_on", models.DateTimeField(blank=True, null=True)),
("expedited_by", models.IntegerField(blank=True, null=True)),
(
"expedition_vehicle",
models.CharField(blank=True, max_length=100, null=True),
),
(
"booking",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="container_bookings",
to="booking.bookingmodel",
),
),
(
"container_type",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="container_container_types",
to="common.containertypemodel",
),
),
(
"line_id",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="container_lines",
to="common.linesmodel",
),
),
],
),
migrations.CreateModel(
name="ContainerHistory",
fields=[
(
"container_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="containers.container",
),
),
("operation_date", models.DateTimeField(auto_now_add=True)),
(
"container",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="history_containers",
to="containers.container",
),
),
(
"operation",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="history_operations",
to="common.operationmodel",
),
),
],
bases=("containers.container",),
),
]

@ -4,7 +4,7 @@ from common.models import LinesModel, ContainerTypeModel
# Create your models here.
class Container(models.Model):
number = models.CharField(max_length=11)
line_id = models.ForeignKey(
line = models.ForeignKey(
LinesModel,
on_delete=models.CASCADE,
related_name='container_lines',
@ -15,25 +15,49 @@ class Container(models.Model):
related_name='container_container_types',
)
received_on = models.DateTimeField(auto_now_add=True)
received_by = models.IntegerField()
receive_vehicles = models.CharField(max_length=100, blank=True, null=True)
received_by = models.ForeignKey(
'accounts.DepotUser',
on_delete=models.CASCADE,
related_name='container_received_by',
)
receive_vehicle = models.CharField(max_length=100, blank=True, null=True)
damages = models.TextField(blank=True, null=True)
heavy_damaged = models.BooleanField(default=False)
position = models.CharField(max_length=100, blank=True, null=True)
swept = models.BooleanField(default=False)
swept_on = models.DateTimeField(blank=True, null=True)
swept_by = models.IntegerField(blank=True, null=True)
swept_by = models.ForeignKey(
'accounts.DepotUser',
on_delete=models.CASCADE,
related_name='container_swept_by',
blank=True,
null=True
)
washed = models.BooleanField(default=False)
washed_on = models.DateTimeField(blank=True, null=True)
washed_by = models.IntegerField(blank=True, null=True)
washed_by = models.ForeignKey(
'accounts.DepotUser',
on_delete=models.CASCADE,
related_name='container_washed_by',
blank=True,
null=True
)
booking = models.ForeignKey(
'booking.BookingModel',
on_delete=models.CASCADE,
related_name='container_bookings',
blank = True,
null = True
)
expedited = models.BooleanField(default=False)
expedited_on = models.DateTimeField(blank=True, null=True)
expedited_by = models.IntegerField(blank=True, null=True)
expedited_by = models.ForeignKey(
'accounts.DepotUser',
on_delete=models.CASCADE,
related_name='container_expedited_by',
blank=True,
null=True
)
expedition_vehicle = models.CharField(max_length=100, blank=True, null=True)

@ -0,0 +1,11 @@
from django.urls import include, path
from containers.views import ContainerReceive, ContainerExpedition, ContainerSearchView
urlpatterns = [
path('search', ContainerSearchView.as_view(), name='container_search'),
path('<int:pk>/', include([
path('receive', ContainerReceive.as_view(), name='container_receive'),
path('expedition', ContainerExpedition.as_view(), name='container_expedition'),
])),
]

@ -1,3 +1,98 @@
from django.shortcuts import render
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views import View
from django.views.generic import CreateView, UpdateView, FormView
from common.utils import get_container_by_number
from containers.forms import ContainerReceiveForm, ContainerExpeditionForm
from containers.models import Container
from preinfo.models import Preinfo
# Create your views here.
class ContainerReceive(CreateView):
template_name = 'container-receive.html'
model = Container
form_class = ContainerReceiveForm
success_url = reverse_lazy('dashboard')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pk = self.kwargs.get('pk')
try:
preinfo =Preinfo.objects.filter(pk=pk, received=False).first()
except Preinfo.DoesNotExist:
preinfo = None
if preinfo:
context['preinfo'] = preinfo
context['containers'] = Container.objects.order_by('-received_on').all()[:10] # Fetch the last 10 containers
return context
return redirect(reverse_lazy('container_search'))
def form_valid(self, form):
# Get the preinfo_id from the POST data
preinfo_id = self.request.POST.get('preinfo_id')
try:
preinfo = Preinfo.objects.get(id=preinfo_id)
except Preinfo.DoesNotExist:
preinfo = None
# validate if data is correct, comparing user data with preinfo data
if preinfo and preinfo.container_number == form.cleaned_data.get('number') and not preinfo.received:
preinfo.received = True
preinfo.save()
form.instance.received_by = self.request.user
form.instance.line = preinfo.line
form.instance.container_type = preinfo.container_type
else:
form.add_error('number', 'Invalid data')
return super().form_valid(form)
class ContainerSearchView(View):
template_name = 'container-search.html'
def get(self, request):
return render(request, self.template_name)
def post(self, request):
number = request.POST.get('number')
container = get_container_by_number(number)
if container:
if container.booking:
next_url = request.POST.get('param')
return redirect(next_url, pk=container.booking.pk)
else:
return render(request, self.template_name, {'error': 'Booking not found'})
return render(request, self.template_name, {'error': 'Not found'})
class ContainerExpedition(UpdateView):
template_name = 'container-expedition.html'
model = Container
form_class = ContainerExpeditionForm
success_url = reverse_lazy('dashboard')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
pk = self.kwargs.get('pk')
try:
preinfo =Preinfo.objects.filter(pk=pk, received=False).first()
except Preinfo.DoesNotExist:
preinfo = None
if preinfo:
context['preinfo'] = preinfo
context['containers'] = Container.objects.order_by('-received_on').all()[:10] # Fetch the last 10 containers
return context
return redirect(reverse_lazy('container_search'))

@ -0,0 +1,24 @@
from django.forms import ModelForm
from django.urls import reverse_lazy
from preinfo.models import Preinfo
class PreinfoBaseForm(ModelForm):
class Meta:
model = Preinfo
fields = '__all__'
# success_url = reverse_lazy('client_preinfo')
class PreinfoCreateForm(PreinfoBaseForm):
"""
Form for creating a new PreinfoModel instance.
Inherits from PreinfoBaseForm.
"""
class Meta(PreinfoBaseForm.Meta):
exclude = ['created_on',
'created_by',
'deleted',
'deleted_on',
'deleted_by',
'received'] # Exclude fields that should not be set by the user

@ -1,7 +1,7 @@
from django.db import models
# Create your models here.
class PreinfoModel(models.Model):
class Preinfo(models.Model):
container_number = models.CharField(
max_length=11,
)
@ -17,18 +17,19 @@ class PreinfoModel(models.Model):
)
created_on = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(
'users.DepotUser',
'accounts.DepotUser',
on_delete=models.CASCADE,
related_name='preinfo_created_by',
db_column='created_by_id', # Ensure the column name matches your database schema
)
deleted = models.BooleanField(default=False, null=False)
deleted_by = models.ForeignKey(
'users.DepotUser',
'accounts.DepotUser',
on_delete=models.CASCADE,
related_name='preinfo_deleted_by',
db_column='deleted_by_id', # Ensure the column name matches your database schema
null=True,
blank=True
)
deleted_on = models.DateTimeField(null=True)
deleted_on = models.DateTimeField(null=True, blank=True)
received = models.BooleanField(default=False, null=False)

@ -0,0 +1,8 @@
from django.urls import path
from preinfo.views import ClientPreinfoView, check_preinfo, PreinfoSearchView
urlpatterns = [
path('client/', ClientPreinfoView.as_view(), name='client_preinfo'),
path('check-preinfo/', check_preinfo, name='check_preinfo'),
path('preinfo-search/', PreinfoSearchView.as_view(), name='preinfo_search'),
]

@ -1,3 +1,82 @@
from django.shortcuts import render
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin
from django.forms import forms
from django.forms.widgets import HiddenInput
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views import View
from django.views.generic import TemplateView, FormView, CreateView
# Create your views here.
from common.utils import filter_queryset_by_user, get_preinfo_by_number
from preinfo.forms import PreinfoBaseForm, PreinfoCreateForm
from preinfo.models import Preinfo
class ClientPreinfoView(LoginRequiredMixin, CreateView):
template_name = 'client-preinfo-content.html'
form_class = PreinfoCreateForm
success_url = reverse_lazy('client_preinfo')
model = Preinfo
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
queryset = self.model.objects.all().order_by('-created_on')
user = self.request.user
# !!! important
queryset = filter_queryset_by_user( queryset, user)[:10]
# !!! important
context['recent'] = queryset
return context
def get_form(self, form_class=None):
form = super().get_form(form_class)
user = self.request.user
# If user has a specific line, limit the line choices
if user.line:
form.fields['line'].queryset = form.fields['line'].queryset.filter(pk=user.line.pk)
form.fields['line'].initial = user.line
form.fields['line'].widget.attrs['disabled'] = True
# Keep the value when form is submitted
# form.fields['line'].widget = HiddenInput()
return form
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
# Check if a preinfo exists for the given container number
def check_preinfo(request):
number = request.GET.get('number')
preinfo = Preinfo.objects.filter(container_number=number, received=False).first()
if preinfo:
return JsonResponse({
'found': True,
'line': preinfo.line.name,
'container_type': preinfo.container_type.name,
'preinfo_id': preinfo.id,
})
return JsonResponse({'found': False})
class PreinfoSearchView(View):
template_name = 'container-search.html'
def get(self, request):
return render(request, self.template_name)
def post(self, request):
number = request.POST.get('number')
preinfo = get_preinfo_by_number(number)
if preinfo:
next_url = request.POST.get('param')
return redirect(next_url, pk=preinfo.pk)
return render(request, self.template_name, {'error': 'Not found'})

@ -0,0 +1,92 @@
/* === Layout === */
.layout-root {
display: flex;
height: 100vh;
overflow: hidden;
}
/* === Sidebar === */
.sidebar {
width: 16rem;
height: 100%;
color: white;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #0f4c81 0%, #1a6baf 100%);
transition: all 0.3s;
}
.sidebar-header {
padding: 1.25rem;
border-bottom: 1px solid #2b6cb0;
}
.sidebar-title {
font-size: 1.25rem;
font-weight: 700;
}
.sidebar-subtitle {
font-size: 0.875rem;
color: #bfdbfe;
}
.nav-section {
padding: 1rem 0;
flex-grow: 1;
}
.nav-label {
padding: 0.5rem 1rem;
font-size: 0.75rem;
text-transform: uppercase;
color: #93c5fd;
letter-spacing: 0.05em;
}
.nav-item {
display: flex;
align-items: center;
padding: 0.75rem 1.5rem;
color: white;
transition: all 0.2s;
text-decoration: none;
}
.nav-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid white;
}
.nav-icon {
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
}
.user-profile {
padding: 1rem;
border-top: 1px solid #2b6cb0;
display: flex;
align-items: center;
}
.user-avatar {
width: 2.5rem;
height: 2.5rem;
border-radius: 9999px;
background-color: #3b82f6;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
color: white;
}
.user-details {
margin-left: 0.75rem;
}
.user-name {
font-size: 0.875rem;
font-weight: 500;
}
.user-role {
font-size: 0.75rem;
color: #bfdbfe;
}
.logout-button {
margin-left: auto;
color: white;
}

@ -196,3 +196,5 @@ input[type="password"]:focus {
width: 1.5rem;
height: 1.5rem;
}

@ -0,0 +1,124 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Line Operator Dashboard | Container Depot</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.sidebar {
background: linear-gradient(180deg, #0f4c81 0%, #1a6baf 100%);
transition: all 0.3s;
}
.content-area {
transition: all 0.3s;
}
.nav-item {
transition: all 0.2s;
}
.nav-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid white;
}
.card {
transition: all 0.3s;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.tab {
transition: all 0.2s;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.form-section {
animation: slideIn 0.5s ease-in-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
{% load static %}
<div class="sidebar w-64 h-full text-white flex flex-col">
<div class="p-5 border-b border-blue-700">
<h1 class="text-xl font-bold">Container Depot</h1>
<p class="text-sm text-blue-200">Line Operator Portal</p>
</div>
<nav class="flex-grow py-4">
<div class="px-4 py-2 text-xs text-blue-300 uppercase tracking-wider">Main</div>
<a href="{% url 'barrier_dashboard' %}" class="nav-item active flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Dashboard
</a>
<a href="{% url 'preinfo_search' %}?param=container_receive" id="ordersNav" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
Receive container
</a>
<a href="{% url 'container_search' %}?param=container_expedition" id="ordersNav" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
Expedite container
</a>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
Photos
</a>
<div class="px-4 py-2 mt-6 text-xs text-blue-300 uppercase tracking-wider">Account</div>
{# <a href="#" class="nav-item flex items-center px-6 py-3 text-white">#}
{# <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">#}
{# <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />#}
{# <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />#}
{# </svg>#}
{# Settings#}
{# </a>#}
</nav>
<div class="p-4 border-t border-blue-700">
<div class="flex items-center">
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold">
LO
</div>
<div class="ml-3">
<p class="text-sm font-medium">Maersk Line</p>
<p class="text-xs text-blue-300">Line Operator</p>
</div>
<button class="ml-auto text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
</button>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,232 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Line Operator Dashboard | Container Depot</title>
<link rel="stylesheet" href="styles.css">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.content-area {
transition: all 0.3s;
}
.nav-item {
transition: all 0.2s;
}
.card {
transition: all 0.3s;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.tab {
transition: all 0.2s;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.form-section {
animation: slideIn 0.5s ease-in-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="layout-root">
<aside class="sidebar">
<div class="sidebar-header">
<h1 class="sidebar-title">Container Depot</h1>
<p class="sidebar-subtitle">Line Operator Portal</p>
</div>
<nav class="nav-section">
<div class="nav-label">Main</div>
<a href="#" class="nav-item active">
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Dashboard
</a>
<!-- Repeat for other nav items like Container Preinfo, Expedition Orders, Reports, etc. -->
</nav>
<div class="user-profile">
<div class="user-avatar">LO</div>
<div class="user-details">
<p class="user-name">Maersk Line</p>
<p class="user-role">Line Operator</p>
</div>
<button class="logout-button">
<svg class="nav-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
</button>
</div>
</aside>
<!-- Main content layout will continue here... -->
<main class="content-area">
<header class="topbar">
<div class="topbar-inner">
<div class="topbar-title">
<h2>Dashboard</h2>
</div>
<div class="topbar-actions">
<button class="topbar-button">
<svg xmlns="http://www.w3.org/2000/svg" class="topbar-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
<button class="topbar-button">
<svg xmlns="http://www.w3.org/2000/svg" class="topbar-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</header>
<!-- More dashboard content will follow -->
<section class="dashboard-overview">
<div class="dashboard-cards">
<div class="card card-blue">
<div class="card-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="card-icon-inner" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
</div>
<div class="card-details">
<h3 class="card-title">Active Containers</h3>
<p class="card-number">42</p>
<p class="card-note green">+3 since last week</p>
</div>
</div>
<div class="card card-green">
<div class="card-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="card-icon-inner" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="card-details">
<h3 class="card-title">Preinfo Sent</h3>
<p class="card-number">18</p>
<p class="card-note green">+5 since last week</p>
</div>
</div>
<div class="card card-orange">
<div class="card-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="card-icon-inner" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
</div>
<div class="card-details">
<h3 class="card-title">Pending Orders</h3>
<p class="card-number">7</p>
<p class="card-note orange">2 require attention</p>
</div>
</div>
</div>
</section>
<section class="dashboard-tables">
<div class="table-container">
<div class="table-header">
<h3>Recent Container Activity</h3>
</div>
<table class="data-table">
<thead>
<tr>
<th>Container</th>
<th>Type</th>
<th>Status</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>MSCU1234567</td>
<td>40HC</td>
<td><span class="badge badge-green">Received</span></td>
<td>2023-06-15</td>
</tr>
<tr>
<td>MSCU7654321</td>
<td>20DV</td>
<td><span class="badge badge-blue">Preinfo</span></td>
<td>2023-06-14</td>
</tr>
<tr>
<td>MSCU2468135</td>
<td>40DV</td>
<td><span class="badge badge-orange">Order</span></td>
<td>2023-06-13</td>
</tr>
<tr>
<td>MSCU1357924</td>
<td>20RF</td>
<td><span class="badge badge-red">Expedited</span></td>
<td>2023-06-12</td>
</tr>
</tbody>
</table>
</div>
<div class="table-container">
<div class="table-header">
<h3>Payment Status</h3>
</div>
<table class="data-table">
<thead>
<tr>
<th>Invoice</th>
<th>Amount</th>
<th>Status</th>
<th>Due Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>INV-2023-0042</td>
<td>$1,250.00</td>
<td><span class="badge badge-green">Paid</span></td>
<td>2023-06-10</td>
</tr>
<tr>
<td>INV-2023-0041</td>
<td>$875.50</td>
<td><span class="badge badge-yellow">Pending</span></td>
<td>2023-06-20</td>
</tr>
<tr>
<td>INV-2023-0040</td>
<td>$2,100.00</td>
<td><span class="badge badge-red">Overdue</span></td>
<td>2023-06-05</td>
</tr>
<tr>
<td>INV-2023-0039</td>
<td>$950.25</td>
<td><span class="badge badge-green">Paid</span></td>
<td>2023-05-28</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
</body>
</html>

@ -0,0 +1,194 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Line Operator Dashboard | Container Depot</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.sidebar {
background: linear-gradient(180deg, #0f4c81 0%, #1a6baf 100%);
transition: all 0.3s;
}
.content-area {
transition: all 0.3s;
}
.nav-item {
transition: all 0.2s;
}
.nav-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid white;
}
.card {
transition: all 0.3s;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.tab {
transition: all 0.2s;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.form-section {
animation: slideIn 0.5s ease-in-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="flex h-screen overflow-hidden">
<!-- Sidebar -->
{% include 'sidebar.html' %}
<!-- Main Content -->
<main class="content-area flex-1 overflow-y-auto">
<!-- Top Navigation -->
<header class="bg-white shadow-sm">
<div class="flex items-center justify-between px-6 py-4">
<div class="flex items-center">
<h2 class="text-xl font-semibold text-gray-800">Dashboard</h2>
</div>
<div class="flex items-center space-x-4">
<button class="text-gray-500 hover:text-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
<button class="text-gray-500 hover:text-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</header>
<!-- Dashboard Content -->
<div class="p-6">
{% block content %}
{# {% include 'client-dashboard-content.html' %}#}
{# {% include 'client-preinfo-content.html' %}#}
{# {% include 'client-orders-content.html' %}#}
{% endblock content %}
</div>
</main>
{# <script>#}
{# // Tab Navigation#}
{# const dashboardContent = document.getElementById('dashboardContent');#}
{# const preinfoContent = document.getElementById('preinfoContent');#}
{# const ordersContent = document.getElementById('ordersContent');#}
{# #}
{# const preinfoNav = document.getElementById('preinfoNav');#}
{# const ordersNav = document.getElementById('ordersNav');#}
{# #}
{# preinfoNav.addEventListener('click', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // Update content visibility#}
{# dashboardContent.classList.remove('active');#}
{# preinfoContent.classList.add('active');#}
{# ordersContent.classList.remove('active');#}
{# #}
{# // Update navigation styling#}
{# document.querySelector('.nav-item.active').classList.remove('active');#}
{# preinfoNav.classList.add('active');#}
{# #}
{# // Update header title#}
{# document.querySelector('header h2').textContent = 'Container Preinfo';#}
{# });#}
{# #}
{# ordersNav.addEventListener('click', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // Update content visibility#}
{# dashboardContent.classList.remove('active');#}
{# preinfoContent.classList.remove('active');#}
{# ordersContent.classList.add('active');#}
{# #}
{# // Update navigation styling#}
{# document.querySelector('.nav-item.active').classList.remove('active');#}
{# ordersNav.classList.add('active');#}
{# #}
{# // Update header title#}
{# document.querySelector('header h2').textContent = 'Expedition Orders';#}
{# });#}
{# #}
{# // Damage checkbox toggle#}
{# const damageCheck = document.getElementById('damageCheck');#}
{# const damageDetails = document.getElementById('damageDetails');#}
{# #}
{# damageCheck.addEventListener('change', function() {#}
{# if (this.checked) {#}
{# damageDetails.classList.remove('hidden');#}
{# } else {#}
{# damageDetails.classList.add('hidden');#}
{# }#}
{# });#}
{# #}
{# // Order type toggle#}
{# const specificContainer = document.getElementById('specificContainer');#}
{# const anyContainer = document.getElementById('anyContainer');#}
{# const specificContainerFields = document.getElementById('specificContainerFields');#}
{# const anyContainerFields = document.getElementById('anyContainerFields');#}
{# #}
{# specificContainer.addEventListener('change', function() {#}
{# if (this.checked) {#}
{# specificContainerFields.classList.remove('hidden');#}
{# anyContainerFields.classList.add('hidden');#}
{# }#}
{# });#}
{# #}
{# anyContainer.addEventListener('change', function() {#}
{# if (this.checked) {#}
{# specificContainerFields.classList.add('hidden');#}
{# anyContainerFields.classList.remove('hidden');#}
{# }#}
{# });#}
{# #}
{# // Form submissions#}
{# document.getElementById('preinfoForm').addEventListener('submit', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // In a real app, this would send data to the server#}
{# alert('Preinfo submitted successfully!');#}
{# this.reset();#}
{# });#}
{# #}
{# document.getElementById('orderForm').addEventListener('submit', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // In a real app, this would send data to the server#}
{# alert('Expedition order submitted successfully!');#}
{# this.reset();#}
{# });#}
{# #}
{# // Add more container button#}
{# document.getElementById('addMoreContainer').addEventListener('click', function() {#}
{# alert('In a real app, this would add fields for another container');#}
{# });#}
{# </script>#}
{#<script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'947f86ac452d3130',t:'MTc0ODYyMTY4Mi4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body>#}
</body>
</html>

@ -0,0 +1,63 @@
{% extends 'client-base.html' %}
{% block content %}
<div id="preinfoContent" class="tab-content active">
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Submit Container Preinfo</h3>
<p class="text-sm text-gray-600 mt-1">Provide information about containers that will arrive at the depot</p>
</div>
<div class="p-6">
<form id="preinfoForm" class="space-y-6" method="POST" >
{{ form.as_p }}
{% csrf_token %}
<div class="form-section flex justify-end space-x-3">
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Submit Preinfo
</button>
</div>
</form>
</div>
</div>
<div class="mt-6 bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Recent Preinfo Submissions</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Est. Arrival</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{% for preinfo in recent %}
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">{{ preinfo.container_number }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ preinfo.container_type }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ preinfo.created_on }}</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">Pending</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">Edit</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock content %}

@ -0,0 +1,162 @@
{% extends 'client-base.html' %}
{% block content %}
<div id="dashboardContent" class="tab-content active">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
<div class="card bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-blue-100 text-blue-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-700">Active Containers</h3>
<p class="text-3xl font-bold text-gray-900">42</p>
<p class="text-sm text-green-600">+3 since last week</p>
</div>
</div>
</div>
<div class="card bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-green-100 text-green-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-700">Preinfo Sent</h3>
<p class="text-3xl font-bold text-gray-900">18</p>
<p class="text-sm text-green-600">+5 since last week</p>
</div>
</div>
</div>
<div class="card bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-orange-100 text-orange-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-700">Pending Orders</h3>
<p class="text-3xl font-bold text-gray-900">7</p>
<p class="text-sm text-orange-600">2 require attention</p>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Recent Container Activity</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU1234567</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40HC</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Received</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-15</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU7654321</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20DV</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">Preinfo</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-14</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU2468135</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40DV</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-orange-100 text-orange-800">Order</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-13</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU1357924</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20RF</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800">Expedited</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-12</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Payment Status</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Invoice</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Due Date</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0042</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$1,250.00</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Paid</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-10</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0041</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$875.50</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800">Pending</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-20</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0040</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$2,100.00</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800">Overdue</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-05</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0039</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$950.25</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Paid</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-05-28</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

@ -1,689 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Line Operator Dashboard | Container Depot</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.sidebar {
background: linear-gradient(180deg, #0f4c81 0%, #1a6baf 100%);
transition: all 0.3s;
}
.content-area {
transition: all 0.3s;
}
.nav-item {
transition: all 0.2s;
}
.nav-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid white;
}
.card {
transition: all 0.3s;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.tab {
transition: all 0.2s;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.form-section {
animation: slideIn 0.5s ease-in-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="flex h-screen overflow-hidden">
<!-- Sidebar -->
<aside class="sidebar w-64 h-full text-white flex flex-col">
<div class="p-5 border-b border-blue-700">
<h1 class="text-xl font-bold">Container Depot</h1>
<p class="text-sm text-blue-200">Line Operator Portal</p>
</div>
<nav class="flex-grow py-4">
<div class="px-4 py-2 text-xs text-blue-300 uppercase tracking-wider">Main</div>
<a href="#" class="nav-item active flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Dashboard
</a>
<a href="#" id="preinfoNav" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
Container Preinfo
</a>
<a href="#" id="ordersNav" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
Expedition Orders
</a>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
Reports
</a>
<div class="px-4 py-2 mt-6 text-xs text-blue-300 uppercase tracking-wider">Account</div>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Settings
</a>
</nav>
<div class="p-4 border-t border-blue-700">
<div class="flex items-center">
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold">
LO
</div>
<div class="ml-3">
<p class="text-sm font-medium">Maersk Line</p>
<p class="text-xs text-blue-300">Line Operator</p>
</div>
<button class="ml-auto text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
</button>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="content-area flex-1 overflow-y-auto">
<!-- Top Navigation -->
<header class="bg-white shadow-sm">
<div class="flex items-center justify-between px-6 py-4">
<div class="flex items-center">
<h2 class="text-xl font-semibold text-gray-800">Dashboard</h2>
</div>
<div class="flex items-center space-x-4">
<button class="text-gray-500 hover:text-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
<button class="text-gray-500 hover:text-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</button>
</div>
</div>
</header>
<!-- Dashboard Content -->
<div class="p-6">
<!-- Dashboard Overview -->
<div id="dashboardContent" class="tab-content active">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
<div class="card bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-blue-100 text-blue-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-700">Active Containers</h3>
<p class="text-3xl font-bold text-gray-900">42</p>
<p class="text-sm text-green-600">+3 since last week</p>
</div>
</div>
</div>
<div class="card bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-green-100 text-green-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-700">Preinfo Sent</h3>
<p class="text-3xl font-bold text-gray-900">18</p>
<p class="text-sm text-green-600">+5 since last week</p>
</div>
</div>
</div>
<div class="card bg-white rounded-lg shadow p-6">
<div class="flex items-center">
<div class="p-3 rounded-full bg-orange-100 text-orange-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-700">Pending Orders</h3>
<p class="text-3xl font-bold text-gray-900">7</p>
<p class="text-sm text-orange-600">2 require attention</p>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Recent Container Activity</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU1234567</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40HC</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Received</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-15</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU7654321</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20DV</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">Preinfo</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-14</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU2468135</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40DV</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-orange-100 text-orange-800">Order</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-13</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU1357924</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20RF</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800">Expedited</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-12</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Payment Status</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Invoice</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Amount</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Due Date</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0042</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$1,250.00</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Paid</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-10</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0041</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$875.50</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800">Pending</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-20</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0040</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$2,100.00</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-red-100 text-red-800">Overdue</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-05</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">INV-2023-0039</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">$950.25</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Paid</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-05-28</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Container Preinfo Form -->
<div id="preinfoContent" class="tab-content">
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Submit Container Preinfo</h3>
<p class="text-sm text-gray-600 mt-1">Provide information about containers that will arrive at the depot</p>
</div>
<div class="p-6">
<form id="preinfoForm" class="space-y-6">
<div class="form-section grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="containerNumber" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>
<input type="text" id="containerNumber" name="containerNumber" placeholder="e.g. MSCU1234567" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<p class="mt-1 text-xs text-gray-500">Enter the full container number including prefix</p>
</div>
<div>
<label for="containerType" class="block text-sm font-medium text-gray-700 mb-1">Container Type</label>
<select id="containerType" name="containerType" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<option value="">Select container type</option>
<option value="20DV">20' Dry Van (20DV)</option>
<option value="40DV">40' Dry Van (40DV)</option>
<option value="40HC">40' High Cube (40HC)</option>
<option value="20RF">20' Reefer (20RF)</option>
<option value="40RF">40' Reefer (40RF)</option>
<option value="20OT">20' Open Top (20OT)</option>
<option value="40OT">40' Open Top (40OT)</option>
<option value="20FR">20' Flat Rack (20FR)</option>
<option value="40FR">40' Flat Rack (40FR)</option>
</select>
</div>
</div>
<div class="form-section grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="estimatedArrival" class="block text-sm font-medium text-gray-700 mb-1">Estimated Arrival Date</label>
<input type="date" id="estimatedArrival" name="estimatedArrival" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
<div>
<label for="vesselVoyage" class="block text-sm font-medium text-gray-700 mb-1">Vessel/Voyage</label>
<input type="text" id="vesselVoyage" name="vesselVoyage" placeholder="e.g. MAERSK SEVILLE / 123E" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
</div>
<div class="form-section">
<label for="additionalInfo" class="block text-sm font-medium text-gray-700 mb-1">Additional Information</label>
<textarea id="additionalInfo" name="additionalInfo" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Any special handling instructions or notes"></textarea>
</div>
<div class="form-section flex items-center">
<input type="checkbox" id="damageCheck" name="damageCheck" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
<label for="damageCheck" class="ml-2 block text-sm text-gray-700">Container has visible damage</label>
</div>
<div id="damageDetails" class="form-section hidden">
<label for="damageDescription" class="block text-sm font-medium text-gray-700 mb-1">Damage Description</label>
<textarea id="damageDescription" name="damageDescription" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Describe the damage in detail"></textarea>
</div>
<div class="form-section flex justify-end space-x-3">
<button type="button" id="addMoreContainer" class="px-4 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500">
Add Another Container
</button>
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Submit Preinfo
</button>
</div>
</form>
</div>
</div>
<div class="mt-6 bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Recent Preinfo Submissions</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Est. Arrival</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU7654321</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20DV</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-18</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">Pending</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">Edit</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU9876543</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40HC</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-17</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Received</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">View</button>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU1122334</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20RF</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-16</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800">Delayed</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">Edit</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Expedition Orders Form -->
<div id="ordersContent" class="tab-content">
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Create Expedition Order</h3>
<p class="text-sm text-gray-600 mt-1">Request containers to be expedited from the depot</p>
</div>
<div class="p-6">
<form id="orderForm" class="space-y-6">
<div class="form-section">
<label for="orderType" class="block text-sm font-medium text-gray-700 mb-1">Order Type</label>
<div class="flex space-x-4">
<div class="flex items-center">
<input type="radio" id="specificContainer" name="orderType" value="specific" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300" checked>
<label for="specificContainer" class="ml-2 block text-sm text-gray-700">Specific Container</label>
</div>
<div class="flex items-center">
<input type="radio" id="anyContainer" name="orderType" value="any" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300">
<label for="anyContainer" class="ml-2 block text-sm text-gray-700">Any Available Container</label>
</div>
</div>
</div>
<div id="specificContainerFields" class="form-section">
<label for="containerNumber" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>
<input type="text" id="orderContainerNumber" name="containerNumber" placeholder="e.g. MSCU1234567" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<p class="mt-1 text-xs text-gray-500">Enter the full container number including prefix</p>
</div>
<div id="anyContainerFields" class="form-section hidden grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="containerType" class="block text-sm font-medium text-gray-700 mb-1">Container Type</label>
<select id="orderContainerType" name="containerType" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">Select container type</option>
<option value="20DV">20' Dry Van (20DV)</option>
<option value="40DV">40' Dry Van (40DV)</option>
<option value="40HC">40' High Cube (40HC)</option>
<option value="20RF">20' Reefer (20RF)</option>
<option value="40RF">40' Reefer (40RF)</option>
<option value="20OT">20' Open Top (20OT)</option>
<option value="40OT">40' Open Top (40OT)</option>
<option value="20FR">20' Flat Rack (20FR)</option>
<option value="40FR">40' Flat Rack (40FR)</option>
</select>
</div>
<div>
<label for="containerCondition" class="block text-sm font-medium text-gray-700 mb-1">Container Condition</label>
<select id="containerCondition" name="containerCondition" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="any">Any Condition</option>
<option value="new">New / Like New</option>
<option value="good">Good Condition</option>
<option value="acceptable">Acceptable</option>
</select>
</div>
</div>
<div class="form-section grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="pickupDate" class="block text-sm font-medium text-gray-700 mb-1">Pickup Date</label>
<input type="date" id="pickupDate" name="pickupDate" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
<div>
<label for="transportCompany" class="block text-sm font-medium text-gray-700 mb-1">Transport Company</label>
<input type="text" id="transportCompany" name="transportCompany" placeholder="e.g. ABC Trucking" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
</div>
<div class="form-section">
<label for="driverInfo" class="block text-sm font-medium text-gray-700 mb-1">Driver Information</label>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<input type="text" id="driverName" name="driverName" placeholder="Driver Name" class="px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<input type="text" id="driverPhone" name="driverPhone" placeholder="Driver Phone" class="px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
</div>
<div class="form-section">
<label for="orderNotes" class="block text-sm font-medium text-gray-700 mb-1">Special Instructions</label>
<textarea id="orderNotes" name="orderNotes" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Any special handling instructions or notes"></textarea>
</div>
<div class="form-section flex justify-end">
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Submit Order
</button>
</div>
</form>
</div>
</div>
<div class="mt-6 bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Active Expedition Orders</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Order ID</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pickup Date</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">ORD-2023-0015</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">MSCU2468135</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-20</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">Approved</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">View</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">ORD-2023-0014</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">Any 40HC</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-19</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800">Pending</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">View</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">ORD-2023-0013</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">MSCU1357924</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-15</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Completed</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800">View</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</main>
<script>
// Tab Navigation
const dashboardContent = document.getElementById('dashboardContent');
const preinfoContent = document.getElementById('preinfoContent');
const ordersContent = document.getElementById('ordersContent');
const preinfoNav = document.getElementById('preinfoNav');
const ordersNav = document.getElementById('ordersNav');
preinfoNav.addEventListener('click', function(e) {
e.preventDefault();
// Update content visibility
dashboardContent.classList.remove('active');
preinfoContent.classList.add('active');
ordersContent.classList.remove('active');
// Update navigation styling
document.querySelector('.nav-item.active').classList.remove('active');
preinfoNav.classList.add('active');
// Update header title
document.querySelector('header h2').textContent = 'Container Preinfo';
});
ordersNav.addEventListener('click', function(e) {
e.preventDefault();
// Update content visibility
dashboardContent.classList.remove('active');
preinfoContent.classList.remove('active');
ordersContent.classList.add('active');
// Update navigation styling
document.querySelector('.nav-item.active').classList.remove('active');
ordersNav.classList.add('active');
// Update header title
document.querySelector('header h2').textContent = 'Expedition Orders';
});
// Damage checkbox toggle
const damageCheck = document.getElementById('damageCheck');
const damageDetails = document.getElementById('damageDetails');
damageCheck.addEventListener('change', function() {
if (this.checked) {
damageDetails.classList.remove('hidden');
} else {
damageDetails.classList.add('hidden');
}
});
// Order type toggle
const specificContainer = document.getElementById('specificContainer');
const anyContainer = document.getElementById('anyContainer');
const specificContainerFields = document.getElementById('specificContainerFields');
const anyContainerFields = document.getElementById('anyContainerFields');
specificContainer.addEventListener('change', function() {
if (this.checked) {
specificContainerFields.classList.remove('hidden');
anyContainerFields.classList.add('hidden');
}
});
anyContainer.addEventListener('change', function() {
if (this.checked) {
specificContainerFields.classList.add('hidden');
anyContainerFields.classList.remove('hidden');
}
});
// Form submissions
document.getElementById('preinfoForm').addEventListener('submit', function(e) {
e.preventDefault();
// In a real app, this would send data to the server
alert('Preinfo submitted successfully!');
this.reset();
});
document.getElementById('orderForm').addEventListener('submit', function(e) {
e.preventDefault();
// In a real app, this would send data to the server
alert('Expedition order submitted successfully!');
this.reset();
});
// Add more container button
document.getElementById('addMoreContainer').addEventListener('click', function() {
alert('In a real app, this would add fields for another container');
});
</script>
<script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'947f86ac452d3130',t:'MTc0ODYyMTY4Mi4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body>
</html>

@ -0,0 +1,151 @@
{% extends 'client-base.html' %}
{% block content %}
<div id="ordersContent" class="tab-content">
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Create Expedition Order</h3>
<p class="text-sm text-gray-600 mt-1">Request containers to be expedited from the depot</p>
</div>
<div class="p-6">
<form id="orderForm" class="space-y-6">
<div class="form-section">
<label for="orderType" class="block text-sm font-medium text-gray-700 mb-1">Order Type</label>
<div class="flex space-x-4">
<div class="flex items-center">
<input type="radio" id="specificContainer" name="orderType" value="specific" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300" checked>
<label for="specificContainer" class="ml-2 block text-sm text-gray-700">Specific Container</label>
</div>
<div class="flex items-center">
<input type="radio" id="anyContainer" name="orderType" value="any" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300">
<label for="anyContainer" class="ml-2 block text-sm text-gray-700">Any Available Container</label>
</div>
</div>
</div>
<div id="specificContainerFields" class="form-section">
<label for="containerNumber" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>
<input type="text" id="orderContainerNumber" name="containerNumber" placeholder="e.g. MSCU1234567" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<p class="mt-1 text-xs text-gray-500">Enter the full container number including prefix</p>
</div>
<div id="anyContainerFields" class="form-section hidden grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="containerType" class="block text-sm font-medium text-gray-700 mb-1">Container Type</label>
<select id="orderContainerType" name="containerType" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">Select container type</option>
<option value="20DV">20' Dry Van (20DV)</option>
<option value="40DV">40' Dry Van (40DV)</option>
<option value="40HC">40' High Cube (40HC)</option>
<option value="20RF">20' Reefer (20RF)</option>
<option value="40RF">40' Reefer (40RF)</option>
<option value="20OT">20' Open Top (20OT)</option>
<option value="40OT">40' Open Top (40OT)</option>
<option value="20FR">20' Flat Rack (20FR)</option>
<option value="40FR">40' Flat Rack (40FR)</option>
</select>
</div>
<div>
<label for="containerCondition" class="block text-sm font-medium text-gray-700 mb-1">Container Condition</label>
<select id="containerCondition" name="containerCondition" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="any">Any Condition</option>
<option value="new">New / Like New</option>
<option value="good">Good Condition</option>
<option value="acceptable">Acceptable</option>
</select>
</div>
</div>
<div class="form-section grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="pickupDate" class="block text-sm font-medium text-gray-700 mb-1">Pickup Date</label>
<input type="date" id="pickupDate" name="pickupDate" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
<div>
<label for="transportCompany" class="block text-sm font-medium text-gray-700 mb-1">Transport Company</label>
<input type="text" id="transportCompany" name="transportCompany" placeholder="e.g. ABC Trucking" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
</div>
<div class="form-section">
<label for="driverInfo" class="block text-sm font-medium text-gray-700 mb-1">Driver Information</label>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<input type="text" id="driverName" name="driverName" placeholder="Driver Name" class="px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
<input type="text" id="driverPhone" name="driverPhone" placeholder="Driver Phone" class="px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
</div>
<div class="form-section">
<label for="orderNotes" class="block text-sm font-medium text-gray-700 mb-1">Special Instructions</label>
<textarea id="orderNotes" name="orderNotes" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Any special handling instructions or notes"></textarea>
</div>
<div class="form-section flex justify-end">
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Submit Order
</button>
</div>
</form>
</div>
</div>
<div class="mt-6 bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Active Expedition Orders</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Order ID</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pickup Date</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">ORD-2023-0015</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">MSCU2468135</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-20</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">Approved</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">View</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">ORD-2023-0014</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">Any 40HC</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-19</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800">Pending</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">View</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">ORD-2023-0013</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">MSCU1357924</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-15</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Completed</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800">View</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock content %}

@ -0,0 +1,139 @@
{% extends 'client-base.html' %}
{% block content %}
<div id="preinfoContent" class="tab-content active">
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Submit Container Preinfo</h3>
<p class="text-sm text-gray-600 mt-1">Provide information about containers that will arrive at the depot</p>
</div>
<div class="p-6">
<form id="preinfoForm" class="space-y-6" method="POST" >
{{ form.as_p }}
{% csrf_token %}
{# <div class="form-section grid grid-cols-1 md:grid-cols-2 gap-6">#}
{# <div>#}
{# <label for="containerNumber" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>#}
{# <input type="text" id="containerNumber" name="containerNumber" placeholder="e.g. MSCU1234567" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>#}
{# <p class="mt-1 text-xs text-gray-500">Enter the full container number including prefix</p>#}
{# </div>#}
{##}
{# <div>#}
{# <label for="containerType" class="block text-sm font-medium text-gray-700 mb-1">Container Type</label>#}
{# <select id="containerType" name="containerType" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>#}
{# <option value="">Select container type</option>#}
{# <option value="20DV">20' Dry Van (20DV)</option>#}
{# <option value="40DV">40' Dry Van (40DV)</option>#}
{# <option value="40HC">40' High Cube (40HC)</option>#}
{# <option value="20RF">20' Reefer (20RF)</option>#}
{# <option value="40RF">40' Reefer (40RF)</option>#}
{# <option value="20OT">20' Open Top (20OT)</option>#}
{# <option value="40OT">40' Open Top (40OT)</option>#}
{# <option value="20FR">20' Flat Rack (20FR)</option>#}
{# <option value="40FR">40' Flat Rack (40FR)</option>#}
{# </select>#}
{# </div>#}
{# </div>#}
{##}
{# <div class="form-section grid grid-cols-1 md:grid-cols-2 gap-6">#}
{# <div>#}
{# <label for="estimatedArrival" class="block text-sm font-medium text-gray-700 mb-1">Estimated Arrival Date</label>#}
{# <input type="date" id="estimatedArrival" name="estimatedArrival" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>#}
{# </div>#}
{##}
{# <div>#}
{# <label for="vesselVoyage" class="block text-sm font-medium text-gray-700 mb-1">Vessel/Voyage</label>#}
{# <input type="text" id="vesselVoyage" name="vesselVoyage" placeholder="e.g. MAERSK SEVILLE / 123E" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">#}
{# </div>#}
{# </div>#}
{##}
{# <div class="form-section">#}
{# <label for="additionalInfo" class="block text-sm font-medium text-gray-700 mb-1">Additional Information</label>#}
{# <textarea id="additionalInfo" name="additionalInfo" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Any special handling instructions or notes"></textarea>#}
{# </div>#}
{##}
{# <div class="form-section flex items-center">#}
{# <input type="checkbox" id="damageCheck" name="damageCheck" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">#}
{# <label for="damageCheck" class="ml-2 block text-sm text-gray-700">Container has visible damage</label>#}
{# </div>#}
{##}
{# <div id="damageDetails" class="form-section hidden">#}
{# <label for="damageDescription" class="block text-sm font-medium text-gray-700 mb-1">Damage Description</label>#}
{# <textarea id="damageDescription" name="damageDescription" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Describe the damage in detail"></textarea>#}
{# </div>#}
<div class="form-section flex justify-end space-x-3">
<button type="button" id="addMoreContainer" class="px-4 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-gray-500">
Add Another Container
</button>
<button type="submit" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Submit Preinfo
</button>
</div>
</form>
</div>
</div>
<div class="mt-6 bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Recent Preinfo Submissions</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Est. Arrival</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{% for preinfo in recent %}
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">{{ preinfo.container_number }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ preinfo.container_type }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ preinfo.created_on }}</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">Pending</span>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">
<button class="text-blue-600 hover:text-blue-800 mr-3">Edit</button>
<button class="text-red-600 hover:text-red-800">Cancel</button>
</td>
</tr>
{% endfor %}
{# <tr>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU9876543</td>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40HC</td>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-17</td>#}
{# <td class="px-4 py-3 whitespace-nowrap">#}
{# <span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Received</span>#}
{# </td>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">#}
{# <button class="text-blue-600 hover:text-blue-800 mr-3">View</button>#}
{# </td>#}
{# </tr>#}
{# <tr>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU1122334</td>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20RF</td>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">2023-06-16</td>#}
{# <td class="px-4 py-3 whitespace-nowrap">#}
{# <span class="px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800">Delayed</span>#}
{# </td>#}
{# <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">#}
{# <button class="text-blue-600 hover:text-blue-800 mr-3">Edit</button>#}
{# <button class="text-red-600 hover:text-red-800">Cancel</button>#}
{# </td>#}
{# </tr>#}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock content %}

@ -112,66 +112,7 @@
</head>
<body class="flex h-screen overflow-hidden">
<!-- Sidebar -->
<aside class="sidebar w-64 h-full text-white flex flex-col">
<div class="p-5 border-b border-blue-700">
<h1 class="text-xl font-bold">Container Depot</h1>
<p class="text-sm text-blue-200">Barrier Staff Portal</p>
</div>
<nav class="flex-grow py-4">
<div class="px-4 py-2 text-xs text-blue-300 uppercase tracking-wider">Operations</div>
<a href="#" class="nav-item active flex items-center px-6 py-3 text-white" id="receiveNav">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 4H6a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-2m-4-1v8m0 0l3-3m-3 3L9 8m-5 5h2.586a1 1 0 01.707.293l2.414 2.414a1 1 0 00.707.293h3.172a1 1 0 00.707-.293l2.414-2.414a1 1 0 01.707-.293H20" />
</svg>
Receive Container
</a>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white" id="expediteNav">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
Expedite Container
</a>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01" />
</svg>
Daily Log
</a>
<div class="px-4 py-2 mt-6 text-xs text-blue-300 uppercase tracking-wider">System</div>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Settings
</a>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Help
</a>
</nav>
<div class="p-4 border-t border-blue-700">
<div class="flex items-center">
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold">
BS
</div>
<div class="ml-3">
<p class="text-sm font-medium">John Smith</p>
<p class="text-xs text-blue-300">Barrier Staff</p>
</div>
<button class="ml-auto text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
</button>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="content-area flex-1 overflow-y-auto">
@ -198,244 +139,6 @@
</div>
</header>
<!-- Container Reception Content -->
<div id="receiveContent" class="tab-content active p-6">
<div class="bg-white rounded-lg shadow mb-6">
<div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
<div>
<h3 class="text-lg font-semibold text-gray-800">Container Reception</h3>
<p class="text-sm text-gray-600 mt-1">Process incoming containers</p>
</div>
<div class="flex items-center">
<span class="bg-green-100 text-green-800 text-xs font-semibold px-3 py-1 rounded-full">Gate Open</span>
</div>
</div>
<div class="p-6">
<form id="receiveForm" class="space-y-6">
<div class="form-section grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="md:col-span-2">
<label for="containerNumber" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>
<div class="flex">
<input type="text" id="containerNumber" name="containerNumber" placeholder="e.g. MSCU1234567" class="flex-1 px-4 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<button type="button" id="searchContainer" class="px-4 py-2 bg-blue-600 text-white rounded-r-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Search
</button>
</div>
<p class="mt-1 text-xs text-gray-500">Enter the full container number including prefix</p>
</div>
<div>
<label for="arrivalDate" class="block text-sm font-medium text-gray-700 mb-1">Arrival Date</label>
<input type="date" id="arrivalDate" name="arrivalDate" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required value="">
</div>
</div>
<!-- Container Preinfo Data (initially hidden) -->
<div id="preinfoData" class="hidden">
<div class="bg-blue-50 border border-blue-200 rounded-md p-4 mb-6">
<div class="flex items-start">
<div class="flex-shrink-0">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-blue-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="ml-3 flex-1">
<h3 class="text-sm font-medium text-blue-800">Preinfo Found</h3>
<div class="mt-2 text-sm text-blue-700">
<div class="grid grid-cols-2 gap-4">
<div>
<p><span class="font-medium">Container Type:</span> <span id="preinfoType">40HC</span></p>
<p><span class="font-medium">Line Operator:</span> <span id="preinfoOperator">Maersk Line</span></p>
</div>
<div>
<p><span class="font-medium">Expected Arrival:</span> <span id="preinfoArrival">2023-06-18</span></p>
<p><span class="font-medium">Vessel/Voyage:</span> <span id="preinfoVessel">MAERSK SEVILLE / 123E</span></p>
</div>
</div>
<p class="mt-2"><span class="font-medium">Notes:</span> <span id="preinfoNotes">Container reported with minor damage on right side panel.</span></p>
</div>
</div>
</div>
</div>
<div class="form-section grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="containerType" class="block text-sm font-medium text-gray-700 mb-1">Container Type</label>
<select id="containerType" name="containerType" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<option value="">Select container type</option>
<option value="20DV">20' Dry Van (20DV)</option>
<option value="40DV">40' Dry Van (40DV)</option>
<option value="40HC" selected>40' High Cube (40HC)</option>
<option value="20RF">20' Reefer (20RF)</option>
<option value="40RF">40' Reefer (40RF)</option>
<option value="20OT">20' Open Top (20OT)</option>
<option value="40OT">40' Open Top (40OT)</option>
<option value="20FR">20' Flat Rack (20FR)</option>
<option value="40FR">40' Flat Rack (40FR)</option>
</select>
</div>
<div>
<label for="truckInfo" class="block text-sm font-medium text-gray-700 mb-1">Truck Information</label>
<input type="text" id="truckInfo" name="truckInfo" placeholder="License plate / Company" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
</div>
<div class="form-section">
<label class="block text-sm font-medium text-gray-700 mb-3">Container Condition</label>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="flex items-center">
<input type="radio" id="conditionGood" name="containerCondition" value="good" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300">
<label for="conditionGood" class="ml-2 block text-sm text-gray-700">Good Condition</label>
</div>
<div class="flex items-center">
<input type="radio" id="conditionMinor" name="containerCondition" value="minor" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300" checked>
<label for="conditionMinor" class="ml-2 block text-sm text-gray-700">Minor Damage</label>
</div>
<div class="flex items-center">
<input type="radio" id="conditionMajor" name="containerCondition" value="major" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300">
<label for="conditionMajor" class="ml-2 block text-sm text-gray-700">Major Damage</label>
</div>
</div>
</div>
<div class="form-section">
<label for="damageDescription" class="block text-sm font-medium text-gray-700 mb-1">Damage Description</label>
<textarea id="damageDescription" name="damageDescription" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Describe any damage in detail">Minor dent on right side panel, approximately 30cm x 20cm. No structural damage.</textarea>
</div>
<div class="form-section">
<label class="block text-sm font-medium text-gray-700 mb-3">Container Images</label>
<p class="text-sm text-gray-600 mb-3">Take photos of the container from different angles, especially any damaged areas</p>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
<div class="image-preview has-image" id="preview1">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
<svg class="w-full h-full" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="20" width="100" height="80" fill="#2563eb" />
<rect x="20" y="30" width="30" height="20" fill="#1e40af" />
<rect x="70" y="30" width="30" height="20" fill="#1e40af" />
<rect x="20" y="60" width="80" height="30" fill="#1e40af" />
<circle cx="85" cy="45" r="8" fill="#ef4444" />
</svg>
</div>
<div class="image-preview has-image" id="preview2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
<svg class="w-full h-full" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="20" width="100" height="80" fill="#2563eb" />
<rect x="20" y="30" width="80" height="20" fill="#1e40af" />
<rect x="20" y="60" width="80" height="30" fill="#1e40af" />
<path d="M85,40 Q95,50 85,60 Q75,50 85,40" fill="#ef4444" />
</svg>
</div>
<div class="image-preview" id="preview3">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
</div>
<div class="image-preview" id="preview4">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
</div>
</div>
<button type="button" id="takePhoto" class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Take Photo
</button>
</div>
<div class="form-section">
<label for="positionLocation" class="block text-sm font-medium text-gray-700 mb-1">Position Location</label>
<input type="text" id="positionLocation" name="positionLocation" placeholder="e.g. Block A, Row 3, Position 5" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
</div>
<div class="form-section flex justify-end">
<button type="submit" class="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
Complete Reception
</button>
</div>
</div>
</form>
</div>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Recent Container Movements</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Line</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Direction</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">MSCU1234567</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40HC</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">Maersk</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">10:15 AM</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">IN</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Complete</span>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">CMAU7654321</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20DV</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">CMA CGM</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">09:42 AM</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">OUT</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Complete</span>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">OOLU2468135</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">40DV</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">ONE</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">09:15 AM</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">IN</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Complete</span>
</td>
</tr>
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">HLXU1357924</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">20RF</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">Hapag-Lloyd</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">08:30 AM</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">OUT</td>
<td class="px-4 py-3 whitespace-nowrap">
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Complete</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Container Expedition Content -->
<div id="expediteContent" class="tab-content p-6">
<div class="bg-white rounded-lg shadow mb-6">

@ -0,0 +1,593 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Barrier Staff Interface | Container Depot</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.sidebar {
background: linear-gradient(180deg, #0f4c81 0%, #1a6baf 100%);
transition: all 0.3s;
}
.content-area {
transition: all 0.3s;
}
.nav-item {
transition: all 0.2s;
}
.nav-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid white;
}
.card {
transition: all 0.3s;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.tab {
transition: all 0.2s;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.form-section {
animation: slideIn 0.5s ease-in-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.camera-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.9);
z-index: 50;
display: none;
animation: fadeIn 0.3s ease-in-out;
}
.camera-frame {
border: 2px solid #fff;
box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.5);
}
.image-preview {
width: 120px;
height: 120px;
background-color: #f3f4f6;
border: 2px dashed #d1d5db;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-preview svg {
color: #9ca3af;
}
.image-preview.has-image {
border: none;
}
.image-preview.has-image svg {
display: none;
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 10px rgba(255, 0, 0, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(255, 0, 0, 0);
}
}
</style>
</head>
<body class="flex h-screen overflow-hidden">
<!-- Sidebar -->
<!-- Main Content -->
<main class="content-area flex-1 overflow-y-auto">
<!-- Top Navigation -->
<header class="bg-white shadow-sm">
<div class="flex items-center justify-between px-6 py-4">
<div class="flex items-center">
<h2 class="text-xl font-semibold text-gray-800">Receive Container</h2>
</div>
<div class="flex items-center space-x-4">
<div class="relative">
<span class="absolute top-0 right-0 -mt-1 -mr-1 flex h-4 w-4">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-4 w-4 bg-red-500 text-xs text-white justify-center items-center">3</span>
</span>
<button class="text-gray-500 hover:text-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
</div>
<span class="text-gray-700 font-medium">Gate North</span>
</div>
</div>
</header>
<!-- Container Reception Content -->
<div id="receiveContent" class="tab-content active p-6">
<div class="bg-white rounded-lg shadow mb-6">
<div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
<div>
<h3 class="text-lg font-semibold text-gray-800">Container Reception</h3>
<p class="text-sm text-gray-600 mt-1">Process incoming containers</p>
</div>
<div class="flex items-center">
<span class="bg-green-100 text-green-800 text-xs font-semibold px-3 py-1 rounded-full">Gate Open</span>
</div>
</div>
<form id="receiveForm" class="space-y-6" method="POST">
{% csrf_token %}
<div class="p-6">
<label for="id_number" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>
{# <label for="id_number" >Container Number</label>#}
{# <input type="text" id="id_number" name="number" placeholder="Enter Container Number" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 mb-4">#}
{# <button type="button" id="check-preinfo-btn">Check Preinfo</button>#}
{# <label for="containerNumber" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>#}
{# <div class="flex">#}
{# <input type="text" id="id_number" name="number" class="flex-1 px-4 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>#}
{# <button type="button" id="check-preinfo-btn" class="px-4 py-2 bg-blue-600 text-white rounded-r-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">#}
{# Search#}
{# </button>#}
{# </div>#}
</div>
<div id="preinfoData">
<div class="bg-blue-50 border border-blue-200 rounded-md p-4 mb-6">
<div class="flex items-start">
<div class="flex-shrink-0">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-blue-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div class="ml-3 flex-1">
<h3 class="text-sm font-medium text-blue-800">Preinfo Found</h3>
<div class="mt-2 text-sm text-blue-700">
<div class="grid grid-cols-2 gap-4">
<div>
<div>
<span class="font-medium">Container Number:</span>
<input type="text" id="id_number" name="number" value="{{ preinfo.container_number }}" readonly>
</div>
<div>
<span class="font-medium">Container Type:</span>
<input type="text" id="id_container_type" name="id_container_type" value="{{ preinfo.container_type }}" readonly>
</div>
<div>
<span class="font-medium">Line Operator:</span>
<input type="text" id="id_line" name="id_line" value="{{ preinfo.line.name }}" readonly>
</div>
</div>
</div>
{# <p class="mt-2"><span class="font-medium">Notes:</span> <span id="preinfoNotes">Container reported with minor damage on right side panel.</span></p>#}
</div>
</div>
</div>
</div>
</div>
<div>
<label for="id_receive_vehicle">Receive vehicle:</label>
<input type="text" name="receive_vehicle" maxlength="100" id="id_receive_vehicle">
</div>
<div>
<label for="id_damages">Damages:</label>
<textarea name="damages" cols="40" rows="10" id="id_damages"></textarea>
</div>
<div>
<label for="id_heavy_damaged">Heavy damaged:</label>
<input type="checkbox" name="heavy_damaged" id="id_heavy_damaged">
</div>
<div>
<label for="id_position">Position:</label>
<input type="text" name="position" maxlength="100" id="id_position">
</div>
<div class="form-section flex justify-end">
<button type="submit" class="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
Complete Reception
</button>
</div>
<input type="hidden" name="preinfo_id" id="preinfo_id" value="{{ preinfo.pk }}">
</form>
</div>
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-800">Recent Container Movements</h3>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Container</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Line</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
{# <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Direction</th>#}
{# <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>#}
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{% for container in containers %}
<tr>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
{{ container.number }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ container.container_type }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ container.line.name }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ container.received_on }}</td>
{# <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">IN</td>#}
{# <td class="px-4 py-3 whitespace-nowrap">#}
{# <span class="px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800">Complete</span>#}
{# </td>#}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Container Expedition Content -->
</main>
<!-- Camera Overlay -->
<div id="cameraOverlay" class="camera-overlay">
<div class="h-full flex flex-col">
<div class="p-4 flex justify-between items-center">
<h3 class="text-lg font-semibold text-white">Take Container Photo</h3>
<button id="closeCamera" class="text-white hover:text-gray-300">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="flex-grow flex items-center justify-center p-4">
<div class="relative">
<div class="camera-frame w-full max-w-2xl aspect-[4/3] bg-gray-800 flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-24 w-24 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<!-- Guide lines for container positioning -->
<div class="absolute inset-0 border-2 border-dashed border-white opacity-50 m-8"></div>
<!-- Positioning guides -->
<div class="absolute top-8 left-8 border-t-2 border-l-2 border-white w-8 h-8"></div>
<div class="absolute top-8 right-8 border-t-2 border-r-2 border-white w-8 h-8"></div>
<div class="absolute bottom-8 left-8 border-b-2 border-l-2 border-white w-8 h-8"></div>
<div class="absolute bottom-8 right-8 border-b-2 border-r-2 border-white w-8 h-8"></div>
</div>
</div>
</div>
<div class="p-4 flex justify-center">
<button id="capturePhoto" class="w-16 h-16 rounded-full bg-red-600 border-4 border-white flex items-center justify-center pulse">
<div class="w-12 h-12 rounded-full bg-red-600"></div>
</button>
</div>
</div>
</div>
{# <script>#}
{# // Set current date as default#}
{# const today = new Date().toISOString().split('T')[0];#}
{# document.getElementById('arrivalDate').value = today;#}
{# document.getElementById('expeditionDate').value = today;#}
{# #}
{# // Tab Navigation#}
{# const receiveContent = document.getElementById('receiveContent');#}
{# const expediteContent = document.getElementById('expediteContent');#}
{# #}
{# const receiveNav = document.getElementById('receiveNav');#}
{# const expediteNav = document.getElementById('expediteNav');#}
{# #}
{# receiveNav.addEventListener('click', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // Update content visibility#}
{# receiveContent.classList.add('active');#}
{# expediteContent.classList.remove('active');#}
{# #}
{# // Update navigation styling#}
{# document.querySelector('.nav-item.active').classList.remove('active');#}
{# receiveNav.classList.add('active');#}
{# #}
{# // Update header title#}
{# document.querySelector('header h2').textContent = 'Receive Container';#}
{# });#}
{# #}
{# expediteNav.addEventListener('click', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // Update content visibility#}
{# receiveContent.classList.remove('active');#}
{# expediteContent.classList.add('active');#}
{# #}
{# // Update navigation styling#}
{# document.querySelector('.nav-item.active').classList.remove('active');#}
{# expediteNav.classList.add('active');#}
{# #}
{# // Update header title#}
{# document.querySelector('header h2').textContent = 'Expedite Container';#}
{# });#}
{# #}
{# // Container search functionality#}
{# document.getElementById('searchContainer').addEventListener('click', function() {#}
{# const containerNumber = document.getElementById('containerNumber').value;#}
{# if (containerNumber) {#}
{# document.getElementById('preinfoData').classList.remove('hidden');#}
{# } else {#}
{# alert('Please enter a container number');#}
{# }#}
{# });#}
{# #}
{# document.getElementById('searchExpediteContainer').addEventListener('click', function() {#}
{# const containerNumber = document.getElementById('expediteContainerNumber').value;#}
{# if (containerNumber) {#}
{# document.getElementById('orderData').classList.remove('hidden');#}
{# } else {#}
{# alert('Please enter a container number');#}
{# }#}
{# });#}
{# #}
{# // Camera functionality#}
{# const cameraOverlay = document.getElementById('cameraOverlay');#}
{# const takePhotoBtn = document.getElementById('takePhoto');#}
{# const expediteTakePhotoBtn = document.getElementById('expediteTakePhoto');#}
{# const closeCamera = document.getElementById('closeCamera');#}
{# const capturePhoto = document.getElementById('capturePhoto');#}
{# #}
{# let currentImageTarget = null;#}
{# #}
{# function openCamera(imageTarget) {#}
{# cameraOverlay.style.display = 'block';#}
{# currentImageTarget = imageTarget;#}
{# }#}
{# #}
{# takePhotoBtn.addEventListener('click', function() {#}
{# // Find the first empty preview slot#}
{# for (let i = 1; i <= 4; i++) {#}
{# const previewEl = document.getElementById(`preview${i}`);#}
{# if (!previewEl.classList.contains('has-image')) {#}
{# openCamera(`preview${i}`);#}
{# break;#}
{# }#}
{# }#}
{# });#}
{# #}
{# expediteTakePhotoBtn.addEventListener('click', function() {#}
{# // Find the first empty preview slot#}
{# for (let i = 1; i <= 2; i++) {#}
{# const previewEl = document.getElementById(`expeditePreview${i}`);#}
{# if (!previewEl.classList.contains('has-image')) {#}
{# openCamera(`expeditePreview${i}`);#}
{# break;#}
{# }#}
{# }#}
{# });#}
{# #}
{# closeCamera.addEventListener('click', function() {#}
{# cameraOverlay.style.display = 'none';#}
{# });#}
{# #}
{# capturePhoto.addEventListener('click', function() {#}
{# if (currentImageTarget) {#}
{# const previewEl = document.getElementById(currentImageTarget);#}
{# #}
{# // Create a container SVG image#}
{# const containerSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");#}
{# containerSvg.setAttribute("class", "w-full h-full");#}
{# containerSvg.setAttribute("viewBox", "0 0 120 120");#}
{# #}
{# // Random container color#}
{# const colors = ['#2563eb', '#059669', '#d97706', '#7c3aed'];#}
{# const randomColor = colors[Math.floor(Math.random() * colors.length)];#}
{# #}
{# // Create container body#}
{# const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");#}
{# rect.setAttribute("x", "10");#}
{# rect.setAttribute("y", "20");#}
{# rect.setAttribute("width", "100");#}
{# rect.setAttribute("height", "80");#}
{# rect.setAttribute("fill", randomColor);#}
{# containerSvg.appendChild(rect);#}
{# #}
{# // Add some container details#}
{# const detail1 = document.createElementNS("http://www.w3.org/2000/svg", "rect");#}
{# detail1.setAttribute("x", "20");#}
{# detail1.setAttribute("y", "30");#}
{# detail1.setAttribute("width", "80");#}
{# detail1.setAttribute("height", "20");#}
{# detail1.setAttribute("fill", shadeColor(randomColor, -20));#}
{# containerSvg.appendChild(detail1);#}
{# #}
{# const detail2 = document.createElementNS("http://www.w3.org/2000/svg", "rect");#}
{# detail2.setAttribute("x", "20");#}
{# detail2.setAttribute("y", "60");#}
{# detail2.setAttribute("width", "80");#}
{# detail2.setAttribute("height", "30");#}
{# detail2.setAttribute("fill", shadeColor(randomColor, -20));#}
{# containerSvg.appendChild(detail2);#}
{# #}
{# // Clear the preview and add the new SVG#}
{# previewEl.innerHTML = '';#}
{# previewEl.appendChild(containerSvg);#}
{# previewEl.classList.add('has-image');#}
{# #}
{# // Close the camera#}
{# cameraOverlay.style.display = 'none';#}
{# }#}
{# });#}
{# #}
{# // Helper function to darken/lighten colors#}
{# function shadeColor(color, percent) {#}
{# let R = parseInt(color.substring(1,3), 16);#}
{# let G = parseInt(color.substring(3,5), 16);#}
{# let B = parseInt(color.substring(5,7), 16);#}
{# #}
{# R = parseInt(R * (100 + percent) / 100);#}
{# G = parseInt(G * (100 + percent) / 100);#}
{# B = parseInt(B * (100 + percent) / 100);#}
{# #}
{# R = (R<255)?R:255; #}
{# G = (G<255)?G:255; #}
{# B = (B<255)?B:255; #}
{# #}
{# R = Math.round(R);#}
{# G = Math.round(G);#}
{# B = Math.round(B);#}
{# #}
{# const RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));#}
{# const GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));#}
{# const BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));#}
{# #}
{# return "#"+RR+GG+BB;#}
{# }#}
{# #}
{# // Form submissions#}
{# document.getElementById('receiveForm').addEventListener('submit', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // Check if container data is loaded#}
{# if (document.getElementById('preinfoData').classList.contains('hidden')) {#}
{# alert('Please search for a container first');#}
{# return;#}
{# }#}
{# #}
{# // In a real app, this would send data to the server#}
{# alert('Container reception completed successfully!');#}
{# this.reset();#}
{# document.getElementById('preinfoData').classList.add('hidden');#}
{# #}
{# // Reset image previews#}
{# for (let i = 1; i <= 4; i++) {#}
{# const previewEl = document.getElementById(`preview${i}`);#}
{# previewEl.classList.remove('has-image');#}
{# previewEl.innerHTML = `#}
{# <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">#}
{# <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />#}
{# </svg>#}
{# `;#}
{# }#}
{# #}
{# // Add the first two images back#}
{# document.getElementById('preview1').classList.add('has-image');#}
{# document.getElementById('preview1').innerHTML = `#}
{# <svg class="w-full h-full" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">#}
{# <rect x="10" y="20" width="100" height="80" fill="#2563eb" />#}
{# <rect x="20" y="30" width="30" height="20" fill="#1e40af" />#}
{# <rect x="70" y="30" width="30" height="20" fill="#1e40af" />#}
{# <rect x="20" y="60" width="80" height="30" fill="#1e40af" />#}
{# <circle cx="85" cy="45" r="8" fill="#ef4444" />#}
{# </svg>#}
{# `;#}
{# #}
{# document.getElementById('preview2').classList.add('has-image');#}
{# document.getElementById('preview2').innerHTML = `#}
{# <svg class="w-full h-full" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">#}
{# <rect x="10" y="20" width="100" height="80" fill="#2563eb" />#}
{# <rect x="20" y="30" width="80" height="20" fill="#1e40af" />#}
{# <rect x="20" y="60" width="80" height="30" fill="#1e40af" />#}
{# <path d="M85,40 Q95,50 85,60 Q75,50 85,40" fill="#ef4444" />#}
{# </svg>#}
{# `;#}
{# });#}
{# #}
{# document.getElementById('expediteForm').addEventListener('submit', function(e) {#}
{# e.preventDefault();#}
{# #}
{# // Check if order data is loaded#}
{# if (document.getElementById('orderData').classList.contains('hidden')) {#}
{# alert('Please search for a container first');#}
{# return;#}
{# }#}
{# #}
{# // In a real app, this would send data to the server#}
{# alert('Container expedition completed successfully!');#}
{# this.reset();#}
{# document.getElementById('orderData').classList.add('hidden');#}
{# #}
{# // Reset image previews#}
{# for (let i = 1; i <= 2; i++) {#}
{# const previewEl = document.getElementById(`expeditePreview${i}`);#}
{# previewEl.classList.remove('has-image');#}
{# previewEl.innerHTML = `#}
{# <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">#}
{# <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />#}
{# </svg>#}
{# `;#}
{# }#}
{# });#}
{# </script>#}
{#<script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'9498ddc2d702313f',t:'MTc0ODg4NzM5My4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body>#}
{##}
{#<script>#}
{#document.getElementById('check-preinfo-btn').onclick = function() {#}
{# const number = document.getElementById('id_number').value;#}
{# fetch(`/preinfo/check-preinfo/?number=${encodeURIComponent(number)}`)#}
{# .then(response => response.json())#}
{# .then(data => {#}
{# if (data.found) {#}
{# alert('Preinfo found ' + data.container_type);#}
{# document.getElementById('id_line').value = data.line;#}
{# document.getElementById('id_container_type').value = data.container_type;#}
{# document.getElementById('preinfo_id').value = data.preinfo_id;#}
{# } else {#}
{# alert('No preinfo found or already received.');#}
{# }#}
{# });#}
{#;#}
{#</script>#}
</body>
</html>

@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Barrier Staff Interface | Container Depot</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.sidebar {
background: linear-gradient(180deg, #0f4c81 0%, #1a6baf 100%);
transition: all 0.3s;
}
.content-area {
transition: all 0.3s;
}
.nav-item {
transition: all 0.2s;
}
.nav-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid white;
}
.card {
transition: all 0.3s;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.tab {
transition: all 0.2s;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.form-section {
animation: slideIn 0.5s ease-in-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.camera-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.9);
z-index: 50;
display: none;
animation: fadeIn 0.3s ease-in-out;
}
.camera-frame {
border: 2px solid #fff;
box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.5);
}
.image-preview {
width: 120px;
height: 120px;
background-color: #f3f4f6;
border: 2px dashed #d1d5db;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-preview svg {
color: #9ca3af;
}
.image-preview.has-image {
border: none;
}
.image-preview.has-image svg {
display: none;
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 10px rgba(255, 0, 0, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(255, 0, 0, 0);
}
}
</style>
</head>
<body>
<form method="post">
{% csrf_token %}
<div class="p-6">
<label for="id_number" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>
<div class="flex">
<input type="text" id="id_number" name="number" class="flex-1 px-4 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<button type="submit" id="check-preinfo-btn" class="px-4 py-2 bg-blue-600 text-white rounded-r-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Search
</button>
<input type="hidden" name="param" value="{{ request.GET.param }}">
{% if error %}
<div class="ml-4 text-red-600">
{{ error }}
</div>
{% endif %}
</div>
</div>
</form>
</body>
</html>

@ -0,0 +1,126 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Barrier Staff Interface | Container Depot</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.sidebar {
background: linear-gradient(180deg, #0f4c81 0%, #1a6baf 100%);
transition: all 0.3s;
}
.content-area {
transition: all 0.3s;
}
.nav-item {
transition: all 0.2s;
}
.nav-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
.nav-item.active {
background-color: rgba(255, 255, 255, 0.2);
border-left: 4px solid white;
}
.card {
transition: all 0.3s;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.tab {
transition: all 0.2s;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
animation: fadeIn 0.5s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.form-section {
animation: slideIn 0.5s ease-in-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.camera-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.9);
z-index: 50;
display: none;
animation: fadeIn 0.3s ease-in-out;
}
.camera-frame {
border: 2px solid #fff;
box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.5);
}
.image-preview {
width: 120px;
height: 120px;
background-color: #f3f4f6;
border: 2px dashed #d1d5db;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-preview svg {
color: #9ca3af;
}
.image-preview.has-image {
border: none;
}
.image-preview.has-image svg {
display: none;
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(255, 0, 0, 0.7);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 10px rgba(255, 0, 0, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(255, 0, 0, 0);
}
}
</style>
</head>
<body>
<form method="post">
{% csrf_token %}
<div class="p-6">
<label for="id_number" class="block text-sm font-medium text-gray-700 mb-1">Container Number</label>
<div class="flex">
<input type="text" id="id_number" name="number" class="flex-1 px-4 py-2 border border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500" required>
<button type="submit" id="check-preinfo-btn" class="px-4 py-2 bg-blue-600 text-white rounded-r-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Search
</button>
<input type="hidden" name="param" value="{{ request.GET.param }}">
</div>
</div>
</form>
</body>
</html>

@ -0,0 +1,96 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Container Depot Management System</title>
<link rel="stylesheet" href="{% static '/css/styles.css' %}"/>
</head>
<body>
{# {{ title|default:"Container Depot Management System" }} {{ description|default:"Login to the Container Depot Management System" }}#}
<div class="background-image"></div>
<div class="wave"></div>
<div class="login-container">
<!-- Left side - Login Form -->
<div class="login-form-section">
<div>
<h1>Container Depot</h1>
<p class="subtitle">Sign in to access the management system</p>
</div>
<form id="loginForm" method="post" action="{% url 'login' %}"
>
{% csrf_token %}
{{ form }}
<div>
<button type="submit" class="submit-button" >
Sign In
</button>
</div>
</form>
<div>
<p>Need help? Contact system administrator</p>
</div>
</div>
<!-- Right side - Info -->
<div class="info-section">
<div>
<h2>Container Depot Management System</h2>
<div>
<div class="feature-item">
<div class="feature-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path>
</svg>
</div>
<div>
<h3>Line Operators</h3>
<p class="feature-text">Manage container preinfo and expedition orders</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
</div>
<div>
<h3>Barrier Staff</h3>
<p class="feature-text">Process container arrivals and departures</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
</svg>
</div>
<div>
<h3>Depot Management</h3>
<p class="feature-text">View inventory and generate reports</p>
</div>
</div>
</div>
</div>
<div>
<div class="version-info">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z"></path>
</svg>
<span>Version 1.0.0</span>
</div>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,61 @@
{% load static %}
<aside class="sidebar w-64 h-full text-white flex flex-col">
<div class="p-5 border-b border-blue-700">
<h1 class="text-xl font-bold">Container Depot</h1>
<p class="text-sm text-blue-200">Line Operator Portal</p>
</div>
<nav class="flex-grow py-4">
<div class="px-4 py-2 text-xs text-blue-300 uppercase tracking-wider">Main</div>
<a href="{% url 'dashboard' %}" class="nav-item active flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Dashboard
</a>
<a href="{% url 'client_preinfo' %}" id="preinfoNav" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
Container Preinfo
</a>
<a href="{% url 'container_search' %}?param=container_receive" id="ordersNav" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
</svg>
Expedition Orders
</a>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
Reports
</a>
<div class="px-4 py-2 mt-6 text-xs text-blue-300 uppercase tracking-wider">Account</div>
<a href="#" class="nav-item flex items-center px-6 py-3 text-white">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
Settings
</a>
</nav>
<div class="p-4 border-t border-blue-700">
<div class="flex items-center">
<div class="w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold">
LO
</div>
<div class="ml-3">
<p class="text-sm font-medium">{{ request.user }}</p>
<p class="text-xs text-blue-300">{{ request.user.company }}</p>
</div>
<button class="ml-auto text-white" onclick="{% url 'relogin' %}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
</svg>
</button>
</div>
</div>
</aside>

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

@ -1,5 +0,0 @@
from django.forms import forms
class LoginForm(forms.Form):
field_order = ['username', 'password']

@ -1,21 +0,0 @@
from django.contrib.auth.models import AbstractUser
from django.db import models
class DepotUser(AbstractUser):
USER_TYPES = (
('management', 'Management'),
('barrier', 'Barrier Staff'),
('client', 'Client'),
)
user_type = models.CharField(max_length=20, choices=USER_TYPES, default='client')
# Add any other fields you want
phone_number = models.CharField(max_length=15, blank=True, null=True)
email = models.EmailField(unique=True, blank=False, null=False)
line = models.ForeignKey(
'common.LinesModel',
on_delete=models.CASCADE,
related_name='user_lines',
blank=True,
null=True
)

@ -1,7 +0,0 @@
from django.urls import path
from users import views
urlpatterns = [
path('login/', views.LoginView.as_view(), name='login'),
]

@ -1,12 +0,0 @@
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import TemplateView, FormView
from users.forms import LoginForm
# Create your views here.
class LoginView(FormView):
template_name = 'logintest.html'
success_url = reverse_lazy('dashboard')
form_class = LoginForm
Loading…
Cancel
Save