Initial commit
0
company_site/company_site/__init__.py
Normal file
16
company_site/company_site/asgi.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
ASGI config for company_site project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'company_site.settings')
|
||||
|
||||
application = get_asgi_application()
|
||||
149
company_site/company_site/settings.py
Normal file
@@ -0,0 +1,149 @@
|
||||
"""
|
||||
Django settings for company_site project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 5.0.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/5.0/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-0$+hho_6%-(ud^t%0zos(q&i@2&)9m+u&dgj77&51g$m#hr^0s'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'public.apps.PublicConfig',
|
||||
'financial.apps.FinancialConfig',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'phonenumber_field',
|
||||
'django_recaptcha',
|
||||
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'company_site.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'company_site.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.0/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/5.0/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
# # email settings
|
||||
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
# EMAIL_USE_TLS = True
|
||||
# EMAIL_HOST = 'smtp.outlook.office365.com'#'smtp-mail.outlook.com'
|
||||
# EMAIL_HOST_USERNAME = 'ryan@aimloperations.com'
|
||||
# EMAIL_HOST_USER = 'ryan@aimloperations.com'
|
||||
# EMAIL_HOST_PASSWORD = '!HopeThisW0rkz'
|
||||
# EMAIL_PORT = 587
|
||||
# SERVER_EMAIL = EMAIL_HOST_USER
|
||||
|
||||
# Recapcha Stuff
|
||||
RECAPTCHA_PUBLIC_KEY = '6LdXRbopAAAAAL9NT7C2J3Fuu_b6rvhhsPyxTd9Z'
|
||||
RECAPTCHA_PRIVATE_KEY = '6LdXRbopAAAAAPt31zdQJaOwLseognmZHZEHmWlt'
|
||||
|
||||
# SMTP2GO
|
||||
EMAIL_HOST = 'mail.smtp2go.com'
|
||||
EMAIL_HOST_USER = 'info.aimloperations.com'
|
||||
EMAIL_HOST_PASSWORD = 'ZDErIII2sipNNVMz'
|
||||
EMAIL_PORT = 2525
|
||||
EMAIL_USE_TLS = True
|
||||
25
company_site/company_site/urls.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""
|
||||
URL configuration for company_site project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/5.0/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
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.urls import include, path
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("public/", include("public.urls")),
|
||||
path("financial/", include("financial.urls")),
|
||||
path('admin/', admin.site.urls),
|
||||
]
|
||||
16
company_site/company_site/wsgi.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for company_site project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'company_site.settings')
|
||||
|
||||
application = get_wsgi_application()
|
||||
0
company_site/financial/__init__.py
Normal file
8
company_site/financial/admin.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from .models import Contract
|
||||
# Register your models here.
|
||||
|
||||
class ContractAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
|
||||
admin.site.register(Contract, ContractAdmin)
|
||||
6
company_site/financial/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class FinancialConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'financial'
|
||||
20
company_site/financial/forms.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from django import forms
|
||||
|
||||
from django.forms import ModelForm
|
||||
from .models import Employee, Contract, ChargeNumber
|
||||
|
||||
class EmployeeForm(ModelForm):
|
||||
class Meta:
|
||||
model = Employee
|
||||
# TODO: fix slary to be salary
|
||||
fields = ["primaryAddress","workAddress", "slary"]
|
||||
|
||||
class ContractForm(ModelForm):
|
||||
class Meta:
|
||||
model = Contract
|
||||
fields = ["contract_type","name","proposed_amount","baseline_amount","funded_amount","baseline_start","baseline_end"]
|
||||
|
||||
class ChargeNumberForm(ModelForm):
|
||||
class Meta:
|
||||
model = ChargeNumber
|
||||
fields = ["charge_number_type","amount", "start_date","end_date"]
|
||||
120
company_site/financial/migrations/0001_initial.py
Normal file
@@ -0,0 +1,120 @@
|
||||
# Generated by Django 5.0 on 2024-02-11 20:29
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import django_enum.fields
|
||||
import phonenumber_field.modelfields
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AddressModel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('address_1', models.CharField(max_length=128)),
|
||||
('address_2', models.CharField(blank=True, max_length=128)),
|
||||
('city', models.CharField(max_length=64)),
|
||||
('state', models.CharField(max_length=2)),
|
||||
('zip_code', models.CharField(max_length=5)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Contract',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('last_modified', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('slug', models.SlugField()),
|
||||
('contract_type', django_enum.fields.EnumCharField(choices=[('FFP', 'FIRM_FIX_PRICED'), ('MAX', 'MAX_NUM_CONTRACT_TYPES')], max_length=3)),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('proposed_amount', models.FloatField(default=0.0)),
|
||||
('baseline_amount', models.FloatField(default=0.0)),
|
||||
('funded_amount', models.FloatField(default=0.0)),
|
||||
('baseline_start', models.DateField(default=None, null=True)),
|
||||
('baseline_end', models.DateField(default=None, null=True)),
|
||||
('linkedContracts', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='financial.contract')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ChargeNumber',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('last_modified', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('slug', models.SlugField()),
|
||||
('charge_number_type', django_enum.fields.EnumCharField(choices=[('LOE', 'LEVEL_OF_EFFORT'), ('QBD', 'QBD'), ('0_100', 'ZERO_ONE_HUNDRED'), ('50_50', 'FIFTY_FIFTY'), ('MAX', 'MAX_NUM_TASK_TYPES')], max_length=5)),
|
||||
('amount', models.FloatField(default=0.0)),
|
||||
('percent_complete', models.FloatField(default=0.0)),
|
||||
('startDate', models.DateField(default=None, null=True)),
|
||||
('endDate', models.DateField(default=None, null=True)),
|
||||
('contract', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='financial.contract')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Employee',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('last_modified', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('slug', models.SlugField()),
|
||||
('phoneNumber', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None, unique=True)),
|
||||
('slary', models.FloatField(default=0.0)),
|
||||
('manager', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='manager_employee', to='financial.employee')),
|
||||
('primaryAddress', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='primary_address_employee', to='financial.addressmodel')),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
('workAddress', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='work_address_employee', to='financial.addressmodel')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TimeCard',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('last_modified', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('slug', models.SlugField()),
|
||||
('startDate', models.DateField(default=None, null=True)),
|
||||
('endDate', models.DateField(default=None, null=True)),
|
||||
('approvedDate', models.DateField(default=None, null=True)),
|
||||
('approvalComment', models.TextField(default='', max_length=256)),
|
||||
('approvedBy', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='approved_by', to='financial.employee')),
|
||||
('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='employee', to='financial.employee')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TimeCardCell',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('last_modified', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('slug', models.SlugField()),
|
||||
('date', models.DateField(default=None, null=True)),
|
||||
('hour', models.FloatField(default=0.0)),
|
||||
('timeCard', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='financial.timecard')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0 on 2024-02-12 21:27
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('financial', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contract',
|
||||
name='baseline_end',
|
||||
field=models.DateField(blank=True, default=None, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='contract',
|
||||
name='baseline_start',
|
||||
field=models.DateField(blank=True, default=None, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.0 on 2024-02-13 14:02
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('financial', '0002_alter_contract_baseline_end_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contract',
|
||||
name='linkedContracts',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='financial.contract'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.0 on 2024-02-13 14:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('financial', '0003_alter_contract_linkedcontracts'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='chargenumber',
|
||||
name='endDate',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='chargenumber',
|
||||
name='startDate',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chargenumber',
|
||||
name='end_date',
|
||||
field=models.DateField(blank=True, default=None, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='chargenumber',
|
||||
name='start_date',
|
||||
field=models.DateField(blank=True, default=None, null=True),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-10 17:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("financial", "0004_remove_chargenumber_enddate_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddConstraint(
|
||||
model_name="chargenumber",
|
||||
constraint=models.CheckConstraint(
|
||||
check=models.Q(
|
||||
("charge_number_type__in", ["LOE", "QBD", "0_100", "50_50", "MAX"])
|
||||
),
|
||||
name="financial_ChargeNumber_charge_number_type_ChargeNumberTypeEnum",
|
||||
),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name="contract",
|
||||
constraint=models.CheckConstraint(
|
||||
check=models.Q(("contract_type__in", ["FFP", "MAX"])),
|
||||
name="financial_Contract_contract_type_ContractTypeEnum",
|
||||
),
|
||||
),
|
||||
]
|
||||
0
company_site/financial/migrations/__init__.py
Normal file
105
company_site/financial/models.py
Normal file
@@ -0,0 +1,105 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from django.utils import timezone
|
||||
from django_enum import EnumField
|
||||
from django.utils.text import slugify
|
||||
import datetime
|
||||
|
||||
# Abstract Model Classes
|
||||
class TimeMixin(models.Model):
|
||||
|
||||
created = models.DateTimeField(default=timezone.now)
|
||||
last_modified = models.DateTimeField(default=timezone.now)
|
||||
created_by = models.ForeignKey
|
||||
last_modified_BY = models.ForeignKey
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
class IdMixin(models.Model):
|
||||
slug = models.SlugField()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.slug is None:
|
||||
self.slug = slugify(datetime.datetime.now().time())
|
||||
super(IdMixin, self).save(*args, **kwargs)
|
||||
|
||||
# Concrete Classes
|
||||
class Contract(IdMixin, TimeMixin):
|
||||
class ContractTypeEnum(models.TextChoices):
|
||||
FIRM_FIX_PRICED = "FFP", "FIRM_FIX_PRICED"
|
||||
MAX_NUM_CONRACT_TYPES = "MAX", "MAX_NUM_CONTRACT_TYPES"
|
||||
|
||||
contract_type = EnumField(ContractTypeEnum)
|
||||
|
||||
name = models.CharField(max_length=100)
|
||||
proposed_amount = models.FloatField(default=0.0)
|
||||
baseline_amount = models.FloatField(default=0.0)
|
||||
funded_amount = models.FloatField(default=0.0)
|
||||
|
||||
baseline_start = models.DateField(null=True, blank=True, default=None)
|
||||
baseline_end = models.DateField(null=True, blank=True, default=None)
|
||||
linkedContracts = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
||||
# TODO: make calc ev func
|
||||
|
||||
class ChargeNumber(IdMixin, TimeMixin):
|
||||
class ChargeNumberTypeEnum(models.TextChoices):
|
||||
LEVEL_OF_EFFORT = "LOE", "LEVEL_OF_EFFORT"
|
||||
QBD = "QBD", "QBD"
|
||||
ZERO_ONE_HUNDRED = "0_100", "ZERO_ONE_HUNDRED"
|
||||
FIFTY_FIFTY = "50_50", "FIFTY_FIFTY"
|
||||
MAX_NUM_TASK_TYPES = "MAX", "MAX_NUM_TASK_TYPES"
|
||||
|
||||
charge_number_type = EnumField(ChargeNumberTypeEnum)
|
||||
|
||||
contract = models.ForeignKey(Contract, on_delete=models.CASCADE)
|
||||
amount = models.FloatField(default=0.0)
|
||||
percent_complete = models.FloatField(default=0.0)
|
||||
# TODO: add validator to make sure the range is 0.0 - 100
|
||||
start_date = models.DateField(null=True, blank=True, default = None)
|
||||
end_date = models.DateField(null=True, blank=True, default = None)
|
||||
|
||||
class AddressModel(models.Model):
|
||||
address_1 = models.CharField(max_length=128)
|
||||
address_2 = models.CharField(max_length=128, blank=True)
|
||||
|
||||
city = models.CharField(max_length=64)
|
||||
state = models.CharField(max_length=2)
|
||||
zip_code = models.CharField(max_length=5)
|
||||
|
||||
class Employee(IdMixin, TimeMixin):
|
||||
manager = models.ForeignKey("self", on_delete=models.CASCADE, related_name="manager_employee")
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
primaryAddress = models.ForeignKey(AddressModel, on_delete=models.CASCADE, related_name="primary_address_employee")
|
||||
workAddress = models.ForeignKey(AddressModel, on_delete=models.CASCADE, related_name="work_address_employee")
|
||||
phoneNumber = PhoneNumberField(null=False, blank=False, unique=True)
|
||||
slary= models.FloatField(default=0.0)
|
||||
|
||||
# TODO: get hourly salary
|
||||
# TODO: roles, jpbTitles
|
||||
|
||||
|
||||
|
||||
class TimeCard(IdMixin, TimeMixin):
|
||||
startDate = models.DateField(null=True, default = None)
|
||||
endDate = models.DateField(null=True, default = None)
|
||||
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name="employee")
|
||||
approvedBy = models.ForeignKey(Employee, on_delete=models.CASCADE, null=True, related_name="approved_by")
|
||||
approvedDate = models.DateField(null=True, default=None)
|
||||
approvalComment = models.TextField(max_length=256, default="")
|
||||
# TODO: do the is approved comment
|
||||
|
||||
class TimeCardCell(IdMixin, TimeMixin):
|
||||
timeCard = models.ForeignKey(TimeCard, on_delete=models.CASCADE)
|
||||
date = models.DateField(null=True, default = None)
|
||||
hour = models.FloatField(default = 0.0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
27936
company_site/financial/static/financial/css/material-dashboard.css
Normal file
42
company_site/financial/static/financial/css/material-dashboard.min.css
vendored
Normal file
597
company_site/financial/static/financial/css/nucleo-icons.css
Normal file
@@ -0,0 +1,597 @@
|
||||
/*--------------------------------
|
||||
|
||||
hermes-dashboard-icons Web Font - built using nucleoapp.com
|
||||
License - nucleoapp.com/license/
|
||||
|
||||
-------------------------------- */
|
||||
@font-face {
|
||||
font-family: 'NucleoIcons';
|
||||
src: url('../fonts/nucleo-icons.eot');
|
||||
src: url('../fonts/nucleo-icons.eot') format('embedded-opentype'), url('../fonts/nucleo-icons.woff2') format('woff2'), url('../fonts/nucleo-icons.woff') format('woff'), url('../fonts/nucleo-icons.ttf') format('truetype'), url('../fonts/nucleo-icons.svg') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/*------------------------
|
||||
base class definition
|
||||
-------------------------*/
|
||||
.ni {
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 NucleoIcons;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/*------------------------
|
||||
change icon size
|
||||
-------------------------*/
|
||||
.ni-lg {
|
||||
font-size: 1.33333333em;
|
||||
line-height: 0.75em;
|
||||
vertical-align: -15%;
|
||||
}
|
||||
|
||||
.ni-2x {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.ni-3x {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
.ni-4x {
|
||||
font-size: 4em;
|
||||
}
|
||||
|
||||
.ni-5x {
|
||||
font-size: 5em;
|
||||
}
|
||||
|
||||
/*----------------------------------
|
||||
add a square/circle background
|
||||
-----------------------------------*/
|
||||
.ni.square,
|
||||
.ni.circle {
|
||||
padding: 0.33333333em;
|
||||
vertical-align: -16%;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.ni.circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/*------------------------
|
||||
list icons
|
||||
-------------------------*/
|
||||
.ni-ul {
|
||||
padding-left: 0;
|
||||
margin-left: 2.14285714em;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.ni-ul>li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ni-ul>li>.ni {
|
||||
position: absolute;
|
||||
left: -1.57142857em;
|
||||
top: 0.14285714em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ni-ul>li>.ni.lg {
|
||||
top: 0;
|
||||
left: -1.35714286em;
|
||||
}
|
||||
|
||||
.ni-ul>li>.ni.circle,
|
||||
.ni-ul>li>.ni.square {
|
||||
top: -0.19047619em;
|
||||
left: -1.9047619em;
|
||||
}
|
||||
|
||||
/*------------------------
|
||||
spinning icons
|
||||
-------------------------*/
|
||||
.ni.spin {
|
||||
-webkit-animation: nc-spin 2s infinite linear;
|
||||
-moz-animation: nc-spin 2s infinite linear;
|
||||
animation: nc-spin 2s infinite linear;
|
||||
}
|
||||
|
||||
@-webkit-keyframes nc-spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes nc-spin {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-moz-transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nc-spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-ms-transform: rotate(0deg);
|
||||
-o-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
-moz-transform: rotate(360deg);
|
||||
-ms-transform: rotate(360deg);
|
||||
-o-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------
|
||||
rotated/flipped icons
|
||||
-------------------------*/
|
||||
.ni.rotate-90 {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
|
||||
-webkit-transform: rotate(90deg);
|
||||
-moz-transform: rotate(90deg);
|
||||
-ms-transform: rotate(90deg);
|
||||
-o-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.ni.rotate-180 {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
|
||||
-webkit-transform: rotate(180deg);
|
||||
-moz-transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg);
|
||||
-o-transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.ni.rotate-270 {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
|
||||
-webkit-transform: rotate(270deg);
|
||||
-moz-transform: rotate(270deg);
|
||||
-ms-transform: rotate(270deg);
|
||||
-o-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
.ni.flip-y {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0);
|
||||
-webkit-transform: scale(-1, 1);
|
||||
-moz-transform: scale(-1, 1);
|
||||
-ms-transform: scale(-1, 1);
|
||||
-o-transform: scale(-1, 1);
|
||||
transform: scale(-1, 1);
|
||||
}
|
||||
|
||||
.ni.flip-x {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
|
||||
-webkit-transform: scale(1, -1);
|
||||
-moz-transform: scale(1, -1);
|
||||
-ms-transform: scale(1, -1);
|
||||
-o-transform: scale(1, -1);
|
||||
transform: scale(1, -1);
|
||||
}
|
||||
|
||||
/*------------------------
|
||||
font icons
|
||||
-------------------------*/
|
||||
|
||||
.ni-active-40::before {
|
||||
content: "\ea02";
|
||||
}
|
||||
|
||||
.ni-air-baloon::before {
|
||||
content: "\ea03";
|
||||
}
|
||||
|
||||
.ni-album-2::before {
|
||||
content: "\ea04";
|
||||
}
|
||||
|
||||
.ni-align-center::before {
|
||||
content: "\ea05";
|
||||
}
|
||||
|
||||
.ni-align-left-2::before {
|
||||
content: "\ea06";
|
||||
}
|
||||
|
||||
.ni-ambulance::before {
|
||||
content: "\ea07";
|
||||
}
|
||||
|
||||
.ni-app::before {
|
||||
content: "\ea08";
|
||||
}
|
||||
|
||||
.ni-archive-2::before {
|
||||
content: "\ea09";
|
||||
}
|
||||
|
||||
.ni-atom::before {
|
||||
content: "\ea0a";
|
||||
}
|
||||
|
||||
.ni-badge::before {
|
||||
content: "\ea0b";
|
||||
}
|
||||
|
||||
.ni-bag-17::before {
|
||||
content: "\ea0c";
|
||||
}
|
||||
|
||||
.ni-basket::before {
|
||||
content: "\ea0d";
|
||||
}
|
||||
|
||||
.ni-bell-55::before {
|
||||
content: "\ea0e";
|
||||
}
|
||||
|
||||
.ni-bold-down::before {
|
||||
content: "\ea0f";
|
||||
}
|
||||
|
||||
.ni-bold-left::before {
|
||||
content: "\ea10";
|
||||
}
|
||||
|
||||
.ni-bold-right::before {
|
||||
content: "\ea11";
|
||||
}
|
||||
|
||||
.ni-bold-up::before {
|
||||
content: "\ea12";
|
||||
}
|
||||
|
||||
.ni-bold::before {
|
||||
content: "\ea13";
|
||||
}
|
||||
|
||||
.ni-book-bookmark::before {
|
||||
content: "\ea14";
|
||||
}
|
||||
|
||||
.ni-books::before {
|
||||
content: "\ea15";
|
||||
}
|
||||
|
||||
.ni-box-2::before {
|
||||
content: "\ea16";
|
||||
}
|
||||
|
||||
.ni-briefcase-24::before {
|
||||
content: "\ea17";
|
||||
}
|
||||
|
||||
.ni-building::before {
|
||||
content: "\ea18";
|
||||
}
|
||||
|
||||
.ni-bulb-61::before {
|
||||
content: "\ea19";
|
||||
}
|
||||
|
||||
.ni-bullet-list-67::before {
|
||||
content: "\ea1a";
|
||||
}
|
||||
|
||||
.ni-bus-front-12::before {
|
||||
content: "\ea1b";
|
||||
}
|
||||
|
||||
.ni-button-pause::before {
|
||||
content: "\ea1c";
|
||||
}
|
||||
|
||||
.ni-button-play::before {
|
||||
content: "\ea1d";
|
||||
}
|
||||
|
||||
.ni-button-power::before {
|
||||
content: "\ea1e";
|
||||
}
|
||||
|
||||
.ni-calendar-grid-58::before {
|
||||
content: "\ea1f";
|
||||
}
|
||||
|
||||
.ni-camera-compact::before {
|
||||
content: "\ea20";
|
||||
}
|
||||
|
||||
.ni-caps-small::before {
|
||||
content: "\ea21";
|
||||
}
|
||||
|
||||
.ni-cart::before {
|
||||
content: "\ea22";
|
||||
}
|
||||
|
||||
.ni-chart-bar-32::before {
|
||||
content: "\ea23";
|
||||
}
|
||||
|
||||
.ni-chart-pie-35::before {
|
||||
content: "\ea24";
|
||||
}
|
||||
|
||||
.ni-chat-round::before {
|
||||
content: "\ea25";
|
||||
}
|
||||
|
||||
.ni-check-bold::before {
|
||||
content: "\ea26";
|
||||
}
|
||||
|
||||
.ni-circle-08::before {
|
||||
content: "\ea27";
|
||||
}
|
||||
|
||||
.ni-cloud-download-95::before {
|
||||
content: "\ea28";
|
||||
}
|
||||
|
||||
.ni-cloud-upload-96::before {
|
||||
content: "\ea29";
|
||||
}
|
||||
|
||||
.ni-compass-04::before {
|
||||
content: "\ea2a";
|
||||
}
|
||||
|
||||
.ni-controller::before {
|
||||
content: "\ea2b";
|
||||
}
|
||||
|
||||
.ni-credit-card::before {
|
||||
content: "\ea2c";
|
||||
}
|
||||
|
||||
.ni-curved-next::before {
|
||||
content: "\ea2d";
|
||||
}
|
||||
|
||||
.ni-delivery-fast::before {
|
||||
content: "\ea2e";
|
||||
}
|
||||
|
||||
.ni-diamond::before {
|
||||
content: "\ea2f";
|
||||
}
|
||||
|
||||
.ni-email-83::before {
|
||||
content: "\ea30";
|
||||
}
|
||||
|
||||
.ni-fat-add::before {
|
||||
content: "\ea31";
|
||||
}
|
||||
|
||||
.ni-fat-delete::before {
|
||||
content: "\ea32";
|
||||
}
|
||||
|
||||
.ni-fat-remove::before {
|
||||
content: "\ea33";
|
||||
}
|
||||
|
||||
.ni-favourite-28::before {
|
||||
content: "\ea34";
|
||||
}
|
||||
|
||||
.ni-folder-17::before {
|
||||
content: "\ea35";
|
||||
}
|
||||
|
||||
.ni-glasses-2::before {
|
||||
content: "\ea36";
|
||||
}
|
||||
|
||||
.ni-hat-3::before {
|
||||
content: "\ea37";
|
||||
}
|
||||
|
||||
.ni-headphones::before {
|
||||
content: "\ea38";
|
||||
}
|
||||
|
||||
.ni-html5::before {
|
||||
content: "\ea39";
|
||||
}
|
||||
|
||||
.ni-istanbul::before {
|
||||
content: "\ea3a";
|
||||
}
|
||||
|
||||
.ni-key-25::before {
|
||||
content: "\ea3b";
|
||||
}
|
||||
|
||||
.ni-laptop::before {
|
||||
content: "\ea3c";
|
||||
}
|
||||
|
||||
.ni-like-2::before {
|
||||
content: "\ea3d";
|
||||
}
|
||||
|
||||
.ni-lock-circle-open::before {
|
||||
content: "\ea3e";
|
||||
}
|
||||
|
||||
.ni-map-big::before {
|
||||
content: "\ea3f";
|
||||
}
|
||||
|
||||
.ni-mobile-button::before {
|
||||
content: "\ea40";
|
||||
}
|
||||
|
||||
.ni-money-coins::before {
|
||||
content: "\ea41";
|
||||
}
|
||||
|
||||
.ni-note-03::before {
|
||||
content: "\ea42";
|
||||
}
|
||||
|
||||
.ni-notification-70::before {
|
||||
content: "\ea43";
|
||||
}
|
||||
|
||||
.ni-palette::before {
|
||||
content: "\ea44";
|
||||
}
|
||||
|
||||
.ni-paper-diploma::before {
|
||||
content: "\ea45";
|
||||
}
|
||||
|
||||
.ni-pin-3::before {
|
||||
content: "\ea46";
|
||||
}
|
||||
|
||||
.ni-planet::before {
|
||||
content: "\ea47";
|
||||
}
|
||||
|
||||
.ni-ruler-pencil::before {
|
||||
content: "\ea48";
|
||||
}
|
||||
|
||||
.ni-satisfied::before {
|
||||
content: "\ea49";
|
||||
}
|
||||
|
||||
.ni-scissors::before {
|
||||
content: "\ea4a";
|
||||
}
|
||||
|
||||
.ni-send::before {
|
||||
content: "\ea4b";
|
||||
}
|
||||
|
||||
.ni-settings-gear-65::before {
|
||||
content: "\ea4c";
|
||||
}
|
||||
|
||||
.ni-settings::before {
|
||||
content: "\ea4d";
|
||||
}
|
||||
|
||||
.ni-single-02::before {
|
||||
content: "\ea4e";
|
||||
}
|
||||
|
||||
.ni-single-copy-04::before {
|
||||
content: "\ea4f";
|
||||
}
|
||||
|
||||
.ni-sound-wave::before {
|
||||
content: "\ea50";
|
||||
}
|
||||
|
||||
.ni-spaceship::before {
|
||||
content: "\ea51";
|
||||
}
|
||||
|
||||
.ni-square-pin::before {
|
||||
content: "\ea52";
|
||||
}
|
||||
|
||||
.ni-support-16::before {
|
||||
content: "\ea53";
|
||||
}
|
||||
|
||||
.ni-tablet-button::before {
|
||||
content: "\ea54";
|
||||
}
|
||||
|
||||
.ni-tag::before {
|
||||
content: "\ea55";
|
||||
}
|
||||
|
||||
.ni-tie-bow::before {
|
||||
content: "\ea56";
|
||||
}
|
||||
|
||||
.ni-time-alarm::before {
|
||||
content: "\ea57";
|
||||
}
|
||||
|
||||
.ni-trophy::before {
|
||||
content: "\ea58";
|
||||
}
|
||||
|
||||
.ni-tv-2::before {
|
||||
content: "\ea59";
|
||||
}
|
||||
|
||||
.ni-umbrella-13::before {
|
||||
content: "\ea5a";
|
||||
}
|
||||
|
||||
.ni-user-run::before {
|
||||
content: "\ea5b";
|
||||
}
|
||||
|
||||
.ni-vector::before {
|
||||
content: "\ea5c";
|
||||
}
|
||||
|
||||
.ni-watch-time::before {
|
||||
content: "\ea5d";
|
||||
}
|
||||
|
||||
.ni-world::before {
|
||||
content: "\ea5e";
|
||||
}
|
||||
|
||||
.ni-zoom-split-in::before {
|
||||
content: "\ea5f";
|
||||
}
|
||||
|
||||
.ni-collection::before {
|
||||
content: "\ea60";
|
||||
}
|
||||
|
||||
.ni-image::before {
|
||||
content: "\ea61";
|
||||
}
|
||||
|
||||
.ni-shop::before {
|
||||
content: "\ea62";
|
||||
}
|
||||
|
||||
.ni-ungroup::before {
|
||||
content: "\ea63";
|
||||
}
|
||||
|
||||
.ni-world-2::before {
|
||||
content: "\ea64";
|
||||
}
|
||||
|
||||
.ni-ui-04::before {
|
||||
content: "\ea65";
|
||||
}
|
||||
|
||||
|
||||
/* all icon font classes list here */
|
||||
135
company_site/financial/static/financial/css/nucleo-svg.css
Normal file
@@ -0,0 +1,135 @@
|
||||
/* Generated using nucleoapp.com */
|
||||
/* --------------------------------
|
||||
|
||||
Icon colors
|
||||
|
||||
-------------------------------- */
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
/* icon primary color */
|
||||
color: #111111;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
.icon use {
|
||||
/* icon secondary color - fill */
|
||||
fill: #7ea6f6;
|
||||
}
|
||||
|
||||
.icon.icon-outline use {
|
||||
/* icon secondary color - stroke */
|
||||
stroke: #7ea6f6;
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
Change icon size
|
||||
|
||||
-------------------------------- */
|
||||
|
||||
.icon-xs {
|
||||
height: 0.5em;
|
||||
width: 0.5em;
|
||||
}
|
||||
|
||||
.icon-sm {
|
||||
height: 0.8em;
|
||||
width: 0.8em;
|
||||
}
|
||||
|
||||
.icon-lg {
|
||||
height: 1.6em;
|
||||
width: 1.6em;
|
||||
}
|
||||
|
||||
.icon-xl {
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
Align icon and text
|
||||
|
||||
-------------------------------- */
|
||||
|
||||
.icon-text-aligner {
|
||||
/* add this class to parent element that contains icon + text */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon-text-aligner .icon {
|
||||
color: inherit;
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
|
||||
.icon-text-aligner .icon use {
|
||||
color: inherit;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.icon-text-aligner .icon.icon-outline use {
|
||||
stroke: currentColor;
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
Icon reset values - used to enable color customizations
|
||||
|
||||
-------------------------------- */
|
||||
|
||||
.icon {
|
||||
fill: currentColor;
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.icon.icon-outline {
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
}
|
||||
|
||||
.icon use {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.icon.icon-outline use {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
Stroke effects - Nucleo outline icons
|
||||
|
||||
- 16px icons -> up to 1px stroke (16px outline icons do not support stroke changes)
|
||||
- 24px, 32px icons -> up to 2px stroke
|
||||
- 48px, 64px icons -> up to 4px stroke
|
||||
|
||||
-------------------------------- */
|
||||
|
||||
.icon-outline.icon-stroke-1 {
|
||||
stroke-width: 1px;
|
||||
}
|
||||
|
||||
.icon-outline.icon-stroke-2 {
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.icon-outline.icon-stroke-3 {
|
||||
stroke-width: 3px;
|
||||
}
|
||||
|
||||
.icon-outline.icon-stroke-4 {
|
||||
stroke-width: 4px;
|
||||
}
|
||||
|
||||
.icon-outline.icon-stroke-1 use,
|
||||
.icon-outline.icon-stroke-3 use {
|
||||
-webkit-transform: translateX(0.5px) translateY(0.5px);
|
||||
-moz-transform: translateX(0.5px) translateY(0.5px);
|
||||
-ms-transform: translateX(0.5px) translateY(0.5px);
|
||||
-o-transform: translateX(0.5px) translateY(0.5px);
|
||||
transform: translateX(0.5px) translateY(0.5px);
|
||||
}
|
||||
6
company_site/financial/static/financial/js/core/bootstrap.bundle.min.js
vendored
Normal file
6
company_site/financial/static/financial/js/core/bootstrap.min.js
vendored
Normal file
4
company_site/financial/static/financial/js/core/popper.min.js
vendored
Normal file
876
company_site/financial/static/financial/js/material-dashboard.js
Normal file
@@ -0,0 +1,876 @@
|
||||
// =========================================================
|
||||
// Material Dashboard 2 - v3.1.0
|
||||
// =========================================================
|
||||
|
||||
// Product Page: https://www.creative-tim.com/product/material-dashboard
|
||||
// Copyright 2023 Creative Tim (https://www.creative-tim.com)
|
||||
// Licensed under MIT (https://github.com/creativetimofficial/material-dashboard/blob/master/LICENSE.md)
|
||||
|
||||
// Coded by www.creative-tim.com
|
||||
|
||||
// =========================================================
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
"use strict";
|
||||
(function() {
|
||||
var isWindows = navigator.platform.indexOf('Win') > -1 ? true : false;
|
||||
|
||||
if (isWindows) {
|
||||
// if we are on windows OS we activate the perfectScrollbar function
|
||||
if (document.getElementsByClassName('main-content')[0]) {
|
||||
var mainpanel = document.querySelector('.main-content');
|
||||
var ps = new PerfectScrollbar(mainpanel);
|
||||
};
|
||||
|
||||
if (document.getElementsByClassName('sidenav')[0]) {
|
||||
var sidebar = document.querySelector('.sidenav');
|
||||
var ps1 = new PerfectScrollbar(sidebar);
|
||||
};
|
||||
|
||||
if (document.getElementsByClassName('navbar-collapse')[0]) {
|
||||
var fixedplugin = document.querySelector('.navbar:not(.navbar-expand-lg) .navbar-collapse');
|
||||
var ps2 = new PerfectScrollbar(fixedplugin);
|
||||
};
|
||||
|
||||
if (document.getElementsByClassName('fixed-plugin')[0]) {
|
||||
var fixedplugin = document.querySelector('.fixed-plugin');
|
||||
var ps3 = new PerfectScrollbar(fixedplugin);
|
||||
};
|
||||
};
|
||||
})();
|
||||
|
||||
// Verify navbar blur on scroll
|
||||
if (document.getElementById('navbarBlur')) {
|
||||
navbarBlurOnScroll('navbarBlur');
|
||||
}
|
||||
|
||||
// initialization of Tooltips
|
||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
||||
var tooltipList = tooltipTriggerList.map(function(tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl)
|
||||
})
|
||||
|
||||
// when input is focused add focused class for style
|
||||
function focused(el) {
|
||||
if (el.parentElement.classList.contains('input-group')) {
|
||||
el.parentElement.classList.add('focused');
|
||||
}
|
||||
}
|
||||
|
||||
// when input is focused remove focused class for style
|
||||
function defocused(el) {
|
||||
if (el.parentElement.classList.contains('input-group')) {
|
||||
el.parentElement.classList.remove('focused');
|
||||
}
|
||||
}
|
||||
|
||||
// helper for adding on all elements multiple attributes
|
||||
function setAttributes(el, options) {
|
||||
Object.keys(options).forEach(function(attr) {
|
||||
el.setAttribute(attr, options[attr]);
|
||||
})
|
||||
}
|
||||
|
||||
// adding on inputs attributes for calling the focused and defocused functions
|
||||
if (document.querySelectorAll('.input-group').length != 0) {
|
||||
var allInputs = document.querySelectorAll('input.form-control');
|
||||
allInputs.forEach(el => setAttributes(el, {
|
||||
"onfocus": "focused(this)",
|
||||
"onfocusout": "defocused(this)"
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
// Fixed Plugin
|
||||
|
||||
if (document.querySelector('.fixed-plugin')) {
|
||||
var fixedPlugin = document.querySelector('.fixed-plugin');
|
||||
var fixedPlugin = document.querySelector('.fixed-plugin');
|
||||
var fixedPluginButton = document.querySelector('.fixed-plugin-button');
|
||||
var fixedPluginButtonNav = document.querySelector('.fixed-plugin-button-nav');
|
||||
var fixedPluginCard = document.querySelector('.fixed-plugin .card');
|
||||
var fixedPluginCloseButton = document.querySelectorAll('.fixed-plugin-close-button');
|
||||
var navbar = document.getElementById('navbarBlur');
|
||||
var buttonNavbarFixed = document.getElementById('navbarFixed');
|
||||
|
||||
if (fixedPluginButton) {
|
||||
fixedPluginButton.onclick = function() {
|
||||
if (!fixedPlugin.classList.contains('show')) {
|
||||
fixedPlugin.classList.add('show');
|
||||
} else {
|
||||
fixedPlugin.classList.remove('show');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fixedPluginButtonNav) {
|
||||
fixedPluginButtonNav.onclick = function() {
|
||||
if (!fixedPlugin.classList.contains('show')) {
|
||||
fixedPlugin.classList.add('show');
|
||||
} else {
|
||||
fixedPlugin.classList.remove('show');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fixedPluginCloseButton.forEach(function(el) {
|
||||
el.onclick = function() {
|
||||
fixedPlugin.classList.remove('show');
|
||||
}
|
||||
})
|
||||
|
||||
document.querySelector('body').onclick = function(e) {
|
||||
if (e.target != fixedPluginButton && e.target != fixedPluginButtonNav && e.target.closest('.fixed-plugin .card') != fixedPluginCard) {
|
||||
fixedPlugin.classList.remove('show');
|
||||
}
|
||||
}
|
||||
|
||||
if (navbar) {
|
||||
if (navbar.getAttribute('data-scroll') == 'true' && buttonNavbarFixed) {
|
||||
buttonNavbarFixed.setAttribute("checked", "true");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Set Sidebar Color
|
||||
function sidebarColor(a) {
|
||||
var parent = document.querySelector(".nav-link.active");
|
||||
var color = a.getAttribute("data-color");
|
||||
|
||||
if (parent.classList.contains('bg-gradient-primary')) {
|
||||
parent.classList.remove('bg-gradient-primary');
|
||||
}
|
||||
if (parent.classList.contains('bg-gradient-dark')) {
|
||||
parent.classList.remove('bg-gradient-dark');
|
||||
}
|
||||
if (parent.classList.contains('bg-gradient-info')) {
|
||||
parent.classList.remove('bg-gradient-info');
|
||||
}
|
||||
if (parent.classList.contains('bg-gradient-success')) {
|
||||
parent.classList.remove('bg-gradient-success');
|
||||
}
|
||||
if (parent.classList.contains('bg-gradient-warning')) {
|
||||
parent.classList.remove('bg-gradient-warning');
|
||||
}
|
||||
if (parent.classList.contains('bg-gradient-danger')) {
|
||||
parent.classList.remove('bg-gradient-danger');
|
||||
}
|
||||
parent.classList.add('bg-gradient-' + color);
|
||||
}
|
||||
|
||||
// Set Sidebar Type
|
||||
function sidebarType(a) {
|
||||
var parent = a.parentElement.children;
|
||||
var color = a.getAttribute("data-class");
|
||||
var body = document.querySelector("body");
|
||||
var bodyWhite = document.querySelector("body:not(.dark-version)");
|
||||
var bodyDark = body.classList.contains('dark-version');
|
||||
|
||||
var colors = [];
|
||||
|
||||
for (var i = 0; i < parent.length; i++) {
|
||||
parent[i].classList.remove('active');
|
||||
colors.push(parent[i].getAttribute('data-class'));
|
||||
}
|
||||
|
||||
if (!a.classList.contains('active')) {
|
||||
a.classList.add('active');
|
||||
} else {
|
||||
a.classList.remove('active');
|
||||
}
|
||||
|
||||
var sidebar = document.querySelector('.sidenav');
|
||||
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
sidebar.classList.remove(colors[i]);
|
||||
}
|
||||
|
||||
sidebar.classList.add(color);
|
||||
|
||||
|
||||
// Remove text-white/text-dark classes
|
||||
if (color == 'bg-transparent' || color == 'bg-white') {
|
||||
var textWhites = document.querySelectorAll('.sidenav .text-white');
|
||||
for (let i = 0; i < textWhites.length; i++) {
|
||||
textWhites[i].classList.remove('text-white');
|
||||
textWhites[i].classList.add('text-dark');
|
||||
}
|
||||
} else {
|
||||
var textDarks = document.querySelectorAll('.sidenav .text-dark');
|
||||
for (let i = 0; i < textDarks.length; i++) {
|
||||
textDarks[i].classList.add('text-white');
|
||||
textDarks[i].classList.remove('text-dark');
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 'bg-transparent' && bodyDark) {
|
||||
var textDarks = document.querySelectorAll('.navbar-brand .text-dark');
|
||||
for (let i = 0; i < textDarks.length; i++) {
|
||||
textDarks[i].classList.add('text-white');
|
||||
textDarks[i].classList.remove('text-dark');
|
||||
}
|
||||
}
|
||||
|
||||
// Remove logo-white/logo-dark
|
||||
|
||||
if ((color == 'bg-transparent' || color == 'bg-white') && bodyWhite) {
|
||||
var navbarBrand = document.querySelector('.navbar-brand-img');
|
||||
var navbarBrandImg = navbarBrand.src;
|
||||
|
||||
if (navbarBrandImg.includes('logo-ct.png')) {
|
||||
var navbarBrandImgNew = navbarBrandImg.replace("logo-ct", "logo-ct-dark");
|
||||
navbarBrand.src = navbarBrandImgNew;
|
||||
}
|
||||
} else {
|
||||
var navbarBrand = document.querySelector('.navbar-brand-img');
|
||||
var navbarBrandImg = navbarBrand.src;
|
||||
if (navbarBrandImg.includes('logo-ct-dark.png')) {
|
||||
var navbarBrandImgNew = navbarBrandImg.replace("logo-ct-dark", "logo-ct");
|
||||
navbarBrand.src = navbarBrandImgNew;
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 'bg-white' && bodyDark) {
|
||||
var navbarBrand = document.querySelector('.navbar-brand-img');
|
||||
var navbarBrandImg = navbarBrand.src;
|
||||
|
||||
if (navbarBrandImg.includes('logo-ct.png')) {
|
||||
var navbarBrandImgNew = navbarBrandImg.replace("logo-ct", "logo-ct-dark");
|
||||
navbarBrand.src = navbarBrandImgNew;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set Navbar Fixed
|
||||
function navbarFixed(el) {
|
||||
let classes = ['position-sticky', 'blur', 'shadow-blur', 'mt-4', 'left-auto', 'top-1', 'z-index-sticky'];
|
||||
const navbar = document.getElementById('navbarBlur');
|
||||
|
||||
if (!el.getAttribute("checked")) {
|
||||
navbar.classList.add(...classes);
|
||||
navbar.setAttribute('navbar-scroll', 'true');
|
||||
navbarBlurOnScroll('navbarBlur');
|
||||
el.setAttribute("checked", "true");
|
||||
} else {
|
||||
navbar.classList.remove(...classes);
|
||||
navbar.setAttribute('navbar-scroll', 'false');
|
||||
navbarBlurOnScroll('navbarBlur');
|
||||
el.removeAttribute("checked");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Set Navbar Minimized
|
||||
function navbarMinimize(el) {
|
||||
var sidenavShow = document.getElementsByClassName('g-sidenav-show')[0];
|
||||
|
||||
if (!el.getAttribute("checked")) {
|
||||
sidenavShow.classList.remove('g-sidenav-pinned');
|
||||
sidenavShow.classList.add('g-sidenav-hidden');
|
||||
el.setAttribute("checked", "true");
|
||||
} else {
|
||||
sidenavShow.classList.remove('g-sidenav-hidden');
|
||||
sidenavShow.classList.add('g-sidenav-pinned');
|
||||
el.removeAttribute("checked");
|
||||
}
|
||||
}
|
||||
|
||||
// Navbar blur on scroll
|
||||
function navbarBlurOnScroll(id) {
|
||||
const navbar = document.getElementById(id);
|
||||
let navbarScrollActive = navbar ? navbar.getAttribute("data-scroll") : false;
|
||||
let scrollDistance = 5;
|
||||
let classes = ['blur', 'shadow-blur', 'left-auto'];
|
||||
let toggleClasses = ['shadow-none'];
|
||||
|
||||
if (navbarScrollActive == 'true') {
|
||||
window.onscroll = debounce(function() {
|
||||
if (window.scrollY > scrollDistance) {
|
||||
blurNavbar();
|
||||
} else {
|
||||
transparentNavbar();
|
||||
}
|
||||
}, 10);
|
||||
} else {
|
||||
window.onscroll = debounce(function() {
|
||||
transparentNavbar();
|
||||
}, 10);
|
||||
}
|
||||
|
||||
var isWindows = navigator.platform.indexOf('Win') > -1 ? true : false;
|
||||
|
||||
if (isWindows) {
|
||||
var content = document.querySelector('.main-content');
|
||||
if (navbarScrollActive == 'true') {
|
||||
content.addEventListener('ps-scroll-y', debounce(function() {
|
||||
if (content.scrollTop > scrollDistance) {
|
||||
blurNavbar();
|
||||
} else {
|
||||
transparentNavbar();
|
||||
}
|
||||
}, 10));
|
||||
} else {
|
||||
content.addEventListener('ps-scroll-y', debounce(function() {
|
||||
transparentNavbar();
|
||||
}, 10));
|
||||
}
|
||||
}
|
||||
|
||||
function blurNavbar() {
|
||||
navbar.classList.add(...classes)
|
||||
navbar.classList.remove(...toggleClasses)
|
||||
|
||||
toggleNavLinksColor('blur');
|
||||
}
|
||||
|
||||
function transparentNavbar() {
|
||||
navbar.classList.remove(...classes)
|
||||
navbar.classList.add(...toggleClasses)
|
||||
|
||||
toggleNavLinksColor('transparent');
|
||||
}
|
||||
|
||||
function toggleNavLinksColor(type) {
|
||||
let navLinks = document.querySelectorAll('.navbar-main .nav-link')
|
||||
let navLinksToggler = document.querySelectorAll('.navbar-main .sidenav-toggler-line')
|
||||
|
||||
if (type === "blur") {
|
||||
navLinks.forEach(element => {
|
||||
element.classList.remove('text-body')
|
||||
});
|
||||
|
||||
navLinksToggler.forEach(element => {
|
||||
element.classList.add('bg-dark')
|
||||
});
|
||||
} else if (type === "transparent") {
|
||||
navLinks.forEach(element => {
|
||||
element.classList.add('text-body')
|
||||
});
|
||||
|
||||
navLinksToggler.forEach(element => {
|
||||
element.classList.remove('bg-dark')
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Debounce Function
|
||||
// Returns a function, that, as long as it continues to be invoked, will not
|
||||
// be triggered. The function will be called after it stops being called for
|
||||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||||
// leading edge, instead of the trailing.
|
||||
function debounce(func, wait, immediate) {
|
||||
var timeout;
|
||||
return function() {
|
||||
var context = this,
|
||||
args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
if (!immediate) func.apply(context, args);
|
||||
};
|
||||
var callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
};
|
||||
|
||||
// initialization of Toasts
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var toastElList = [].slice.call(document.querySelectorAll(".toast"));
|
||||
|
||||
var toastList = toastElList.map(function(toastEl) {
|
||||
return new bootstrap.Toast(toastEl);
|
||||
});
|
||||
|
||||
var toastButtonList = [].slice.call(document.querySelectorAll(".toast-btn"));
|
||||
|
||||
toastButtonList.map(function(toastButtonEl) {
|
||||
toastButtonEl.addEventListener("click", function() {
|
||||
var toastToTrigger = document.getElementById(toastButtonEl.dataset.target);
|
||||
|
||||
if (toastToTrigger) {
|
||||
var toast = bootstrap.Toast.getInstance(toastToTrigger);
|
||||
toast.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Tabs navigation
|
||||
|
||||
var total = document.querySelectorAll('.nav-pills');
|
||||
|
||||
function initNavs() {
|
||||
total.forEach(function(item, i) {
|
||||
var moving_div = document.createElement('div');
|
||||
var first_li = item.querySelector('li:first-child .nav-link');
|
||||
var tab = first_li.cloneNode();
|
||||
tab.innerHTML = "-";
|
||||
|
||||
moving_div.classList.add('moving-tab', 'position-absolute', 'nav-link');
|
||||
moving_div.appendChild(tab);
|
||||
item.appendChild(moving_div);
|
||||
|
||||
var list_length = item.getElementsByTagName("li").length;
|
||||
|
||||
moving_div.style.padding = '0px';
|
||||
moving_div.style.width = item.querySelector('li:nth-child(1)').offsetWidth + 'px';
|
||||
moving_div.style.transform = 'translate3d(0px, 0px, 0px)';
|
||||
moving_div.style.transition = '.5s ease';
|
||||
|
||||
item.onmouseover = function(event) {
|
||||
let target = getEventTarget(event);
|
||||
let li = target.closest('li'); // get reference
|
||||
if (li) {
|
||||
let nodes = Array.from(li.closest('ul').children); // get array
|
||||
let index = nodes.indexOf(li) + 1;
|
||||
item.querySelector('li:nth-child(' + index + ') .nav-link').onclick = function() {
|
||||
moving_div = item.querySelector('.moving-tab');
|
||||
let sum = 0;
|
||||
if (item.classList.contains('flex-column')) {
|
||||
for (var j = 1; j <= nodes.indexOf(li); j++) {
|
||||
sum += item.querySelector('li:nth-child(' + j + ')').offsetHeight;
|
||||
}
|
||||
moving_div.style.transform = 'translate3d(0px,' + sum + 'px, 0px)';
|
||||
moving_div.style.height = item.querySelector('li:nth-child(' + j + ')').offsetHeight;
|
||||
} else {
|
||||
for (var j = 1; j <= nodes.indexOf(li); j++) {
|
||||
sum += item.querySelector('li:nth-child(' + j + ')').offsetWidth;
|
||||
}
|
||||
moving_div.style.transform = 'translate3d(' + sum + 'px, 0px, 0px)';
|
||||
moving_div.style.width = item.querySelector('li:nth-child(' + index + ')').offsetWidth + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
initNavs();
|
||||
}, 100);
|
||||
|
||||
// Tabs navigation resize
|
||||
|
||||
window.addEventListener('resize', function(event) {
|
||||
total.forEach(function(item, i) {
|
||||
item.querySelector('.moving-tab').remove();
|
||||
var moving_div = document.createElement('div');
|
||||
var tab = item.querySelector(".nav-link.active").cloneNode();
|
||||
tab.innerHTML = "-";
|
||||
|
||||
moving_div.classList.add('moving-tab', 'position-absolute', 'nav-link');
|
||||
moving_div.appendChild(tab);
|
||||
|
||||
item.appendChild(moving_div);
|
||||
|
||||
moving_div.style.padding = '0px';
|
||||
moving_div.style.transition = '.5s ease';
|
||||
|
||||
let li = item.querySelector(".nav-link.active").parentElement;
|
||||
|
||||
if (li) {
|
||||
let nodes = Array.from(li.closest('ul').children); // get array
|
||||
let index = nodes.indexOf(li) + 1;
|
||||
|
||||
let sum = 0;
|
||||
if (item.classList.contains('flex-column')) {
|
||||
for (var j = 1; j <= nodes.indexOf(li); j++) {
|
||||
sum += item.querySelector('li:nth-child(' + j + ')').offsetHeight;
|
||||
}
|
||||
moving_div.style.transform = 'translate3d(0px,' + sum + 'px, 0px)';
|
||||
moving_div.style.width = item.querySelector('li:nth-child(' + index + ')').offsetWidth + 'px';
|
||||
moving_div.style.height = item.querySelector('li:nth-child(' + j + ')').offsetHeight;
|
||||
} else {
|
||||
for (var j = 1; j <= nodes.indexOf(li); j++) {
|
||||
sum += item.querySelector('li:nth-child(' + j + ')').offsetWidth;
|
||||
}
|
||||
moving_div.style.transform = 'translate3d(' + sum + 'px, 0px, 0px)';
|
||||
moving_div.style.width = item.querySelector('li:nth-child(' + index + ')').offsetWidth + 'px';
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (window.innerWidth < 991) {
|
||||
total.forEach(function(item, i) {
|
||||
if (!item.classList.contains('flex-column')) {
|
||||
item.classList.remove('flex-row');
|
||||
item.classList.add('flex-column', 'on-resize');
|
||||
let li = item.querySelector(".nav-link.active").parentElement;
|
||||
let nodes = Array.from(li.closest('ul').children); // get array
|
||||
let index = nodes.indexOf(li) + 1;
|
||||
let sum = 0;
|
||||
for (var j = 1; j <= nodes.indexOf(li); j++) {
|
||||
sum += item.querySelector('li:nth-child(' + j + ')').offsetHeight;
|
||||
}
|
||||
var moving_div = document.querySelector('.moving-tab');
|
||||
moving_div.style.width = item.querySelector('li:nth-child(1)').offsetWidth + 'px';
|
||||
moving_div.style.transform = 'translate3d(0px,' + sum + 'px, 0px)';
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
total.forEach(function(item, i) {
|
||||
if (item.classList.contains('on-resize')) {
|
||||
item.classList.remove('flex-column', 'on-resize');
|
||||
item.classList.add('flex-row');
|
||||
let li = item.querySelector(".nav-link.active").parentElement;
|
||||
let nodes = Array.from(li.closest('ul').children); // get array
|
||||
let index = nodes.indexOf(li) + 1;
|
||||
let sum = 0;
|
||||
for (var j = 1; j <= nodes.indexOf(li); j++) {
|
||||
sum += item.querySelector('li:nth-child(' + j + ')').offsetWidth;
|
||||
}
|
||||
var moving_div = document.querySelector('.moving-tab');
|
||||
moving_div.style.transform = 'translate3d(' + sum + 'px, 0px, 0px)';
|
||||
moving_div.style.width = item.querySelector('li:nth-child(' + index + ')').offsetWidth + 'px';
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// Function to remove flex row on mobile devices
|
||||
if (window.innerWidth < 991) {
|
||||
total.forEach(function(item, i) {
|
||||
if (item.classList.contains('flex-row')) {
|
||||
item.classList.remove('flex-row');
|
||||
item.classList.add('flex-column', 'on-resize');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getEventTarget(e) {
|
||||
e = e || window.event;
|
||||
return e.target || e.srcElement;
|
||||
}
|
||||
|
||||
// End tabs navigation
|
||||
|
||||
window.onload = function() {
|
||||
// Material Design Input function
|
||||
var inputs = document.querySelectorAll('input');
|
||||
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
inputs[i].addEventListener('focus', function(e) {
|
||||
this.parentElement.classList.add('is-focused');
|
||||
}, false);
|
||||
|
||||
inputs[i].onkeyup = function(e) {
|
||||
if (this.value != "") {
|
||||
this.parentElement.classList.add('is-filled');
|
||||
} else {
|
||||
this.parentElement.classList.remove('is-filled');
|
||||
}
|
||||
};
|
||||
|
||||
inputs[i].addEventListener('focusout', function(e) {
|
||||
if (this.value != "") {
|
||||
this.parentElement.classList.add('is-filled');
|
||||
}
|
||||
this.parentElement.classList.remove('is-focused');
|
||||
}, false);
|
||||
}
|
||||
|
||||
// Ripple Effect
|
||||
var ripples = document.querySelectorAll('.btn');
|
||||
|
||||
for (var i = 0; i < ripples.length; i++) {
|
||||
ripples[i].addEventListener('click', function(e) {
|
||||
var targetEl = e.target;
|
||||
var rippleDiv = targetEl.querySelector('.ripple');
|
||||
|
||||
rippleDiv = document.createElement('span');
|
||||
rippleDiv.classList.add('ripple');
|
||||
rippleDiv.style.width = rippleDiv.style.height = Math.max(targetEl.offsetWidth, targetEl.offsetHeight) + 'px';
|
||||
targetEl.appendChild(rippleDiv);
|
||||
|
||||
rippleDiv.style.left = (e.offsetX - rippleDiv.offsetWidth / 2) + 'px';
|
||||
rippleDiv.style.top = (e.offsetY - rippleDiv.offsetHeight / 2) + 'px';
|
||||
rippleDiv.classList.add('ripple');
|
||||
setTimeout(function() {
|
||||
rippleDiv.parentElement.removeChild(rippleDiv);
|
||||
}, 600);
|
||||
}, false);
|
||||
}
|
||||
};
|
||||
|
||||
// Toggle Sidenav
|
||||
const iconNavbarSidenav = document.getElementById('iconNavbarSidenav');
|
||||
const iconSidenav = document.getElementById('iconSidenav');
|
||||
const sidenav = document.getElementById('sidenav-main');
|
||||
let body = document.getElementsByTagName('body')[0];
|
||||
let className = 'g-sidenav-pinned';
|
||||
|
||||
if (iconNavbarSidenav) {
|
||||
iconNavbarSidenav.addEventListener("click", toggleSidenav);
|
||||
}
|
||||
|
||||
if (iconSidenav) {
|
||||
iconSidenav.addEventListener("click", toggleSidenav);
|
||||
}
|
||||
|
||||
function toggleSidenav() {
|
||||
if (body.classList.contains(className)) {
|
||||
body.classList.remove(className);
|
||||
setTimeout(function() {
|
||||
sidenav.classList.remove('bg-white');
|
||||
}, 100);
|
||||
sidenav.classList.remove('bg-transparent');
|
||||
|
||||
} else {
|
||||
body.classList.add(className);
|
||||
sidenav.classList.add('bg-white');
|
||||
sidenav.classList.remove('bg-transparent');
|
||||
iconSidenav.classList.remove('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
// Resize navbar color depends on configurator active type of sidenav
|
||||
|
||||
let referenceButtons = document.querySelector('[data-class]');
|
||||
|
||||
if (sidenav) {
|
||||
window.addEventListener("resize", navbarColorOnResize);
|
||||
|
||||
function navbarColorOnResize() {
|
||||
if (window.innerWidth > 1200) {
|
||||
if (referenceButtons?.classList.contains('active') && referenceButtons?.getAttribute('data-class') === 'bg-transparent') {
|
||||
sidenav.classList.remove('bg-white');
|
||||
} else {
|
||||
sidenav.classList.add('bg-white');
|
||||
}
|
||||
} else {
|
||||
sidenav.classList.add('bg-white');
|
||||
sidenav.classList.remove('bg-transparent');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deactivate sidenav type buttons on resize and small screens
|
||||
window.addEventListener("resize", sidenavTypeOnResize);
|
||||
window.addEventListener("load", sidenavTypeOnResize);
|
||||
|
||||
function sidenavTypeOnResize() {
|
||||
let elements = document.querySelectorAll('[onclick="sidebarType(this)"]');
|
||||
if (window.innerWidth < 1200) {
|
||||
elements.forEach(function(el) {
|
||||
el.classList.add('disabled');
|
||||
});
|
||||
} else {
|
||||
elements.forEach(function(el) {
|
||||
el.classList.remove('disabled');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Light Mode / Dark Mode
|
||||
function darkMode(el) {
|
||||
const body = document.getElementsByTagName('body')[0];
|
||||
const hr = document.querySelectorAll('div:not(.sidenav) > hr');
|
||||
const hr_card = document.querySelectorAll('div:not(.bg-gradient-dark) hr');
|
||||
const text_btn = document.querySelectorAll('button:not(.btn) > .text-dark');
|
||||
const text_span = document.querySelectorAll('span.text-dark, .breadcrumb .text-dark');
|
||||
const text_span_white = document.querySelectorAll('span.text-white, .breadcrumb .text-white');
|
||||
const text_strong = document.querySelectorAll('strong.text-dark');
|
||||
const text_strong_white = document.querySelectorAll('strong.text-white');
|
||||
const text_nav_link = document.querySelectorAll('a.nav-link.text-dark');
|
||||
const text_nav_link_white = document.querySelectorAll('a.nav-link.text-white');
|
||||
const secondary = document.querySelectorAll('.text-secondary');
|
||||
const bg_gray_100 = document.querySelectorAll('.bg-gray-100');
|
||||
const bg_gray_600 = document.querySelectorAll('.bg-gray-600');
|
||||
const btn_text_dark = document.querySelectorAll('.btn.btn-link.text-dark, .material-icons.text-dark');
|
||||
const btn_text_white = document.querySelectorAll('.btn.btn-link.text-white, .material-icons.text-white');
|
||||
const card_border = document.querySelectorAll('.card.border');
|
||||
const card_border_dark = document.querySelectorAll('.card.border.border-dark');
|
||||
|
||||
const svg = document.querySelectorAll('g');
|
||||
|
||||
if (!el.getAttribute("checked")) {
|
||||
body.classList.add('dark-version');
|
||||
for (var i = 0; i < hr.length; i++) {
|
||||
if (hr[i].classList.contains('dark')) {
|
||||
hr[i].classList.remove('dark');
|
||||
hr[i].classList.add('light');
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < hr_card.length; i++) {
|
||||
if (hr_card[i].classList.contains('dark')) {
|
||||
hr_card[i].classList.remove('dark');
|
||||
hr_card[i].classList.add('light');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_btn.length; i++) {
|
||||
if (text_btn[i].classList.contains('text-dark')) {
|
||||
text_btn[i].classList.remove('text-dark');
|
||||
text_btn[i].classList.add('text-white');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_span.length; i++) {
|
||||
if (text_span[i].classList.contains('text-dark')) {
|
||||
text_span[i].classList.remove('text-dark');
|
||||
text_span[i].classList.add('text-white');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_strong.length; i++) {
|
||||
if (text_strong[i].classList.contains('text-dark')) {
|
||||
text_strong[i].classList.remove('text-dark');
|
||||
text_strong[i].classList.add('text-white');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_nav_link.length; i++) {
|
||||
if (text_nav_link[i].classList.contains('text-dark')) {
|
||||
text_nav_link[i].classList.remove('text-dark');
|
||||
text_nav_link[i].classList.add('text-white');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < secondary.length; i++) {
|
||||
if (secondary[i].classList.contains('text-secondary')) {
|
||||
secondary[i].classList.remove('text-secondary');
|
||||
secondary[i].classList.add('text-white');
|
||||
secondary[i].classList.add('opacity-8');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < bg_gray_100.length; i++) {
|
||||
if (bg_gray_100[i].classList.contains('bg-gray-100')) {
|
||||
bg_gray_100[i].classList.remove('bg-gray-100');
|
||||
bg_gray_100[i].classList.add('bg-gray-600');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < btn_text_dark.length; i++) {
|
||||
btn_text_dark[i].classList.remove('text-dark');
|
||||
btn_text_dark[i].classList.add('text-white');
|
||||
}
|
||||
for (var i = 0; i < svg.length; i++) {
|
||||
if (svg[i].hasAttribute('fill')) {
|
||||
svg[i].setAttribute('fill', '#fff');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < card_border.length; i++) {
|
||||
card_border[i].classList.add('border-dark');
|
||||
}
|
||||
el.setAttribute("checked", "true");
|
||||
} else {
|
||||
body.classList.remove('dark-version');
|
||||
for (var i = 0; i < hr.length; i++) {
|
||||
if (hr[i].classList.contains('light')) {
|
||||
hr[i].classList.add('dark');
|
||||
hr[i].classList.remove('light');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < hr_card.length; i++) {
|
||||
if (hr_card[i].classList.contains('light')) {
|
||||
hr_card[i].classList.add('dark');
|
||||
hr_card[i].classList.remove('light');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_btn.length; i++) {
|
||||
if (text_btn[i].classList.contains('text-white')) {
|
||||
text_btn[i].classList.remove('text-white');
|
||||
text_btn[i].classList.add('text-dark');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_span_white.length; i++) {
|
||||
if (text_span_white[i].classList.contains('text-white') && !text_span_white[i].closest('.sidenav') && !text_span_white[i].closest('.card.bg-gradient-dark')) {
|
||||
text_span_white[i].classList.remove('text-white');
|
||||
text_span_white[i].classList.add('text-dark');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_strong_white.length; i++) {
|
||||
if (text_strong_white[i].classList.contains('text-white')) {
|
||||
text_strong_white[i].classList.remove('text-white');
|
||||
text_strong_white[i].classList.add('text-dark');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < text_nav_link_white.length; i++) {
|
||||
if (text_nav_link_white[i].classList.contains('text-white') && !text_nav_link_white[i].closest('.sidenav')) {
|
||||
text_nav_link_white[i].classList.remove('text-white');
|
||||
text_nav_link_white[i].classList.add('text-dark');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < secondary.length; i++) {
|
||||
if (secondary[i].classList.contains('text-white')) {
|
||||
secondary[i].classList.remove('text-white');
|
||||
secondary[i].classList.remove('opacity-8');
|
||||
secondary[i].classList.add('text-dark');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < bg_gray_600.length; i++) {
|
||||
if (bg_gray_600[i].classList.contains('bg-gray-600')) {
|
||||
bg_gray_600[i].classList.remove('bg-gray-600');
|
||||
bg_gray_600[i].classList.add('bg-gray-100');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < svg.length; i++) {
|
||||
if (svg[i].hasAttribute('fill')) {
|
||||
svg[i].setAttribute('fill', '#252f40');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < btn_text_white.length; i++) {
|
||||
if (!btn_text_white[i].closest('.card.bg-gradient-dark')) {
|
||||
btn_text_white[i].classList.remove('text-white');
|
||||
btn_text_white[i].classList.add('text-dark');
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < card_border_dark.length; i++) {
|
||||
card_border_dark[i].classList.remove('border-dark');
|
||||
}
|
||||
el.removeAttribute("checked");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// side bullets
|
||||
|
||||
const indicators = document.querySelectorAll(".indicator");
|
||||
const sections = document.querySelectorAll("section");
|
||||
|
||||
if (indicators) {
|
||||
const resetCurrentActiveIndicator = () => {
|
||||
const activeIndicator = document.querySelector(".indicator.active");
|
||||
if (activeIndicator) {
|
||||
activeIndicator.classList.remove("active");
|
||||
}
|
||||
};
|
||||
|
||||
const onSectionLeavesViewport = (section) => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
resetCurrentActiveIndicator();
|
||||
const element = entry.target;
|
||||
const indicator = document.querySelector(`a[href='#${element.id}']`);
|
||||
indicator.classList.add("active");
|
||||
return;
|
||||
}
|
||||
});
|
||||
}, {
|
||||
root: null,
|
||||
rootMargin: "0px",
|
||||
threshold: 0.75
|
||||
}
|
||||
);
|
||||
observer.observe(section);
|
||||
};
|
||||
|
||||
indicators.forEach((indicator) => {
|
||||
indicator.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
document
|
||||
.querySelector(this.getAttribute("href"))
|
||||
.scrollIntoView({
|
||||
behavior: "smooth"
|
||||
});
|
||||
resetCurrentActiveIndicator();
|
||||
this.classList.add("active");
|
||||
});
|
||||
});
|
||||
|
||||
sections.forEach(onSectionLeavesViewport);
|
||||
}
|
||||
17
company_site/financial/static/financial/js/material-dashboard.min.js
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// Chart extension for making the bars rounded
|
||||
// Code from: https://codepen.io/jedtrow/full/ygRYgo
|
||||
//
|
||||
|
||||
Chart.elements.Rectangle.prototype.draw = function() {
|
||||
|
||||
var ctx = this._chart.ctx;
|
||||
var vm = this._view;
|
||||
var left, right, top, bottom, signX, signY, borderSkipped, radius;
|
||||
var borderWidth = vm.borderWidth;
|
||||
// Set Radius Here
|
||||
// If radius is large enough to cause drawing errors a max radius is imposed
|
||||
var cornerRadius = 6;
|
||||
|
||||
if (!vm.horizontal) {
|
||||
// bar
|
||||
left = vm.x - vm.width / 2;
|
||||
right = vm.x + vm.width / 2;
|
||||
top = vm.y;
|
||||
bottom = vm.base;
|
||||
signX = 1;
|
||||
signY = bottom > top ? 1 : -1;
|
||||
borderSkipped = vm.borderSkipped || 'bottom';
|
||||
} else {
|
||||
// horizontal bar
|
||||
left = vm.base;
|
||||
right = vm.x;
|
||||
top = vm.y - vm.height / 2;
|
||||
bottom = vm.y + vm.height / 2;
|
||||
signX = right > left ? 1 : -1;
|
||||
signY = 1;
|
||||
borderSkipped = vm.borderSkipped || 'left';
|
||||
}
|
||||
|
||||
// Canvas doesn't allow us to stroke inside the width so we can
|
||||
// adjust the sizes to fit if we're setting a stroke on the line
|
||||
if (borderWidth) {
|
||||
// borderWidth shold be less than bar width and bar height.
|
||||
var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom));
|
||||
borderWidth = borderWidth > barSize ? barSize : borderWidth;
|
||||
var halfStroke = borderWidth / 2;
|
||||
// Adjust borderWidth when bar top position is near vm.base(zero).
|
||||
var borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0);
|
||||
var borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0);
|
||||
var borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0);
|
||||
var borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0);
|
||||
// not become a vertical line?
|
||||
if (borderLeft !== borderRight) {
|
||||
top = borderTop;
|
||||
bottom = borderBottom;
|
||||
}
|
||||
// not become a horizontal line?
|
||||
if (borderTop !== borderBottom) {
|
||||
left = borderLeft;
|
||||
right = borderRight;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = vm.backgroundColor;
|
||||
ctx.strokeStyle = vm.borderColor;
|
||||
ctx.lineWidth = borderWidth;
|
||||
|
||||
// Corner points, from bottom-left to bottom-right clockwise
|
||||
// | 1 2 |
|
||||
// | 0 3 |
|
||||
var corners = [
|
||||
[left, bottom],
|
||||
[left, top],
|
||||
[right, top],
|
||||
[right, bottom]
|
||||
];
|
||||
|
||||
// Find first (starting) corner with fallback to 'bottom'
|
||||
var borders = ['bottom', 'left', 'top', 'right'];
|
||||
var startCorner = borders.indexOf(borderSkipped, 0);
|
||||
if (startCorner === -1) {
|
||||
startCorner = 0;
|
||||
}
|
||||
|
||||
function cornerAt(index) {
|
||||
return corners[(startCorner + index) % 4];
|
||||
}
|
||||
|
||||
// Draw rectangle from 'startCorner'
|
||||
var corner = cornerAt(0);
|
||||
ctx.moveTo(corner[0], corner[1]);
|
||||
|
||||
for (var i = 1; i < 4; i++) {
|
||||
corner = cornerAt(i);
|
||||
nextCornerId = i + 1;
|
||||
if (nextCornerId == 4) {
|
||||
nextCornerId = 0
|
||||
}
|
||||
|
||||
nextCorner = cornerAt(nextCornerId);
|
||||
|
||||
width = corners[2][0] - corners[1][0];
|
||||
height = corners[0][1] - corners[1][1];
|
||||
x = corners[1][0];
|
||||
y = corners[1][1];
|
||||
|
||||
var radius = cornerRadius;
|
||||
|
||||
// Fix radius being too large
|
||||
if (radius > height / 2) {
|
||||
radius = height / 2;
|
||||
}
|
||||
if (radius > width / 2) {
|
||||
radius = width / 2;
|
||||
}
|
||||
|
||||
ctx.moveTo(x + radius, y);
|
||||
ctx.lineTo(x + width - radius, y);
|
||||
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
||||
ctx.lineTo(x + width, y + height - radius);
|
||||
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
||||
ctx.lineTo(x + radius, y + height);
|
||||
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
||||
ctx.lineTo(x, y + radius);
|
||||
ctx.quadraticCurveTo(x, y, x + radius, y);
|
||||
|
||||
}
|
||||
|
||||
ctx.fill();
|
||||
if (borderWidth) {
|
||||
ctx.stroke();
|
||||
}
|
||||
};
|
||||
432
company_site/financial/static/financial/js/plugins/bootstrap-notify.js
vendored
Normal file
@@ -0,0 +1,432 @@
|
||||
/*
|
||||
|
||||
|
||||
|
||||
Creative Tim Modifications
|
||||
|
||||
Lines: 238, 239 was changed from top: 5px to top: 50% and we added margin-top: -13px. In this way the close button will be aligned vertically
|
||||
Line:222 - modified when the icon is set, we add the class "alert-with-icon", so there will be enough space for the icon.
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Project: Bootstrap Notify = v3.1.5
|
||||
* Description: Turns standard Bootstrap alerts into "Growl-like" notifications.
|
||||
* Author: Mouse0270 aka Robert McIntosh
|
||||
* License: MIT License
|
||||
* Website: https://github.com/mouse0270/bootstrap-growl
|
||||
*/
|
||||
|
||||
/* global define:false, require: false, jQuery:false */
|
||||
|
||||
(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
// Create the defaults once
|
||||
var defaults = {
|
||||
element: 'body',
|
||||
position: null,
|
||||
type: "info",
|
||||
allow_dismiss: true,
|
||||
allow_duplicates: true,
|
||||
newest_on_top: false,
|
||||
showProgressbar: false,
|
||||
placement: {
|
||||
from: "top",
|
||||
align: "right"
|
||||
},
|
||||
offset: 20,
|
||||
spacing: 10,
|
||||
z_index: 1060,
|
||||
delay: 5000,
|
||||
timer: 1000,
|
||||
url_target: '_blank',
|
||||
mouse_over: null,
|
||||
animate: {
|
||||
enter: 'animated fadeInDown',
|
||||
exit: 'animated fadeOutUp'
|
||||
},
|
||||
onShow: null,
|
||||
onShown: null,
|
||||
onClose: null,
|
||||
onClosed: null,
|
||||
onClick: null,
|
||||
icon_type: 'class',
|
||||
template: '<div data-notify="container" class="col-xs-11 col-sm-4 alert alert-{0}" role="alert"><button type="button" aria-hidden="true" class="close" data-notify="dismiss"><i class="tim-icons icon-simple-remove"></i></button><span data-notify="icon"></span> <span data-notify="title">{1}</span> <span data-notify="message">{2}</span><div class="progress" data-notify="progressbar"><div class="progress-bar progress-bar-{0}" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div></div><a href="{3}" target="{4}" data-notify="url"></a></div>'
|
||||
};
|
||||
|
||||
String.format = function() {
|
||||
var args = arguments;
|
||||
var str = arguments[0];
|
||||
return str.replace(/(\{\{\d\}\}|\{\d\})/g, function(str) {
|
||||
if (str.substring(0, 2) === "{{") return str;
|
||||
var num = parseInt(str.match(/\d/)[0]);
|
||||
return args[num + 1];
|
||||
});
|
||||
};
|
||||
|
||||
function isDuplicateNotification(notification) {
|
||||
var isDupe = false;
|
||||
|
||||
$('[data-notify="container"]').each(function(i, el) {
|
||||
var $el = $(el);
|
||||
var title = $el.find('[data-notify="title"]').html().trim();
|
||||
var message = $el.find('[data-notify="message"]').html().trim();
|
||||
|
||||
// The input string might be different than the actual parsed HTML string!
|
||||
// (<br> vs <br /> for example)
|
||||
// So we have to force-parse this as HTML here!
|
||||
var isSameTitle = title === $("<div>" + notification.settings.content.title + "</div>").html().trim();
|
||||
var isSameMsg = message === $("<div>" + notification.settings.content.message + "</div>").html().trim();
|
||||
var isSameType = $el.hasClass('alert-' + notification.settings.type);
|
||||
|
||||
if (isSameTitle && isSameMsg && isSameType) {
|
||||
//we found the dupe. Set the var and stop checking.
|
||||
isDupe = true;
|
||||
}
|
||||
return !isDupe;
|
||||
});
|
||||
|
||||
return isDupe;
|
||||
}
|
||||
|
||||
function Notify(element, content, options) {
|
||||
// Setup Content of Notify
|
||||
var contentObj = {
|
||||
content: {
|
||||
message: typeof content === 'object' ? content.message : content,
|
||||
title: content.title ? content.title : '',
|
||||
icon: content.icon ? content.icon : '',
|
||||
url: content.url ? content.url : '#',
|
||||
target: content.target ? content.target : '-'
|
||||
}
|
||||
};
|
||||
|
||||
options = $.extend(true, {}, contentObj, options);
|
||||
this.settings = $.extend(true, {}, defaults, options);
|
||||
this._defaults = defaults;
|
||||
if (this.settings.content.target === "-") {
|
||||
this.settings.content.target = this.settings.url_target;
|
||||
}
|
||||
this.animations = {
|
||||
start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart',
|
||||
end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend'
|
||||
};
|
||||
|
||||
if (typeof this.settings.offset === 'number') {
|
||||
this.settings.offset = {
|
||||
x: this.settings.offset,
|
||||
y: this.settings.offset
|
||||
};
|
||||
}
|
||||
|
||||
//if duplicate messages are not allowed, then only continue if this new message is not a duplicate of one that it already showing
|
||||
if (this.settings.allow_duplicates || (!this.settings.allow_duplicates && !isDuplicateNotification(this))) {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
||||
$.extend(Notify.prototype, {
|
||||
init: function() {
|
||||
var self = this;
|
||||
|
||||
this.buildNotify();
|
||||
if (this.settings.content.icon) {
|
||||
this.setIcon();
|
||||
}
|
||||
if (this.settings.content.url != "#") {
|
||||
this.styleURL();
|
||||
}
|
||||
this.styleDismiss();
|
||||
this.placement();
|
||||
this.bind();
|
||||
|
||||
this.notify = {
|
||||
$ele: this.$ele,
|
||||
update: function(command, update) {
|
||||
var commands = {};
|
||||
if (typeof command === "string") {
|
||||
commands[command] = update;
|
||||
} else {
|
||||
commands = command;
|
||||
}
|
||||
for (var cmd in commands) {
|
||||
switch (cmd) {
|
||||
case "type":
|
||||
this.$ele.removeClass('alert-' + self.settings.type);
|
||||
this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass('progress-bar-' + self.settings.type);
|
||||
self.settings.type = commands[cmd];
|
||||
this.$ele.addClass('alert-' + commands[cmd]).find('[data-notify="progressbar"] > .progress-bar').addClass('progress-bar-' + commands[cmd]);
|
||||
break;
|
||||
case "icon":
|
||||
var $icon = this.$ele.find('[data-notify="icon"]');
|
||||
if (self.settings.icon_type.toLowerCase() === 'class') {
|
||||
$icon.removeClass(self.settings.content.icon).addClass(commands[cmd]);
|
||||
} else {
|
||||
if (!$icon.is('img')) {
|
||||
$icon.find('img');
|
||||
}
|
||||
$icon.attr('src', commands[cmd]);
|
||||
}
|
||||
self.settings.content.icon = commands[command];
|
||||
break;
|
||||
case "progress":
|
||||
var newDelay = self.settings.delay - (self.settings.delay * (commands[cmd] / 100));
|
||||
this.$ele.data('notify-delay', newDelay);
|
||||
this.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', commands[cmd]).css('width', commands[cmd] + '%');
|
||||
break;
|
||||
case "url":
|
||||
this.$ele.find('[data-notify="url"]').attr('href', commands[cmd]);
|
||||
break;
|
||||
case "target":
|
||||
this.$ele.find('[data-notify="url"]').attr('target', commands[cmd]);
|
||||
break;
|
||||
default:
|
||||
this.$ele.find('[data-notify="' + cmd + '"]').html(commands[cmd]);
|
||||
}
|
||||
}
|
||||
var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y);
|
||||
self.reposition(posX);
|
||||
},
|
||||
close: function() {
|
||||
self.close();
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
buildNotify: function() {
|
||||
var content = this.settings.content;
|
||||
this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target));
|
||||
this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align);
|
||||
if (!this.settings.allow_dismiss) {
|
||||
this.$ele.find('[data-notify="dismiss"]').css('display', 'none');
|
||||
}
|
||||
if ((this.settings.delay <= 0 && !this.settings.showProgressbar) || !this.settings.showProgressbar) {
|
||||
this.$ele.find('[data-notify="progressbar"]').remove();
|
||||
}
|
||||
},
|
||||
setIcon: function() {
|
||||
this.$ele.addClass('alert-with-icon');
|
||||
|
||||
if (this.settings.icon_type.toLowerCase() === 'class') {
|
||||
this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon);
|
||||
} else {
|
||||
if (this.$ele.find('[data-notify="icon"]').is('img')) {
|
||||
this.$ele.find('[data-notify="icon"]').attr('src', this.settings.content.icon);
|
||||
} else {
|
||||
this.$ele.find('[data-notify="icon"]').append('<img src="' + this.settings.content.icon + '" alt="Notify Icon" />');
|
||||
}
|
||||
}
|
||||
},
|
||||
styleDismiss: function() {
|
||||
this.$ele.find('[data-notify="dismiss"]').css({
|
||||
position: 'absolute',
|
||||
right: '10px',
|
||||
top: '50%',
|
||||
marginTop: '-13px',
|
||||
zIndex: this.settings.z_index + 2
|
||||
});
|
||||
},
|
||||
styleURL: function() {
|
||||
this.$ele.find('[data-notify="url"]').css({
|
||||
backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)',
|
||||
height: '100%',
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
width: '100%',
|
||||
zIndex: this.settings.z_index + 1
|
||||
});
|
||||
},
|
||||
placement: function() {
|
||||
var self = this,
|
||||
offsetAmt = this.settings.offset.y,
|
||||
css = {
|
||||
display: 'inline-block',
|
||||
margin: '0px auto',
|
||||
position: this.settings.position ? this.settings.position : (this.settings.element === 'body' ? 'fixed' : 'absolute'),
|
||||
transition: 'all .5s ease-in-out',
|
||||
zIndex: this.settings.z_index
|
||||
},
|
||||
hasAnimation = false,
|
||||
settings = this.settings;
|
||||
|
||||
$('[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])').each(function() {
|
||||
offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + parseInt($(this).outerHeight()) + parseInt(settings.spacing));
|
||||
});
|
||||
if (this.settings.newest_on_top === true) {
|
||||
offsetAmt = this.settings.offset.y;
|
||||
}
|
||||
css[this.settings.placement.from] = offsetAmt + 'px';
|
||||
|
||||
switch (this.settings.placement.align) {
|
||||
case "left":
|
||||
case "right":
|
||||
css[this.settings.placement.align] = this.settings.offset.x + 'px';
|
||||
break;
|
||||
case "center":
|
||||
css.left = 0;
|
||||
css.right = 0;
|
||||
break;
|
||||
}
|
||||
this.$ele.css(css).addClass(this.settings.animate.enter);
|
||||
$.each(Array('webkit-', 'moz-', 'o-', 'ms-', ''), function(index, prefix) {
|
||||
self.$ele[0].style[prefix + 'AnimationIterationCount'] = 1;
|
||||
});
|
||||
|
||||
$(this.settings.element).append(this.$ele);
|
||||
|
||||
if (this.settings.newest_on_top === true) {
|
||||
offsetAmt = (parseInt(offsetAmt) + parseInt(this.settings.spacing)) + this.$ele.outerHeight();
|
||||
this.reposition(offsetAmt);
|
||||
}
|
||||
|
||||
if ($.isFunction(self.settings.onShow)) {
|
||||
self.settings.onShow.call(this.$ele);
|
||||
}
|
||||
|
||||
this.$ele.one(this.animations.start, function() {
|
||||
hasAnimation = true;
|
||||
}).one(this.animations.end, function() {
|
||||
self.$ele.removeClass(self.settings.animate.enter);
|
||||
if ($.isFunction(self.settings.onShown)) {
|
||||
self.settings.onShown.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
if (!hasAnimation) {
|
||||
if ($.isFunction(self.settings.onShown)) {
|
||||
self.settings.onShown.call(this);
|
||||
}
|
||||
}
|
||||
}, 600);
|
||||
},
|
||||
bind: function() {
|
||||
var self = this;
|
||||
|
||||
this.$ele.find('[data-notify="dismiss"]').on('click', function() {
|
||||
self.close();
|
||||
});
|
||||
|
||||
if ($.isFunction(self.settings.onClick)) {
|
||||
this.$ele.on('click', function(event) {
|
||||
if (event.target != self.$ele.find('[data-notify="dismiss"]')[0]) {
|
||||
self.settings.onClick.call(this, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.$ele.mouseover(function() {
|
||||
$(this).data('data-hover', "true");
|
||||
}).mouseout(function() {
|
||||
$(this).data('data-hover', "false");
|
||||
});
|
||||
this.$ele.data('data-hover', "false");
|
||||
|
||||
if (this.settings.delay > 0) {
|
||||
self.$ele.data('notify-delay', self.settings.delay);
|
||||
var timer = setInterval(function() {
|
||||
var delay = parseInt(self.$ele.data('notify-delay')) - self.settings.timer;
|
||||
if ((self.$ele.data('data-hover') === 'false' && self.settings.mouse_over === "pause") || self.settings.mouse_over != "pause") {
|
||||
var percent = ((self.settings.delay - delay) / self.settings.delay) * 100;
|
||||
self.$ele.data('notify-delay', delay);
|
||||
self.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', percent).css('width', percent + '%');
|
||||
}
|
||||
if (delay <= -(self.settings.timer)) {
|
||||
clearInterval(timer);
|
||||
self.close();
|
||||
}
|
||||
}, self.settings.timer);
|
||||
}
|
||||
},
|
||||
close: function() {
|
||||
var self = this,
|
||||
posX = parseInt(this.$ele.css(this.settings.placement.from)),
|
||||
hasAnimation = false;
|
||||
|
||||
this.$ele.attr('data-closing', 'true').addClass(this.settings.animate.exit);
|
||||
self.reposition(posX);
|
||||
|
||||
if ($.isFunction(self.settings.onClose)) {
|
||||
self.settings.onClose.call(this.$ele);
|
||||
}
|
||||
|
||||
this.$ele.one(this.animations.start, function() {
|
||||
hasAnimation = true;
|
||||
}).one(this.animations.end, function() {
|
||||
$(this).remove();
|
||||
if ($.isFunction(self.settings.onClosed)) {
|
||||
self.settings.onClosed.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
if (!hasAnimation) {
|
||||
self.$ele.remove();
|
||||
if (self.settings.onClosed) {
|
||||
self.settings.onClosed(self.$ele);
|
||||
}
|
||||
}
|
||||
}, 600);
|
||||
},
|
||||
reposition: function(posX) {
|
||||
var self = this,
|
||||
notifies = '[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])',
|
||||
$elements = this.$ele.nextAll(notifies);
|
||||
if (this.settings.newest_on_top === true) {
|
||||
$elements = this.$ele.prevAll(notifies);
|
||||
}
|
||||
$elements.each(function() {
|
||||
$(this).css(self.settings.placement.from, posX);
|
||||
posX = (parseInt(posX) + parseInt(self.settings.spacing)) + $(this).outerHeight();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$.notify = function(content, options) {
|
||||
var plugin = new Notify(this, content, options);
|
||||
return plugin.notify;
|
||||
};
|
||||
$.notifyDefaults = function(options) {
|
||||
defaults = $.extend(true, {}, defaults, options);
|
||||
return defaults;
|
||||
};
|
||||
|
||||
$.notifyClose = function(selector) {
|
||||
|
||||
if (typeof selector === "undefined" || selector === "all") {
|
||||
$('[data-notify]').find('[data-notify="dismiss"]').trigger('click');
|
||||
} else if (selector === 'success' || selector === 'info' || selector === 'warning' || selector === 'danger') {
|
||||
$('.alert-' + selector + '[data-notify]').find('[data-notify="dismiss"]').trigger('click');
|
||||
} else if (selector) {
|
||||
$(selector + '[data-notify]').find('[data-notify="dismiss"]').trigger('click');
|
||||
} else {
|
||||
$('[data-notify-position="' + selector + '"]').find('[data-notify="dismiss"]').trigger('click');
|
||||
}
|
||||
};
|
||||
|
||||
$.notifyCloseExcept = function(selector) {
|
||||
|
||||
if (selector === 'success' || selector === 'info' || selector === 'warning' || selector === 'danger') {
|
||||
$('[data-notify]').not('.alert-' + selector).find('[data-notify="dismiss"]').trigger('click');
|
||||
} else {
|
||||
$('[data-notify]').not(selector).find('[data-notify="dismiss"]').trigger('click');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}));
|
||||
13
company_site/financial/static/financial/js/plugins/chartjs.min.js
vendored
Normal file
1
company_site/financial/static/financial/js/plugins/countup.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(t){for(var i,a=1,s=arguments.length;a<s;a++)for(var n in i=arguments[a])Object.prototype.hasOwnProperty.call(i,n)&&(t[n]=i[n]);return t}).apply(this,arguments)},CountUp=function(){function t(t,i,a){var s=this;this.target=t,this.endVal=i,this.options=a,this.version="2.0.7",this.defaults={startVal:0,decimalPlaces:0,duration:2,useEasing:!0,useGrouping:!0,smartEasingThreshold:999,smartEasingAmount:333,separator:",",decimal:".",prefix:"",suffix:""},this.finalEndVal=null,this.useEasing=!0,this.countDown=!1,this.error="",this.startVal=0,this.paused=!0,this.count=function(t){s.startTime||(s.startTime=t);var i=t-s.startTime;s.remaining=s.duration-i,s.useEasing?s.countDown?s.frameVal=s.startVal-s.easingFn(i,0,s.startVal-s.endVal,s.duration):s.frameVal=s.easingFn(i,s.startVal,s.endVal-s.startVal,s.duration):s.countDown?s.frameVal=s.startVal-(s.startVal-s.endVal)*(i/s.duration):s.frameVal=s.startVal+(s.endVal-s.startVal)*(i/s.duration),s.countDown?s.frameVal=s.frameVal<s.endVal?s.endVal:s.frameVal:s.frameVal=s.frameVal>s.endVal?s.endVal:s.frameVal,s.frameVal=Number(s.frameVal.toFixed(s.options.decimalPlaces)),s.printValue(s.frameVal),i<s.duration?s.rAF=requestAnimationFrame(s.count):null!==s.finalEndVal?s.update(s.finalEndVal):s.callback&&s.callback()},this.formatNumber=function(t){var i,a,n,e,r,o=t<0?"-":"";if(i=Math.abs(t).toFixed(s.options.decimalPlaces),n=(a=(i+="").split("."))[0],e=a.length>1?s.options.decimal+a[1]:"",s.options.useGrouping){r="";for(var l=0,h=n.length;l<h;++l)0!==l&&l%3==0&&(r=s.options.separator+r),r=n[h-l-1]+r;n=r}return s.options.numerals&&s.options.numerals.length&&(n=n.replace(/[0-9]/g,function(t){return s.options.numerals[+t]}),e=e.replace(/[0-9]/g,function(t){return s.options.numerals[+t]})),o+s.options.prefix+n+e+s.options.suffix},this.easeOutExpo=function(t,i,a,s){return a*(1-Math.pow(2,-10*t/s))*1024/1023+i},this.options=__assign(__assign({},this.defaults),a),this.formattingFn=this.options.formattingFn?this.options.formattingFn:this.formatNumber,this.easingFn=this.options.easingFn?this.options.easingFn:this.easeOutExpo,this.startVal=this.validateValue(this.options.startVal),this.frameVal=this.startVal,this.endVal=this.validateValue(i),this.options.decimalPlaces=Math.max(this.options.decimalPlaces),this.resetDuration(),this.options.separator=String(this.options.separator),this.useEasing=this.options.useEasing,""===this.options.separator&&(this.options.useGrouping=!1),this.el="string"==typeof t?document.getElementById(t):t,this.el?this.printValue(this.startVal):this.error="[CountUp] target is null or undefined"}return t.prototype.determineDirectionAndSmartEasing=function(){var t=this.finalEndVal?this.finalEndVal:this.endVal;this.countDown=this.startVal>t;var i=t-this.startVal;if(Math.abs(i)>this.options.smartEasingThreshold){this.finalEndVal=t;var a=this.countDown?1:-1;this.endVal=t+a*this.options.smartEasingAmount,this.duration=this.duration/2}else this.endVal=t,this.finalEndVal=null;this.finalEndVal?this.useEasing=!1:this.useEasing=this.options.useEasing},t.prototype.start=function(t){this.error||(this.callback=t,this.duration>0?(this.determineDirectionAndSmartEasing(),this.paused=!1,this.rAF=requestAnimationFrame(this.count)):this.printValue(this.endVal))},t.prototype.pauseResume=function(){this.paused?(this.startTime=null,this.duration=this.remaining,this.startVal=this.frameVal,this.determineDirectionAndSmartEasing(),this.rAF=requestAnimationFrame(this.count)):cancelAnimationFrame(this.rAF),this.paused=!this.paused},t.prototype.reset=function(){cancelAnimationFrame(this.rAF),this.paused=!0,this.resetDuration(),this.startVal=this.validateValue(this.options.startVal),this.frameVal=this.startVal,this.printValue(this.startVal)},t.prototype.update=function(t){cancelAnimationFrame(this.rAF),this.startTime=null,this.endVal=this.validateValue(t),this.endVal!==this.frameVal&&(this.startVal=this.frameVal,this.finalEndVal||this.resetDuration(),this.finalEndVal=null,this.determineDirectionAndSmartEasing(),this.rAF=requestAnimationFrame(this.count))},t.prototype.printValue=function(t){var i=this.formattingFn(t);"INPUT"===this.el.tagName?this.el.value=i:"text"===this.el.tagName||"tspan"===this.el.tagName?this.el.textContent=i:this.el.innerHTML=i},t.prototype.ensureNumber=function(t){return"number"==typeof t&&!isNaN(t)},t.prototype.validateValue=function(t){var i=Number(t);return this.ensureNumber(i)?i:(this.error="[CountUp] invalid start or end value: "+t,null)},t.prototype.resetDuration=function(){this.startTime=null,this.duration=1e3*Number(this.options.duration),this.remaining=this.duration},t}();
|
||||
19
company_site/financial/static/financial/js/plugins/perfect-scrollbar.min.js
vendored
Normal file
25
company_site/financial/static/financial/js/plugins/smooth-scrollbar.min.js
vendored
Normal file
2464
company_site/financial/static/financial/js/plugins/world.js
Normal file
@@ -0,0 +1,55 @@
|
||||
<!-- a lot of stuff-->
|
||||
|
||||
<!doctype html>
|
||||
{% load static %}
|
||||
<html lang="en"">
|
||||
<head>
|
||||
<title>Contract Detail</title>
|
||||
<link href="{% static 'financial/css/material-dashboard.css' %}" rel="stylesheet" >
|
||||
<link rel="icon" type="image/xicon" href="{% static 'public/img/logo.png' %}">
|
||||
<body class="g-sidenav-show bg-gray-200" >
|
||||
|
||||
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg">
|
||||
|
||||
{% if is_new %}
|
||||
<h1>New Contract</h1>
|
||||
<form method="post" action='{% url "new_contract" %}' >
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<button type=""button" value="submit">Create</button>
|
||||
</form>
|
||||
|
||||
{% else %}
|
||||
<h1> {{ contract.name }}</h1>
|
||||
<form method="post" action='{% url "contract_detail" contract.slug %}' >
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<button type=""button" value="submit">Update</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% if is_new %}
|
||||
{% else %}
|
||||
<h2> Charge Numbers</h2>
|
||||
{% if charge_numbes %}
|
||||
<p> put charge number table here</p>
|
||||
<p> Create a new charge number</p>
|
||||
{{ charge_number_form }}
|
||||
{% else %}
|
||||
<p> There are no charge numbers for this contract</p>
|
||||
<form method="post" action='{% url "new_charge_number" %}' >
|
||||
{% csrf_token %}
|
||||
{{ charge_number_form }}
|
||||
<button type=""button" value="submit">Update</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
</body>
|
||||
49
company_site/financial/templates/financial/contracts.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!-- a lot of stuff-->
|
||||
|
||||
<!doctype html>
|
||||
{% load static %}
|
||||
<html lang="en"">
|
||||
<head>
|
||||
<title>Profile</title>
|
||||
<link href="{% static 'financial/css/material-dashboard.css' %}" rel="stylesheet" >
|
||||
<link rel="icon" type="image/xicon" href="{% static 'public/img/logo.png' %}">
|
||||
<body class="g-sidenav-show bg-gray-200" >
|
||||
|
||||
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg">
|
||||
|
||||
|
||||
<h1>Contracts</h1>
|
||||
{% if contracts %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Identifier</th>
|
||||
<th>Type</th>
|
||||
<th>Start Date</th>
|
||||
<th>End Date</th>
|
||||
<th>Proposed Amount</th>
|
||||
<th>Baseline Amount</th>
|
||||
<th>Funded Amount</th>
|
||||
</tr>
|
||||
|
||||
{% for contract in contracts %}
|
||||
<tr>
|
||||
<td> <a href="{% url 'contract_detail' contract.slug %}">{{ contract.name }}</a></td>
|
||||
<td> {{ contract.slug }}</td>
|
||||
<td> {{ contract.contract_type }}</td>
|
||||
<td> {{ contract.baseline_start }}</td>
|
||||
<td> {{ contract.baseline_end }}</td>
|
||||
<td> {{ contract.proposed_amount }}</td>
|
||||
<td> {{ contract.baseline_amount }}</td>
|
||||
<td> {{ contract.funded_amount }}</td>
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
</table>
|
||||
<hr>
|
||||
<p> Create <a href="{% url 'new_contract' %}">new</a> contract.</p>
|
||||
{% else %}
|
||||
<p> There are no contracts. <a href="{% url 'new_contract' %}">Please make one</a></p>
|
||||
|
||||
{% endif %}
|
||||
</body>
|
||||
116
company_site/financial/templates/financial/index.html
Normal file
@@ -0,0 +1,116 @@
|
||||
<!doctype html>
|
||||
{% load static %}
|
||||
<html lang="en"">
|
||||
<head>
|
||||
<title>Accounting</title>
|
||||
<link href="{% static 'financial/css/material-dashboard.css' %}" rel="stylesheet" >
|
||||
<link rel="icon" type="image/xicon" href="{% static 'public/img/logo.png' %}">
|
||||
<body class="g-sidenav-show bg-gray-200" >
|
||||
<div class="sidenav-header">
|
||||
<ul class="navbar-item">
|
||||
<li class="nav-item">
|
||||
Dashboard
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
Settings
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg">
|
||||
<nav class="navbar navbar-main navbar-expand-lg px-0 mx-4 shadow-none border-radius-xl" id="navbarBlur" data-scroll="true">
|
||||
<div class="container-fluid py-1 px-3">
|
||||
<nav aria-label="breadcrumb">
|
||||
<h6>Dashboard</h6>
|
||||
</nav>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid py-4">
|
||||
<div class="row">
|
||||
<div class="col-xl-3 col-sm-4 mb-xl-o mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header p-3 pt-2">
|
||||
<a href="{% url 'contracts' %}">
|
||||
Contracts
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div class="card-body">
|
||||
<p> put picture here</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if is_worker %}
|
||||
<div class="col-xl-3 col-sm-4 mb-xl-o mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header p-3 pt-2">
|
||||
<a href="{% url 'profile' %}">
|
||||
Profile
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div class="card-body">
|
||||
<p> put picture here</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if is_worker %}
|
||||
<div class="col-xl-3 col-sm-4 mb-xl-o mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header p-3 pt-2">
|
||||
<a href="{% url 'Timekeeping' %}">
|
||||
Timekeeping
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div class="card-body">
|
||||
<p> put picture here</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if is_manager %}
|
||||
<div class="col-xl-3 col-sm-4 mb-xl-o mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header p-3 pt-2">
|
||||
<a href="{% url 'Timeapproval' %}">
|
||||
Time Approval
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p> put picture here</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if is_procurment_officer %}
|
||||
<div class="col-xl-3 col-sm-4 mb-xl-o mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header p-3 pt-2">
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p> put picture here</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if is_finance %}
|
||||
<div class="col-xl-3 col-sm-4 mb-xl-o mb-4">
|
||||
<div class="card">
|
||||
<div class="card-header p-3 pt-2">
|
||||
<a href="{% url 'contracts' %}">
|
||||
Contracts
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p> put picture here</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<h1>Accouting</h1>
|
||||
</body>
|
||||
@@ -0,0 +1 @@
|
||||
<p> this page has not been created yet</p>
|
||||
17
company_site/financial/templates/financial/profile.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!-- a lot of stuff-->
|
||||
|
||||
<!doctype html>
|
||||
{% load static %}
|
||||
<html lang="en"">
|
||||
<head>
|
||||
<title>Profile</title>
|
||||
<link href="{% static 'financial/css/material-dashboard.css' %}" rel="stylesheet" >
|
||||
<link rel="icon" type="image/xicon" href="{% static 'public/img/logo.png' %}">
|
||||
<body class="g-sidenav-show bg-gray-200" >
|
||||
|
||||
<main class="main-content position-relative max-height-vh-100 h-100 border-radius-lg">
|
||||
|
||||
|
||||
<h1>Profile</h1>
|
||||
{{ form }}
|
||||
</body>
|
||||
3
company_site/financial/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
17
company_site/financial/urls.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.index, name="financial_index"),
|
||||
path("timekeeping", views.timekeeping, name="Timekeeping"),
|
||||
path("timeapproval", views.timeapproval, name="Timeapproval"),
|
||||
path("contracts", views.contracts, name="contracts"),
|
||||
path("<str:contract_slug>/contract_detail", views.contract_detail, name="contract_detail"),
|
||||
path("new_contract", views.new_contract, name="new_contract"),
|
||||
path("new_charge_number", views.new_charge_number, name="new_charge_number"),
|
||||
path("<str:charge_number_slug>/update_charge_number", views.update_charge_number, name="update_charge_number"),
|
||||
#path("contracts/<int:contract_id>/", views.contract_detail, name="contract"),
|
||||
path("procurements", views.procurement, name="procurements"),
|
||||
path("profile", views.profile, name="profile"),
|
||||
]
|
||||
79
company_site/financial/views.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from django.shortcuts import render, redirect
|
||||
from .forms import EmployeeForm, ContractForm, ChargeNumberForm
|
||||
from .models import Contract
|
||||
# Create your views here.
|
||||
|
||||
# PAGES TO CREATE
|
||||
# dashboard
|
||||
# log in
|
||||
# log out
|
||||
# password reset
|
||||
# employee timecard
|
||||
# time card approval
|
||||
# contract
|
||||
# charge number
|
||||
# user management (?)
|
||||
|
||||
def index(request):
|
||||
permissions = []
|
||||
context = {
|
||||
'is_procurment_officer':True,
|
||||
'is_worker':True,
|
||||
'is_manager':True,
|
||||
'is_finance': True
|
||||
|
||||
}
|
||||
return render(request, "financial/index.html", context)
|
||||
|
||||
def contracts(request):
|
||||
contracts = Contract.objects.all()
|
||||
return render(request, 'financial/contracts.html', {'contracts':contracts})
|
||||
|
||||
def contract_detail(request, contract_slug):
|
||||
contract = Contract.objects.filter(slug=contract_slug)
|
||||
if request.method == 'POST':
|
||||
form = ContractForm(request.POST, instance=contract[0])
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect('contracts')
|
||||
else:
|
||||
form = ContractForm(instance = contract[0])
|
||||
charge_number_form = ChargeNumberForm()
|
||||
# TODO: handle multiple better but we can assume there is only one
|
||||
|
||||
return render(request, 'financial/contract_detail.html', {'is_new': False, 'form': form, 'charge_number_form':charge_number_form, 'contract': contract[0]})
|
||||
|
||||
def new_contract(request):
|
||||
if request.method == "POST":
|
||||
form = ContractForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect('contracts')
|
||||
else:
|
||||
return render(request, 'financial/contract_detail.html', {"form": ContractForm(), 'is_new': True})
|
||||
|
||||
else:
|
||||
return render(request, 'financial/contract_detail.html', {"form": ContractForm(), 'is_new': True})
|
||||
|
||||
def update_charge_number(request, charge_number_slug):
|
||||
return render(request, 'financial/not_created.html', {})
|
||||
|
||||
def new_charge_number(request, charge_number_slug):
|
||||
return render(request, 'financial/not_created.html', {})
|
||||
|
||||
def timekeeping(request):
|
||||
return render(request, 'financial/not_created.html', {})
|
||||
|
||||
def timeapproval(request):
|
||||
return render(request, 'financial/not_created.html', {})
|
||||
|
||||
def chargenumber(request):
|
||||
return render(request, 'financial/not_created.html', {})
|
||||
|
||||
def procurement(request):
|
||||
return render(request, 'financial/procurement.html', {})
|
||||
|
||||
def profile(request):
|
||||
form = EmployeeForm()
|
||||
return render(request, 'financial/profile.html', {'form': form})
|
||||
# def contract_detail(request, contract_id):
|
||||
22
company_site/manage.py
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'company_site.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
0
company_site/public/__init__.py
Normal file
64
company_site/public/admin.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from django.contrib import admin
|
||||
from .models import Contact, EmailMessage
|
||||
from .views import preview_email
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.urls import path
|
||||
from django.template.loader import get_template
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
# Register your models here.
|
||||
|
||||
@admin.register(Contact, site=admin.site)
|
||||
class ContactAdmin(admin.ModelAdmin):
|
||||
list_display = ("email", "name", "contacted")
|
||||
list_filter = ("email", "name", "contacted")
|
||||
search_fields = ("email", "name")
|
||||
|
||||
@admin.action(description='Send seelcted emails')
|
||||
def send_emails(modeladmin, request, queryset):
|
||||
for email in queryset:
|
||||
success_count: int = 0
|
||||
try:
|
||||
from_email="info@aimloperations.com"
|
||||
d={"title":email.subject,"content":email.body}
|
||||
|
||||
html_content = get_template(f"emails/marketing_email.html").render(d)
|
||||
text_content = get_template(f"emails/marketing_email.txt").render(d)
|
||||
|
||||
msg = EmailMultiAlternatives(email.subject, text_content, from_email, [email.recipient])
|
||||
msg.attach_alternative(html_content, "text/html")
|
||||
|
||||
msg.send(fail_silently=False)
|
||||
|
||||
email.sent = True
|
||||
email.save()
|
||||
success_count += 1
|
||||
except Exception as e:
|
||||
raise UserWarning(e)
|
||||
modeladmin.message_user(request, f"{success_count} emails sent successfully.")
|
||||
|
||||
@admin.register(EmailMessage, site=admin.site)
|
||||
class EmailMessageAdmin(admin.ModelAdmin):
|
||||
change_form_template = 'admin/public/emailmessage/change_form.html'
|
||||
list_display = ('subject', 'recipient', 'sent')
|
||||
actions = [send_emails]
|
||||
|
||||
def get_urls(self):
|
||||
urls = super().get_urls()
|
||||
custom_urls = [
|
||||
path('preview_email/<int:pk>/', self.admin_site.admin_view(self.preview_email), name="preview_email")
|
||||
|
||||
]
|
||||
print(f'RETURNING: {custom_urls + urls}')
|
||||
return custom_urls + urls
|
||||
|
||||
def preview_email(self, request, pk):
|
||||
email_instance = get_object_or_404(EmailMessage, pk=pk)
|
||||
context = {
|
||||
"title":email_instance.subject,
|
||||
"content":email_instance.body
|
||||
}
|
||||
return render(
|
||||
request, 'public/preview_email.html', context
|
||||
)
|
||||
|
||||
|
||||
6
company_site/public/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PublicConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'public'
|
||||
15
company_site/public/forms.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django import forms
|
||||
from django_recaptcha.fields import ReCaptchaField
|
||||
from django_recaptcha.widgets import ReCaptchaV3
|
||||
from django.conf import settings
|
||||
|
||||
class FormWithCaptcha(forms.Form):
|
||||
captcha = ReCaptchaField(
|
||||
widget=ReCaptchaV3(
|
||||
attrs={
|
||||
'required_score':0.85,
|
||||
}
|
||||
),
|
||||
public_key=settings.RECAPTCHA_PUBLIC_KEY,
|
||||
private_key=settings.RECAPTCHA_PRIVATE_KEY,
|
||||
)
|
||||
23
company_site/public/migrations/0001_initial.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.0 on 2023-12-05 18:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Contact',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('email', models.EmailField(max_length=128)),
|
||||
('name', models.CharField(max_length=128)),
|
||||
('blurb', models.CharField(blank=True, max_length=254)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.0 on 2023-12-05 19:28
|
||||
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('public', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contact',
|
||||
name='created',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='contact',
|
||||
name='last_modified',
|
||||
field=models.DateTimeField(default=django.utils.timezone.now),
|
||||
),
|
||||
]
|
||||
18
company_site/public/migrations/0003_contact_contacted.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.0 on 2023-12-07 17:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('public', '0002_contact_created_contact_last_modified'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='contact',
|
||||
name='contacted',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
19
company_site/public/migrations/0004_contact_subject.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-10 17:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("public", "0003_contact_contacted"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="contact",
|
||||
name="subject",
|
||||
field=models.CharField(default=" ", max_length=128),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
40
company_site/public/migrations/0005_emailmessage.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-16 12:43
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("public", "0004_contact_subject"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="EmailMessage",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created", models.DateTimeField(default=django.utils.timezone.now)),
|
||||
(
|
||||
"last_modified",
|
||||
models.DateTimeField(default=django.utils.timezone.now),
|
||||
),
|
||||
("subject", models.CharField(max_length=255)),
|
||||
("body", models.TextField()),
|
||||
("recipient", models.EmailField(max_length=254)),
|
||||
("sent", models.BooleanField(default=False)),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
]
|
||||
0
company_site/public/migrations/__init__.py
Normal file
35
company_site/public/models.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
class TimeInfoBase(models.Model):
|
||||
|
||||
created = models.DateTimeField(default=timezone.now)
|
||||
last_modified = models.DateTimeField(default=timezone.now)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not kwargs.pop("skip_last_modified", False) and not hasattr(self, "skip_last_modified"):
|
||||
self.last_modified = timezone.now()
|
||||
if kwargs.get("update_fields") is not None:
|
||||
kwargs["update_fields"] = list({*kwargs["update_fields"], "last_modified"})
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# Create your models here.
|
||||
class Contact(TimeInfoBase):
|
||||
email = models.EmailField(max_length=128)
|
||||
name = models.CharField(max_length=128)
|
||||
blurb = models.CharField(max_length=254, blank=True)
|
||||
subject = models.CharField(max_length=128)
|
||||
contacted = models.BooleanField(default=False)
|
||||
|
||||
class EmailMessage(TimeInfoBase):
|
||||
subject = models.CharField(max_length=255)
|
||||
body = models.TextField()
|
||||
recipient = models.EmailField()
|
||||
sent = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.recipient + " | " + self.subject
|
||||
BIN
company_site/public/static/public/img/ansys_logo.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
company_site/public/static/public/img/background_w_logo.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
company_site/public/static/public/img/bg1.png
Normal file
|
After Width: | Height: | Size: 978 KiB |
BIN
company_site/public/static/public/img/bg2.jpeg
Normal file
|
After Width: | Height: | Size: 270 KiB |
BIN
company_site/public/static/public/img/bg3.png
Normal file
|
After Width: | Height: | Size: 1012 KiB |
BIN
company_site/public/static/public/img/bg4.jpeg
Normal file
|
After Width: | Height: | Size: 428 KiB |
BIN
company_site/public/static/public/img/chat_screenshot.png
Normal file
|
After Width: | Height: | Size: 291 KiB |
BIN
company_site/public/static/public/img/company_bg.png
Normal file
|
After Width: | Height: | Size: 695 B |
BIN
company_site/public/static/public/img/company_bg.xcf
Normal file
BIN
company_site/public/static/public/img/company_logo.xcf
Normal file
BIN
company_site/public/static/public/img/company_logo_main.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
company_site/public/static/public/img/logo.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,15 @@
|
||||
{% extends 'admin/change_form.html' %}
|
||||
|
||||
{% block submit_buttons_bottom %}
|
||||
<div class="submit-row">
|
||||
<!-- <input type="submit" value="Preview Email" name="_preview_email" class="default" /> -->
|
||||
<form action="/public/emailmessage/preview_email/{{ original.pk }}/" method="post" target="_blank" style="display: inline;">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="Preview Email" name="_preview_email" class="default" />
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
147
company_site/public/templates/base.html
Normal file
@@ -0,0 +1,147 @@
|
||||
<!DOCTYPE html>
|
||||
{% load static %}
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>AI ML Operations, LLC</title>
|
||||
<!-- Materialize CSS -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet">
|
||||
<link rel="icon" type="image/xicon" href="{% static 'public/img/logo.png' %}">
|
||||
<!-- Material Icons -->
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<!-- Custom CSS -->
|
||||
<style>
|
||||
.hero-section {
|
||||
background: {% block path %}url({% static 'public/img/bg1.png' %}) {% endblock %};
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
background-repeat:no-repeat;
|
||||
background-position: center center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
color: white;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.hero-section h1 {
|
||||
font-size: 4rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.hero-section p {
|
||||
font-weight: bold;
|
||||
}
|
||||
.section {
|
||||
padding: 4rem 0;
|
||||
}
|
||||
feature-icon {
|
||||
font-size: 3rem;
|
||||
color: #26a69a;
|
||||
}
|
||||
.pricing-card {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.screenshot-img {
|
||||
width: 100%;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
}
|
||||
.footer {
|
||||
padding: 2rem 0;
|
||||
background-color: #333;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
}
|
||||
main {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Navigation Bar -->
|
||||
<ul id="servicesDropdown" class="dropdown-content">
|
||||
<li ><a href="{% url 'ai_education' %}">AI Education</a></li>
|
||||
<li ><a href="{% url 'ai_sensor' %}">AI Sensor</a></li>
|
||||
<li ><a href="{% url 'bot' %}">Bot Creation</a></li>
|
||||
<li class="active"><a href="{% url 'chat' %}">Chat</a></li>
|
||||
<li ><a href="{% url 'computers' %}">Computer Builds</a></li>
|
||||
<li ><a href="{% url 'file_hosting' %}">File Hosting</a></li>
|
||||
<li ><a href="{% url 'ml_model' %}">ML Models</a></li>
|
||||
<li ><a href="{% url 'web_design' %}">Website Design</a></li>
|
||||
|
||||
|
||||
</ul>
|
||||
<nav class="blue-grey darken-3">
|
||||
<div class="nav-wrapper container">
|
||||
<a href="{% url 'public_index' %}" class="brand-logo">AI ML Operations, LLC</a>
|
||||
<a href="#" data-target="mobile-nav" class="sidenav-trigger"><i class="material-icons">menu</i></a>
|
||||
<ul class="right hide-on-med-and-down">
|
||||
<!-- <li class="active"><a href="{% url 'public_index' %}">Home</a></li> -->
|
||||
<li><a class="dropdown-trigger" href="#!" data-target="servicesDropdown">Services<i class="material-icons right">arrow_drop_down</i></a></li>
|
||||
<li><a href="{% url 'contact' %}">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Mobile Navigation -->
|
||||
<ul class="sidenav" id="mobile-nav">
|
||||
<li class="active"><a >Services</a></li>
|
||||
<hr />
|
||||
<li ><a href="{% url 'ai_education' %}">AI Education</a></li>
|
||||
<li ><a href="{% url 'ai_sensor' %}">AI Sensor</a></li>
|
||||
<li ><a href="{% url 'bot' %}">Bot Creation</a></li>
|
||||
<li ><a href="{% url 'chat' %}">Chat</a></li>
|
||||
<li ><a href="{% url 'computers' %}">Computer Builds</a></li>
|
||||
<li ><a href="{% url 'file_hosting' %}">File Hosting</a></li>
|
||||
<li ><a href="{% url 'ml_model' %}">ML Models</a></li>
|
||||
<li ><a href="{% url 'web_design' %}">Website Design</a></li>
|
||||
<hr/>
|
||||
|
||||
<li class="active"><a href="{% url 'contact' %}">Contact</a></li>
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<main>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<p>© <script>document.write( new Date().getFullYear() );</script> AI ML Operations, LLC. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Materialize JS -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||
<!-- <script>
|
||||
// Initialize Materialize components
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var elems = document.querySelectorAll('.sidenav');
|
||||
var instances = M.Sidenav.init(elems);
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
$(".dropdown-trigger").dropdown();
|
||||
</script> -->
|
||||
<script>
|
||||
$(".dropdown-trigger").dropdown();
|
||||
</script>
|
||||
<script>
|
||||
// Initialize Materialize components
|
||||
M.AutoInit();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
110
company_site/public/templates/emails/contact_email.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>New Feedback Submission</title>
|
||||
<style>
|
||||
/* Basic reset for email clients */
|
||||
body, table, td, a {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
table, td {
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
img {
|
||||
border: 0;
|
||||
height: auto;
|
||||
line-height: 100%;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
.header {
|
||||
background-color: #007BFF;
|
||||
color: #ffffff;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
color: #333333;
|
||||
}
|
||||
.footer {
|
||||
background-color: #f4f4f4;
|
||||
color: #777777;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.feedback-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.feedback-text {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" align="center">
|
||||
<tr>
|
||||
<td>
|
||||
<!-- Email Container -->
|
||||
<div class="email-container">
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<h1>New Contact Request</h1>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="content">
|
||||
<p>Hello,</p>
|
||||
<p>A new feedback item has been submitted. Here are the details:</p>
|
||||
|
||||
<!-- Feedback Title -->
|
||||
<div class="feedback-title">
|
||||
Subject: <strong>{{ subject }}</strong>
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="feedback-title">
|
||||
Email: <strong>{{ email }}</strong>
|
||||
</div>
|
||||
|
||||
<!-- Feedback Text -->
|
||||
<div class="feedback-text">
|
||||
<strong>Message:</strong><br>
|
||||
{{ message }}
|
||||
</div>
|
||||
|
||||
<p>Thank you for your attention.</p>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<p>This is an automated message. Please do not reply to this email.</p>
|
||||
<p>© 2025 AI ML Operations, LLC. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
3
company_site/public/templates/emails/contact_email.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
New Contact Request for AI ML Operations, LLC
|
||||
|
||||
"New Contact. {{ subject }} from {{ email }}. {{ message }}"
|
||||
61
company_site/public/templates/emails/marketing_email.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Email Template</title>
|
||||
<!-- Materialize CSS -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f4f4f4;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.header {
|
||||
background-color: #37474f;
|
||||
color: #ffffff;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
color: #333333;
|
||||
}
|
||||
.footer {
|
||||
background-color: #333;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="email-container">
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<h4>{{ title | safe }}</h4>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="content">
|
||||
{{ content | safe }}
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<p>© 2025 AI ML Operations, LLC. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
3
company_site/public/templates/emails/marketing_email.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
{{ subject }}
|
||||
|
||||
{{ content }}
|
||||
98
company_site/public/templates/public/ai_education.html
Normal file
@@ -0,0 +1,98 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>AI Education</h1>
|
||||
<p class="flow-text">Empowering Businesses with AI Knowledge</p>
|
||||
</div>
|
||||
|
||||
<!-- About AI Education Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">About AI Education</h2>
|
||||
<p class="flow-text">
|
||||
At AI ML Operations, we believe that understanding AI is the first step toward leveraging its power. Our AI Education service is designed to equip businesses with the knowledge and skills needed to integrate AI into their workflows effectively. We offer tailored courses, hands-on workshops, and ongoing support to ensure your team is confident and capable in using AI technologies.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">What We Offer</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">school</i>
|
||||
<h5>Custom Courses</h5>
|
||||
<p>Tailored AI courses designed to meet your business needs and goals.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">work</i>
|
||||
<h5>Hands-On Workshops</h5>
|
||||
<p>Interactive sessions to apply AI concepts in real-world scenarios.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">support</i>
|
||||
<h5>Ongoing Support</h5>
|
||||
<p>Continuous learning and support to keep your team up-to-date.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Course Highlights Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Course Highlights</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="AI Fundamentals">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">AI Fundamentals</span>
|
||||
<p>Learn the basics of AI, including machine learning, neural networks, and data preprocessing.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="AI for Business">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">AI for Business</span>
|
||||
<p>Discover how AI can optimize operations, improve decision-making, and drive innovation.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Advanced AI Techniques">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Advanced AI Techniques</span>
|
||||
<p>Dive deep into advanced topics like deep learning, natural language processing, and computer vision.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="section blue-grey darken-3 white-text">
|
||||
<div class="row container center">
|
||||
<h2 class="header">Ready to Transform Your Business?</h2>
|
||||
<p class="flow-text">Contact us today to schedule your AI Education sessions.</p>
|
||||
<a href="{% url 'contact' %}" class="btn-large waves-effect waves-light white blue-grey-text text-darken-3">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
109
company_site/public/templates/public/ai_sensor.html
Normal file
@@ -0,0 +1,109 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>AI Sensor Algorithms</h1>
|
||||
<p class="flow-text">Enhancing Sensor Performance with Advanced AI</p>
|
||||
</div>
|
||||
|
||||
<!-- About AI Sensor Algorithms Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">About AI Sensor Algorithms</h2>
|
||||
<p class="flow-text">
|
||||
At AI ML Operations, we specialize in developing cutting-edge AI algorithms to enhance the performance of on-board sensors. By leveraging techniques such as Natural Language Processing (NLP), Pattern Recognition, Machine Vision, and more, we enable sensors to deliver smarter, faster, and more accurate results. Our solutions are designed to integrate seamlessly into your systems, providing real-time insights and improving decision-making capabilities.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">What We Offer</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">visibility</i>
|
||||
<h5>Machine Vision</h5>
|
||||
<p>Enhance visual data processing with advanced machine vision algorithms.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">pattern</i>
|
||||
<h5>Pattern Recognition</h5>
|
||||
<p>Identify and analyze patterns in sensor data for improved accuracy.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">translate</i>
|
||||
<h5>Natural Language Processing</h5>
|
||||
<p>Enable sensors to interpret and respond to human language inputs.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Applications Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Applications</h2>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Industrial Automation">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Industrial Automation</span>
|
||||
<p>Optimize manufacturing processes with AI-enhanced sensors.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Autonomous Vehicles">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Autonomous Vehicles</span>
|
||||
<p>Improve navigation and safety with advanced sensor algorithms.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Healthcare Monitoring">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Healthcare Monitoring</span>
|
||||
<p>Enable real-time health tracking with AI-powered sensors.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Smart Home Devices">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Smart Home Devices</span>
|
||||
<p>Enhance user experiences with intelligent sensor integrations.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="section blue-grey darken-3 white-text">
|
||||
<div class="row container center">
|
||||
<h2 class="header">Ready to Enhance Your Sensors?</h2>
|
||||
<p class="flow-text">Contact us today to discuss your AI sensor needs.</p>
|
||||
<a href="{% url 'contact' %}" class="btn-large waves-effect waves-light white blue-grey-text text-darken-3">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
98
company_site/public/templates/public/bot.html
Normal file
@@ -0,0 +1,98 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>Agentic Bots</h1>
|
||||
<p class="flow-text">Intelligent Bots for Automation and Engagement</p>
|
||||
</div>
|
||||
|
||||
<!-- About Agentic Bots Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">About Agentic Bots</h2>
|
||||
<p class="flow-text">
|
||||
At AI ML Operations, we create intelligent, agentic bots designed to automate tasks, engage users, and streamline workflows. Our bots currently integrate seamlessly with Telegram, but we can customize them to suit your specific platform or needs. Whether you need a bot for customer support, data collection, or process automation, we deliver solutions that are reliable, scalable, and easy to use.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">What We Offer</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">smart_toy</i>
|
||||
<h5>Custom Bot Development</h5>
|
||||
<p>Tailored bots designed to meet your unique business requirements.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">integration_instructions</i>
|
||||
<h5>Platform Integration</h5>
|
||||
<p>Bots that integrate with Telegram or other platforms of your choice.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">settings</i>
|
||||
<h5>Hosting & Maintenance</h5>
|
||||
<p>We host and maintain your bots, ensuring they run smoothly 24/7.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Applications Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Applications</h2>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Customer Support">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Customer Support</span>
|
||||
<p>Automate responses and provide instant support to your customers.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Data Collection">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Data Collection</span>
|
||||
<p>Gather and organize data efficiently using intelligent bots.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Process Automation">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Process Automation</span>
|
||||
<p>Streamline workflows and reduce manual effort with automated bots.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="section blue-grey darken-3 white-text">
|
||||
<div class="row container center">
|
||||
<h2 class="header">Ready to Automate?</h2>
|
||||
<p class="flow-text">Contact us today to create your custom agentic bot.</p>
|
||||
<a href="{% url 'contact' %}" class="btn-large waves-effect waves-light white blue-grey-text text-darken-3">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
96
company_site/public/templates/public/chat.html
Normal file
@@ -0,0 +1,96 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section" >
|
||||
<h1>Chat</h1>
|
||||
<p>Your Private, Secure, and Powerful LLM Solution</p>
|
||||
</div>
|
||||
|
||||
<!-- Product Description Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">What is Chat?</h2>
|
||||
<p class="flow-text">
|
||||
Chat is a closed-source Large Language Model (LLM) designed specifically for small and medium businesses. Hosted locally, Chat ensures that all your data remains private and secure. With Chat, your data is never sold or accessed by third parties—ever. You retain full control over your accounts and data. Chat also includes advanced file analysis capabilities, making it a versatile tool for your business needs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">Key Features</h2>
|
||||
<div class="col s12 m4">
|
||||
|
||||
<div class="center">
|
||||
<i class="material-icons feature-icon">lock</i>
|
||||
<h5>Local Hosting</h5>
|
||||
<p>All data is stored and processed locally, ensuring maximum privacy and security.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="center">
|
||||
<i class="material-icons feature-icon">security</i>
|
||||
<h5>No Third-Party Access</h5>
|
||||
<p>Your data is never sold or accessed by third parties for any reason.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="center">
|
||||
<i class="material-icons feature-icon">folder</i>
|
||||
<h5>File Analysis</h5>
|
||||
<p>Analyze files directly within the platform for seamless integration into your workflows.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pricing Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Pricing</h2>
|
||||
|
||||
<div class="col s12 m6">
|
||||
<div class="screenshot-img">
|
||||
<img src="{% static 'public/img/chat_screenshot.png' %}" style="width: 100%;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6">
|
||||
<div class="pricing-card blue-grey lighten-5">
|
||||
<h4>$10</h4>
|
||||
<p>per user per month</p>
|
||||
<p>Start with a free trial to experience the power of Chat.</p>
|
||||
<a class="btn waves-effect waves-light" href="{% url 'contact' %}">Inquire Now</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Product Images Section -->
|
||||
<!-- <div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">Product Images</h2>
|
||||
<div class="col s12 m4">
|
||||
<img src="https://via.placeholder.com/400x300" alt="Chat Interface" class="responsive-img materialboxed">
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<img src="https://via.placeholder.com/400x300" alt="File Analysis" class="responsive-img materialboxed">
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<img src="https://via.placeholder.com/400x300" alt="Dashboard" class="responsive-img materialboxed">
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
{% endblock %}
|
||||
109
company_site/public/templates/public/computers.html
Normal file
@@ -0,0 +1,109 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>Computer Solutions</h1>
|
||||
<p class="flow-text">From Gaming PCs to AI Servers – We Build, Deploy, and Maintain</p>
|
||||
</div>
|
||||
|
||||
<!-- About Computer Solutions Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">About Our Computer Solutions</h2>
|
||||
<p class="flow-text">
|
||||
At AI ML Operations, we specialize in procuring, building, deploying, and maintaining computers tailored to your specific needs. Whether you're a gamer, a creative professional, or a business requiring high-performance workstations or AI servers, we deliver reliable, scalable, and efficient solutions. Our end-to-end service ensures your systems are optimized for performance and longevity.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">What We Offer</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">build</i>
|
||||
<h5>Custom Builds</h5>
|
||||
<p>We design and build computers tailored to your specific requirements, from gaming PCs to AI servers.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">cloud_upload</i>
|
||||
<h5>Deployment</h5>
|
||||
<p>Seamless deployment of systems, ensuring they are ready for immediate use.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">settings</i>
|
||||
<h5>Maintenance</h5>
|
||||
<p>Ongoing support and maintenance to keep your systems running smoothly.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Solutions Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Our Solutions</h2>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Gaming PCs">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Gaming PCs</span>
|
||||
<p>High-performance gaming rigs built for the latest games and VR experiences.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Workstations">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Workstations</span>
|
||||
<p>Powerful workstations for creative professionals, engineers, and developers.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Storage Servers">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Storage Servers</span>
|
||||
<p>Scalable storage solutions for data-intensive applications and backups.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="AI Servers">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">AI Servers</span>
|
||||
<p>High-performance servers optimized for AI and machine learning workloads.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="section blue-grey darken-3 white-text">
|
||||
<div class="row container center">
|
||||
<h2 class="header">Ready to Upgrade Your Systems?</h2>
|
||||
<p class="flow-text">Contact us today to discuss your computer needs.</p>
|
||||
<a href="{% url 'contact' %}" class="btn-large waves-effect waves-light white blue-grey-text text-darken-3">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
126
company_site/public/templates/public/contact.html
Normal file
@@ -0,0 +1,126 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg2.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>Get in Touch</h1>
|
||||
</div>
|
||||
|
||||
<!-- Contact Content -->
|
||||
<div class="contact-section grey lighten-3">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{% if success %}
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<span class="alert-text"> We'll be in contact shortly!</span>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if errors %}
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
<span class="alert-text">{{ errors }}</span>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col s12 m8">
|
||||
<div class="contact-card white">
|
||||
<h4>Send Us a Message</h4>
|
||||
<form action="{% url 'contact' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="form-group col s12 m6" style="padding-right:1rem">
|
||||
<input type="text" class="form-control" class="validate" name="name" placeholder="Your Name">
|
||||
</div>
|
||||
<div class="form-group col s12 m6" style="padding-left:1rem">
|
||||
<input type="email" class="form-control" class="validate" name="email" placeholder="Your Email">
|
||||
</div>
|
||||
<!-- <div class="input-field col s12">
|
||||
<input id="subject" type="text" class="validate" required>
|
||||
<label for="subject">Subject</label>
|
||||
</div> -->
|
||||
<div class="form-group col s12" style="padding-left:1rem">
|
||||
<input type="text" class="form-control" class="validate" name="subject" placeholder="Subject">
|
||||
</div>
|
||||
<div class="form-group col-12" style="padding:1rem">
|
||||
<textarea name="message" type="text" class="form-control" class="validate" placeholder="Your message"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-12">
|
||||
{% if capchaForm %}
|
||||
{{ capchaForm }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col s12">
|
||||
<!-- <input type="submit" class="btn btn-primary" value="Send"> -->
|
||||
<button class="btn waves-effect waves-light blue-grey darken-3" type="submit" value="Send">
|
||||
Send Message
|
||||
<i class="material-icons right">send</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m4">
|
||||
<div class="contact-info">
|
||||
<h5>Contact Information</h5>
|
||||
<ul class="collection">
|
||||
<!-- <li class="collection-item">
|
||||
<i class="material-icons">location_on</i>
|
||||
<p>1968 Greensboro Dr<br>Wheaton, IL 60189</p>
|
||||
</li> -->
|
||||
<li class="collection-item">
|
||||
<i class="material-icons">phone</i>
|
||||
<p>+1 (330) 402-2675</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<i class="material-icons">email</i>
|
||||
<p>ryan@aimloperations.com</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- <h5>Follow Us</h5>
|
||||
<div class="social-links">
|
||||
<a href="#" class="btn-floating blue-grey darken-3">
|
||||
<i class="material-icons">group</i>
|
||||
</a>
|
||||
<a href="#" class="btn-floating blue-grey darken-3">
|
||||
<i class="material-icons">message</i>
|
||||
</a>
|
||||
<a href="#" class="btn-floating blue-grey darken-3">
|
||||
<i class="material-icons">business</i>
|
||||
</a>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Map Section -->
|
||||
<!-- <div class="row">
|
||||
<div class="col s12">
|
||||
<div class="contact-card white">
|
||||
<h5>Our Location</h5>
|
||||
<div class="map-container">
|
||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2972.770560296143!2d-88.12337822267253!3d41.83323846821986!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x880e542fbc244bbd%3A0x7aa4cddecbc2cf1f!2s1968%20Greensboro%20Dr%2C%20Wheaton%2C%20IL%2060189!5e0!3m2!1sen!2sus!4v1739220517291!5m2!1sen!2sus"
|
||||
width="100%"
|
||||
height="300"
|
||||
style="border:0;"
|
||||
allowfullscreen=""
|
||||
loading="lazy">
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
100
company_site/public/templates/public/file_hosting.html
Normal file
@@ -0,0 +1,100 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>File Hosting</h1>
|
||||
<p class="flow-text">Secure, Scalable, and Reliable File Storage with Weekly Backups</p>
|
||||
</div>
|
||||
|
||||
<!-- About File Hosting Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">About Our File Hosting Service</h2>
|
||||
<p class="flow-text">
|
||||
At AI ML Operations, we provide secure and scalable file hosting solutions tailored to your business needs. Our platform ensures your data is always accessible, protected, and backed up with weekly backups for added peace of mind. Whether you're storing critical business documents, media files, or large datasets, our file hosting service is designed to meet your requirements with reliability and efficiency.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">What We Offer</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">cloud</i>
|
||||
<h5>Secure Storage</h5>
|
||||
<p>Your files are stored securely with advanced encryption protocols.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">backup</i>
|
||||
<h5>Weekly Backups</h5>
|
||||
<p>Automatic weekly backups to ensure your data is always safe.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">storage</i>
|
||||
<h5>Scalable Solutions</h5>
|
||||
<p>Easily scale your storage as your business grows.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Benefits Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Why Choose Us?</h2>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Data Security">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Data Security</span>
|
||||
<p>Advanced encryption and access controls to protect your files.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Reliability">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Reliability</span>
|
||||
<p>99.9% uptime guarantee for uninterrupted access to your files.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Easy Management">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Easy Management</span>
|
||||
<p>User-friendly interface for seamless file management.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="section blue-grey darken-3 white-text">
|
||||
<div class="row container center">
|
||||
<h2 class="header">Ready to Secure Your Files?</h2>
|
||||
<p class="flow-text">Contact us today to get started with our file hosting service.</p>
|
||||
<a href="{% url 'contact' %}" class="btn-large waves-effect waves-light white blue-grey-text text-darken-3">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
98
company_site/public/templates/public/ml_model.html
Normal file
@@ -0,0 +1,98 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>ML Model Creation</h1>
|
||||
<p class="flow-text">Tailored Machine Learning Models for Any Problem Set</p>
|
||||
</div>
|
||||
|
||||
<!-- About ML Model Creation Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">About ML Model Creation</h2>
|
||||
<p class="flow-text">
|
||||
At AI ML Operations, we specialize in creating custom machine learning models to solve complex problems across industries. With extensive expertise in supervised, unsupervised, and reinforcement learning, we design models that deliver accurate, scalable, and actionable insights. Whether you need predictive analytics, pattern recognition, or decision-making systems, we provide end-to-end solutions tailored to your needs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">What We Offer</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">supervised_user_circle</i>
|
||||
<h5>Supervised Learning</h5>
|
||||
<p>Create models for classification, regression, and prediction tasks.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">explore</i>
|
||||
<h5>Unsupervised Learning</h5>
|
||||
<p>Discover patterns and insights from unlabeled data.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">trending_up</i>
|
||||
<h5>Reinforcement Learning</h5>
|
||||
<p>Develop systems that learn and adapt through interaction.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Applications Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Applications</h2>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Predictive Analytics">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Predictive Analytics</span>
|
||||
<p>Forecast trends and outcomes with high accuracy.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Fraud Detection">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Fraud Detection</span>
|
||||
<p>Identify and prevent fraudulent activities in real-time.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Recommendation Systems">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Recommendation Systems</span>
|
||||
<p>Personalize user experiences with intelligent recommendations.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="section blue-grey darken-3 white-text">
|
||||
<div class="row container center">
|
||||
<h2 class="header">Ready to Solve Your Problem?</h2>
|
||||
<p class="flow-text">Contact us today to create your custom ML model.</p>
|
||||
<a href="{% url 'contact' %}" class="btn-large waves-effect waves-light white blue-grey-text text-darken-3">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
157
company_site/public/templates/public/new_index.html
Normal file
@@ -0,0 +1,157 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>AI ML Operations, LLC</h1>
|
||||
<br />
|
||||
<p>Taking AI and ML from concept to Production</p>
|
||||
</div>
|
||||
|
||||
<!-- About Us Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">About Us</h2>
|
||||
<p class="flow-text">
|
||||
At AI/ML Operations, we are dedicated to delivering production-ready AI and ML solutions that seamlessly integrate into your workflows. With over a decade of experience, we specialize in crafting cutting-edge machine learning models and AI algorithms to tackle the most complex and demanding challenges across various industries.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Services Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Our Services</h2>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'ai_sensor' %}">AI Sensor Algorithms</a></span>
|
||||
<p>Develop intelligent algorithms that enhance sensor data processing, enabling real-time insights and decision-making for IoT and industrial applications.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'ai_education' %}">AI Education</a></span>
|
||||
<p>Stay ahead of the AI technology curve with our AI Education classes. Classes are tailored to the audience familiarity with AI. Held in-person or virtual.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'bot' %}">Bot Creation</a></span>
|
||||
<p>Build agentic intelligent bots for workflow automation, customer support, and data collection for enhancing productivity and user experience.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'chat' %}">Chat</a></span>
|
||||
<p>Chat is a closed-source Large Language Model (LLM) designed specifically for small and medium businesses.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'computers' %}">Computer Builds</a></span>
|
||||
<p>Wether you're looking for a server for storage or compute or a workstation computer, we will build your next system for you.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'file_hosting' %}">File Hosting</a></span>
|
||||
<p>Secure and scalable file hosting solutions to store, manage, and share your data with ease and confidence.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'ml_model' %}">ML Model Creation</a></span>
|
||||
<p>Design and deploy custom machine learning models tailored to your business needs, ensuring accuracy, scalability, and performance.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card blue-grey lighten-5">
|
||||
<div class="card-content">
|
||||
<span class="card-title"><a href="{% url 'web_design' %}">Web Design and Hosting</a></span>
|
||||
<p>Create visually stunning and highly functional websites, coupled with reliable hosting solutions to ensure your online presence is always at its best.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Us Section -->
|
||||
<!-- <div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">Contact Us</h2>
|
||||
<form action="{% url 'contact' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
{% if success %}
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
<span class="alert-text"> We'll be in contact shortly!</span>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if errors %}
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
<span class="alert-text">{{ errors }}</span>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col l6 m6 s12">
|
||||
<div class="form-group" style="padding-left:1rem">
|
||||
<input type="email" class="form-control" name="email" placeholder="Your Email">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col l6 m6 s12">
|
||||
<div class="form-group" style="padding-right:1rem">
|
||||
<input type="text" class="form-control" name="name" placeholder="Your Name">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col l10 m10 s12">
|
||||
<div class="form-group" style="padding:1rem">
|
||||
<textarea name="message" type="text" class="form-control" rows="5" placeholder="Your message"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col l2 m2 s12">
|
||||
<input type="submit" class="btn btn-primary" value="Send">
|
||||
</div>
|
||||
<div class="col l12 m12 s12">
|
||||
<div class="form-group">
|
||||
{% if capchaForm %}
|
||||
{{ capchaForm }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div> -->
|
||||
{% endblock %}
|
||||
61
company_site/public/templates/public/preview_email.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Email Template</title>
|
||||
<!-- Materialize CSS -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f4f4f4;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.email-container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.header {
|
||||
background-color: #37474f;
|
||||
color: #ffffff;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
color: #333333;
|
||||
}
|
||||
.footer {
|
||||
background-color: #333;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="email-container">
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<h4>{{ title | safe }}</h4>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="content">
|
||||
{{ content | safe }}
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<p>© 2025 AI ML Operations, LLC. All rights reserved.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
207
company_site/public/templates/public/web_design.html
Normal file
@@ -0,0 +1,207 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block path %} url({% static 'public/img/bg4.jpeg' %}) {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Hero Section -->
|
||||
<div class="hero-section">
|
||||
<h1>Web Design & Hosting</h1>
|
||||
<p class="flow-text">Crafting Beautiful, Functional Websites with Reliable Hosting</p>
|
||||
</div>
|
||||
|
||||
<!-- About Web Design & Hosting Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">About Our Web Design & Hosting Service</h2>
|
||||
<p class="flow-text">
|
||||
At AI ML Operations, we specialize in creating visually stunning, highly functional websites tailored to your business needs. From design to deployment, we handle every aspect of your online presence. Our reliable hosting solutions ensure your website is always fast, secure, and accessible. Whether you need a simple portfolio site or a complex e-commerce platform, we’ve got you covered.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features Section -->
|
||||
<div class="section grey lighten-3">
|
||||
<div class="row container">
|
||||
<h2 class="header">What We Offer</h2>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">design_services</i>
|
||||
<h5>Custom Web Design</h5>
|
||||
<p>Tailored designs that reflect your brand and engage your audience.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">dns</i>
|
||||
<h5>Reliable Hosting</h5>
|
||||
<p>Fast, secure, and scalable hosting solutions for your website.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m4">
|
||||
<div class="icon-block">
|
||||
<i class="material-icons">settings</i>
|
||||
<h5>Ongoing Support</h5>
|
||||
<p>Continuous maintenance and support to keep your site running smoothly.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Services Section -->
|
||||
<div class="section white">
|
||||
<div class="row container">
|
||||
<h2 class="header">Our Services</h2>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Custom Web Design">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Custom Web Design</span>
|
||||
<p>Unique, responsive designs tailored to your brand and audience.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="E-Commerce Solutions">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">E-Commerce Solutions</span>
|
||||
<p>Build and optimize online stores for seamless shopping experiences.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Website Hosting">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Website Hosting</span>
|
||||
<p>Secure, high-performance hosting with 99.9% uptime guarantee.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="SEO Optimization">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">SEO Optimization</span>
|
||||
<p>Improve your website's visibility and ranking on search engines.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l4">
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="https://via.placeholder.com/400x200" alt="Maintenance & Support">
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">Maintenance & Support</span>
|
||||
<p>Regular updates, backups, and troubleshooting to keep your site running smoothly.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="section grey lighten-4">
|
||||
<div class="container">
|
||||
<h3 class="center-align">Web Hosting Plans</h3>
|
||||
|
||||
<!-- Pricing toggle -->
|
||||
<div class="row center-align">
|
||||
<div class="col s12">
|
||||
<div class="switch">
|
||||
<label>
|
||||
Monthly
|
||||
<input type="checkbox" id="pricingToggle">
|
||||
<span class="lever"></span>
|
||||
Yearly
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pricing cards -->
|
||||
<div class="row">
|
||||
<!-- Monthly Card -->
|
||||
<div class="col s12 m6 l6">
|
||||
<div class="card z-depth-2">
|
||||
<div class="card-content center-align">
|
||||
<span class="card-title">Standard Plan</span>
|
||||
<h4>$<span class="price">10</span></h4>
|
||||
<p class="grey-text"><span class="billing-period">per month</span></p>
|
||||
<ul class="collection">
|
||||
<li class="collection-item"><i class="material-icons left">check_circle</i>Web Hosting</li>
|
||||
<li class="collection-item"><i class="material-icons left">check_circle</i>Weekly Backups</li>
|
||||
<li class="collection-item"><i class="material-icons left">check_circle</i>SSL Certificate</li>
|
||||
<li class="collection-item"><i class="material-icons left">check_circle</i>CAPTCHA Protection</li>
|
||||
<li class="collection-item"><i class="material-icons left">check_circle</i>Email Notifications</li>
|
||||
<li class="collection-item"><i class="material-icons left">check_circle</i>Backend Admin Access</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-action center-align">
|
||||
<a href="#" class="waves-effect waves-light btn blue">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Yearly Card -->
|
||||
<div class="col s12 m6 l6">
|
||||
<div class="card z-depth-2 teal lighten-1 white-text">
|
||||
<div class="card-content center-align">
|
||||
<span class="card-title">Premium Plan</span>
|
||||
<h4>$<span class="price">15</span></h4>
|
||||
<p><span class="billing-period">per month</span></p>
|
||||
<ul class="collection">
|
||||
<li class="collection-item teal lighten-1 white-text"><i class="material-icons left">check_circle</i>All Standard Features</li>
|
||||
<li class="collection-item teal lighten-1 white-text"><i class="material-icons left">analytics</i>Monthly Analytics Reports</li>
|
||||
<li class="collection-item teal lighten-1 white-text"><i class="material-icons left">speed</i>Site Optimization Reports</li>
|
||||
<li class="collection-item teal lighten-1 white-text"><i class="material-icons left">email</i>HTML Marketing Emails</li>
|
||||
<li class="collection-item teal lighten-1 white-text"><i class="material-icons left">star</i>2 Months Free (Yearly)</li>
|
||||
<li class="collection-item teal lighten-1 white-text"><i class="material-icons left">star</i>Priority Support</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-action center-align">
|
||||
<a href="#" class="waves-effect waves-light btn white blue-text">Save 20%</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
// Toggle functionality
|
||||
document.getElementById('pricingToggle').addEventListener('change', function() {
|
||||
const prices = document.querySelectorAll('.price');
|
||||
const periods = document.querySelectorAll('.billing-period');
|
||||
|
||||
if(this.checked) {
|
||||
prices[0].textContent = '100';
|
||||
periods[0].textContent = 'per year';
|
||||
prices[1].textContent = '150';
|
||||
periods[1].textContent = 'per year';
|
||||
} else {
|
||||
prices[0].textContent = '10';
|
||||
periods[0].textContent = 'per month';
|
||||
prices[1].textContent = '15';
|
||||
periods[1].textContent = 'per month';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="section blue-grey darken-3 white-text">
|
||||
<div class="row container center">
|
||||
<h2 class="header">Ready to Build Your Online Presence?</h2>
|
||||
<p class="flow-text">Contact us today to get started on your website project.</p>
|
||||
<a href="{% url 'contact' %}" class="btn-large waves-effect waves-light white blue-grey-text text-darken-3">Get Started</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
3
company_site/public/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
17
company_site/public/urls.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.index, name="public_index"),
|
||||
path("chat", views.chat, name="chat"),
|
||||
path("ai_education", views.ai_education, name="ai_education"),
|
||||
path("computer", views.computers, name="computers"),
|
||||
path("web_design", views.web_design, name="web_design"),
|
||||
path("ai_sensor", views.ai_sensor, name="ai_sensor"),
|
||||
path("file_hosting", views.file_hosting, name="file_hosting"),
|
||||
path("bot_creation", views.bot, name="bot"),
|
||||
path("ml_model", views.ml_model, name="ml_model"),
|
||||
path("contact", views.contact, name="contact"),
|
||||
path("preview_email/<int:pk>/", views.preview_email, name="preview_email")
|
||||
]
|
||||
104
company_site/public/views.py
Normal file
@@ -0,0 +1,104 @@
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
||||
from django.http import HttpResponse
|
||||
from .models import Contact, EmailMessage
|
||||
from django.template.loader import get_template
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.conf import settings
|
||||
from django.core.mail import send_mail
|
||||
from .forms import FormWithCaptcha
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
def send_contact_email(email, subject, message):
|
||||
subject = "New Contact Request for AI ML Operations, LLC"
|
||||
from_email = email
|
||||
to="ryan@aimloperations.com"
|
||||
d = {"subject": subject, "message": message, "email": email}
|
||||
html_content = get_template(r'emails/contact_email.html').render(d)
|
||||
text_content = get_template(r'emails/contact_email.txt').render(d)
|
||||
|
||||
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
|
||||
msg.attach_alternative(html_content, "text/html")
|
||||
msg.send(fail_silently=True)
|
||||
|
||||
# Create your views here.
|
||||
def index(request):
|
||||
return render(request, "public/new_index.html", {})
|
||||
|
||||
def chat(request):
|
||||
return render(request, "public/chat.html", {})
|
||||
|
||||
def ai_education(request):
|
||||
return render(request, "public/ai_education.html", {})
|
||||
|
||||
def computers(request):
|
||||
return render(request, "public/computers.html", {})
|
||||
|
||||
def web_design(request):
|
||||
return render(request, "public/web_design.html", {})
|
||||
|
||||
def ai_sensor(request):
|
||||
return render(request, "public/ai_sensor.html", {})
|
||||
|
||||
def file_hosting(request):
|
||||
return render(request, "public/file_hosting.html", {})
|
||||
|
||||
def bot(request):
|
||||
return render(request, "public/bot.html", {})
|
||||
|
||||
def ml_model(request):
|
||||
return render(request, "public/ml_model.html", {})
|
||||
|
||||
@login_required
|
||||
def preview_email(request, pk):
|
||||
email_instance = get_object_or_404(EmailMessage, pk=pk)
|
||||
context = {
|
||||
"title":email_instance.subject,
|
||||
"content":email_instance.body
|
||||
}
|
||||
return render(
|
||||
request, 'public/preview_email.html', context
|
||||
)
|
||||
|
||||
def contact(request):
|
||||
errors = ''
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
name = request.POST.get('name')
|
||||
email = request.POST.get('email')
|
||||
message = request.POST.get('message', "")
|
||||
subject = request.POST.get('subject', "")
|
||||
capchaForm = FormWithCaptcha(request.POST)
|
||||
|
||||
if len(name) > 0 and len(email) > 0 and len(subject) > 0:
|
||||
if settings.DEBUG or capchaForm.is_valid():
|
||||
|
||||
|
||||
# then we are good
|
||||
c = Contact(name=name, email=email, blurb=message, subject=subject)
|
||||
c.save()
|
||||
# send the email.
|
||||
try:
|
||||
send_contact_email(email, subject, message)
|
||||
except Exception as e:
|
||||
print(f'Error sending the email {e}')
|
||||
print('Contact Request:')
|
||||
print(f'From: {name}')
|
||||
print(f'Message: {message}')
|
||||
return render(request, "public/contact.html", {'success':True, 'capchaForm': FormWithCaptcha()})
|
||||
else:
|
||||
return render(request, "public/contact.html", {'errors': "There was an error submitting. Try again", 'capchaForm': capchaForm})
|
||||
else:
|
||||
if len(name) == 0 and len(email) == 0:
|
||||
errors = 'Both name and email are required'
|
||||
elif len(email) == 0:
|
||||
errors = 'Email is required'
|
||||
elif len(name) == 0:
|
||||
errors = 'Name is required'
|
||||
# we need to show an error
|
||||
return render(request, "public/contact.html", {'errors': errors, 'capchaForm': capchaForm})
|
||||
|
||||
capcha = None if settings.DEBUG else FormWithCaptcha()
|
||||
return render(request, "public/contact.html", {'capchaForm': capcha})
|
||||
|
||||
1
company_site/scp_command.txt
Normal file
@@ -0,0 +1 @@
|
||||
scp -r ./* westfarn@10.0.0.103:/home/westfarn/company_site_temp/
|
||||
7
requirements.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
asgiref==3.7.2
|
||||
Django==5.0
|
||||
sqlparse==0.4.4
|
||||
typing_extensions==4.8.0
|
||||
django-enum
|
||||
django-recaptcha
|
||||
django-phonenumber-field[phonenumbers]
|
||||