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 da83ae7afc
commit 0eefaad424

@ -1,7 +1,47 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import AuthenticationForm
from django.core.exceptions import ValidationError
from django.forms import CharField
from django.forms.models import ModelForm
from django.forms.widgets import PasswordInput
class LoginForm(AuthenticationForm):
field_order = ['username', 'password']
class Meta:
model = get_user_model()
class RegisterForm(ModelForm):
password1 = CharField(label='Password', widget=PasswordInput)
password2 = CharField(label='Confirm Password', widget=PasswordInput)
field_order = ['username', 'email', 'password1', 'password2', 'phone_number', 'line', 'company_permissions']
class Meta:
model = get_user_model()
fields = ['username', 'email', 'password1', 'password2', 'phone_number', 'line', 'company_permissions']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].widget.attrs.update({'autocomplete': 'new-password'})
self.fields['password2'].widget.attrs.update({'autocomplete': 'new-password'})
def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get('password1')
password2 = cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise ValidationError("Passwords don't match")
return cleaned_data
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user

@ -2,6 +2,9 @@ from django.contrib.auth.models import AbstractUser
from django.db import models
class ClientPermission(models.Model):
codename = models.CharField(max_length=100, default='')
name = models.CharField(max_length=255, default='')
class Meta:
managed = True
default_permissions = ()
@ -10,7 +13,8 @@ class ClientPermission(models.Model):
('can_view_bookings', 'Can view bookings'),
('can_manage_company_users', 'Can manage company users'),
)
def __str__(self):
return self.name
class DepotUser(AbstractUser):

@ -5,4 +5,5 @@ from accounts import views
urlpatterns = [
path('login/', views.DepotLoginView.as_view(), name='login'),
path('relogin/', auth_views.logout_then_login, name='relogin'),
path('register/', views.RegisterView.as_view(), name='register'),
]

@ -1,9 +1,10 @@
from django.contrib.auth import get_user_model
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 django.views.generic import TemplateView, FormView, ListView, UpdateView
from accounts.forms import LoginForm
from accounts.forms import LoginForm, RegisterForm
# Create your views here.
@ -14,4 +15,27 @@ class DepotLoginView(LoginView):
next_page = reverse_lazy('dashboard')
class RegisterView(FormView):
template_name = 'registration/register.html'
form_class = RegisterForm
# model = get_user_model()
success_url = reverse_lazy('dashboard')
def form_valid(self, form):
# Create user from form data
user = form.save(commit=False)
# user.set_password(form.cleaned_data['password'])
user.save()
return super().form_valid(form)
class UserListView(ListView):
template_name = 'registration/register.html'
# form_class = RegisterForm
model = get_user_model()
success_url = reverse_lazy('dashboard')
class UserEditView(UpdateView):
template_name = 'registration/register.html'
form_class = RegisterForm
model = get_user_model()
success_url = reverse_lazy('dashboard')

@ -3,6 +3,13 @@ from common.models import ContainerTypeModel, LinesModel, OperationModel
# Create your models here.
class Booking(models.Model):
STATUS_CHOICES = [
('active', 'Active'),
('finished', 'Finished'),
('canceled', 'Canceled'),
]
number = models.CharField(max_length=50, unique=True)
vehicles = models.CharField(blank=True, null=True)
container_type = models.ForeignKey(
@ -21,8 +28,17 @@ class Booking(models.Model):
visible = models.BooleanField(default=True)
is_new = models.BooleanField(default=True)
container_number = models.CharField(max_length=11, blank=True, null=True)
vehicles_left = models.IntegerField(blank=True, null=True)
vehicles_left = models.CharField(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()
updated_by = models.IntegerField()
status = models.CharField(
max_length=10,
choices=STATUS_CHOICES,
default='active'
)
@property
def containers_left(self):
return self.container_count - (self.container_expedited_count or 0)

@ -12,7 +12,7 @@ class CreateBookingView(CreateView):
template_name = 'client-booking-content.html'
model = Booking
form_class = BookingCreateForm
success_url = reverse_lazy('dashboard')
success_url = reverse_lazy('client_booking')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -21,15 +21,25 @@ class CreateBookingView(CreateView):
# !!! 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.readonly = True #attrs['disabled'] = True
return form
def form_valid(self, form):
# todo more validation
form.instance.created_by = self.request.user.id
form.instance.updated_by = self.request.user.id
form.instance.vehicles_left = form.cleaned_data.get('vehicles')
if self.request.user.line:
form.instance.line = self.request.user.line
return super().form_valid(form)

@ -39,7 +39,7 @@ class ClientPreinfoView(LoginRequiredMixin, CreateView):
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
form.fields['line'].widget.readonly = True #form.fields['line'].widget.attrs['disabled'] = True
# Keep the value when form is submitted
# form.fields['line'].widget = HiddenInput()

@ -59,7 +59,14 @@
</head>
<body>
{% load static %}
<div class="sidebar w-64 h-full text-white flex flex-col">
<div class="sidebar p-5 text-white 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>
<div class="flex min-h-screen items-center justify-center">
<div class="sidebar w-[400px] h-[600px] text-white flex flex-col rounded-lg overflow-hidden">
<div class="sidebar w-[100%] 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>
@ -67,19 +74,19 @@
<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">
<a href="{% url 'barrier_dashboard' %}" class="nav-item active flex items-center px-6 py-10 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">
<a href="{% url 'preinfo_search' %}?param=container_receive" id="ordersNav" class="nav-item flex items-center px-6 py-10 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">
<a href="{% url 'container_search' %}?param=container_expedition" id="ordersNav" class="nav-item flex items-center px-6 py-10 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>
@ -92,7 +99,7 @@
Photos
</a>
<div class="px-4 py-2 mt-6 text-xs text-blue-300 uppercase tracking-wider">Account</div>
{# <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" />#}
@ -102,23 +109,25 @@
{# </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 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>
<div class="flex-grow"></div>
</div>
</div>
</body>
</html>

@ -4,8 +4,8 @@
<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>
<h3 class="text-lg font-semibold text-gray-800">Submit Booking</h3>
<p class="text-sm text-gray-600 mt-1">Create a booking for containers expedition by container type or by specific container numer</p>
</div>
<div class="p-6">
<form id="preinfoForm" class="space-y-6" method="POST" >
@ -35,6 +35,7 @@
<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">Container count</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Containers left</th>
{# <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Vehicles</th>#}
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Vehicles</th>
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
@ -48,10 +49,11 @@
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">{{ booking.container_number }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ booking.container_type }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ booking.container_count }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ booking.containers_left }}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-700">{{ booking.vehicles_left }}</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>
<span class="px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800">{{ booking.status }}</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>

@ -41,7 +41,7 @@
</svg>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-700">Pending Orders</h3>
<h3 class="text-lg font-semibold text-gray-700">Bookings</h3>
<p class="text-3xl font-bold text-gray-900">7</p>
<p class="text-sm text-orange-600">2 require attention</p>
</div>

@ -23,7 +23,7 @@
<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
Bookings
</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">

@ -5,7 +5,9 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>K-DepoT | Kikimor EOOD</title>
<title>
K-DepoT | Kikimor EOOD</title>
<style>
body {
font-family: Arial, sans-serif;
@ -89,7 +91,10 @@ header {
<header>
<div class="header-content">
<h1>K-DepoT</h1>
<h1>
<img src="{% static 'images/k-depot-logo.svg' %}" alt="K-DepoT Logo" style="height: 150px; vertical-align: middle;">
K-DepoT
</h1>
<p>Operated by Kikimor EOOD</p>
</div>
<a href="{% url 'login' %}" class="login-link">Login</a>

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<video id="video" autoplay></video>
<canvas id="canvas" style="display:none;"></canvas>
<button onclick="takePhoto()">Take Photo</button>
<script>
const video = document.getElementById('video');
// Request camera access
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => video.srcObject = stream)
.catch(err => console.error("Camera access denied", err));
function takePhoto() {
const canvas = document.getElementById('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
// Draw current frame
const context = canvas.getContext('2d');
context.drawImage(video, 0, 0);
// Convert to base64 or Blob
canvas.toBlob(blob => {
// Upload blob to server
const formData = new FormData();
formData.append("photo", blob, "photo.jpg");
fetch("https://your-upload-url.com/upload", {
method: "POST",
body: formData
}).then(res => console.log("Uploaded"))
.catch(err => console.error("Upload failed", err));
}, "image/jpeg");
}
</script>
</body>
</html>

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register User</title>
</head>
<body>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Register</button>
</form>
</body>
</html>
Loading…
Cancel
Save