Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions backend/DOSPORTAL/migrations/0016_alter_detector_sn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 6.0.3 on 2026-03-31 15:35

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('DOSPORTAL', '0015_detectorlogbook_metadata'),
]

operations = [
migrations.AlterField(
model_name='detector',
name='sn',
field=models.CharField(max_length=80, unique=True),
),
]
63 changes: 49 additions & 14 deletions backend/DOSPORTAL/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,58 @@
from .soft_delete import SoftDeleteModel, SoftDeleteManager, SoftDeleteQuerySet
from .utils import UUIDMixin, Profile
from .detectors import DetectorManufacturer, DetectorType, DetectorCalib, Detector, DetectorLogbook
from .utils import UUIDMixin, Profile, ProcessingStatusMixin
from .detectors import (
DetectorManufacturer,
DetectorType,
DetectorCalib,
Detector,
DetectorLogbook,
)
from .organizations import Organization, OrganizationUser, OrganizationInvite
from .flights import CARImodel, Airports, Flight, Trajectory, TrajectoryPoint
from .measurements import (
_validate_data_file, _validate_metadata_file, _validate_log_file,
MeasurementDataFlight, MeasurementArtifact,
MeasurementCampaign, Measurement, MeasurementSegment, SpectrumData
_validate_data_file,
_validate_metadata_file,
_validate_log_file,
MeasurementDataFlight,
MeasurementArtifact,
MeasurementCampaign,
Measurement,
MeasurementSegment,
SpectrumData,
)
from .files import File
from .spectrals import SpectralRecord, SpectralRecordArtifact

__all__ = [
"SoftDeleteModel", "SoftDeleteManager", "SoftDeleteQuerySet",
"UUIDMixin", "Profile",
"DetectorManufacturer", "DetectorType", "DetectorCalib", "Detector", "DetectorLogbook",
"Organization", "OrganizationUser", "OrganizationInvite",
"_validate_data_file", "_validate_metadata_file", "_validate_log_file",
"CARImodel", "Airports", "Flight", "MeasurementDataFlight", "MeasurementArtifact",
"MeasurementCampaign", "Measurement", "MeasurementSegment", "File", "Trajectory", "TrajectoryPoint", "SpectrumData",
"SpectralRecord", "SpectralRecordArtifact"
]
"SoftDeleteModel",
"SoftDeleteManager",
"SoftDeleteQuerySet",
"UUIDMixin",
"ProcessingStatusMixin",
"Profile",
"DetectorManufacturer",
"DetectorType",
"DetectorCalib",
"Detector",
"DetectorLogbook",
"Organization",
"OrganizationUser",
"OrganizationInvite",
"_validate_data_file",
"_validate_metadata_file",
"_validate_log_file",
"CARImodel",
"Airports",
"Flight",
"MeasurementDataFlight",
"MeasurementArtifact",
"MeasurementCampaign",
"Measurement",
"MeasurementSegment",
"File",
"Trajectory",
"TrajectoryPoint",
"SpectrumData",
"SpectralRecord",
"SpectralRecordArtifact",
]
2 changes: 1 addition & 1 deletion backend/DOSPORTAL/models/detectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ def __str__(self) -> str:


class Detector(UUIDMixin, SoftDeleteModel):

sn = models.CharField(
max_length=80,
unique=True,
)
name = models.CharField(
_("Detector name"),
Expand Down
191 changes: 2 additions & 189 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,7 @@
* Add only critical fixes here; prefer styling in components with Tailwind.
*/

:root {
--bg: #ffffff;
--card: #ffffff;
--text: #111827;
--muted: #6b7280;
--primary: #0d6efd; /* bootstrap primary */
--green: #198754; /* bootstrap success */
--red: #dc3545; /* bootstrap danger */
--border: #e5e7eb;
}


* {
box-sizing: border-box;
Expand All @@ -37,96 +28,6 @@ body {
overflow-x: hidden;
}

.bg { display: none; }

.auth-layout {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: 1fr 1.2fr;
gap: 2rem;
max-width: 1100px;
margin: 0 auto;
padding: 3rem 1.25rem;
}

.auth-layout.single {
max-width: 520px;
grid-template-columns: 1fr;
}

.content {
position: relative;
z-index: 1;
max-width: 1100px;
margin: 0 auto;
padding: 2.5rem 1.25rem 3rem;
display: flex;
flex-direction: column;
gap: 1.25rem;
}

.hero {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 1.5rem;
display: flex;
justify-content: space-between;
gap: 1rem;
flex-wrap: wrap;
}

.hero h1 {
margin: 0.15rem 0 0.35rem 0;
}

.hero-actions {
display: flex;
gap: 0.5rem;
align-items: center;
flex-wrap: wrap;
}

.eyebrow {
text-transform: uppercase;
letter-spacing: 0.08em;
font-size: 0.8rem;
color: var(--muted);
margin: 0;
}

@media (max-width: 880px) {
.auth-layout {
grid-template-columns: 1fr;
padding: 2rem 1rem;
}
}

.login-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 10px;
padding: 2rem;
box-shadow: 0 6px 18px rgba(0,0,0,0.08);
}

.brand {
margin: 0 0 0.25rem 0;
letter-spacing: 0.04em;
}

.subtitle {
margin-top: 0;
color: var(--muted);
font-size: 0.95rem;
}

.login-form {
margin-top: 1.5rem;
display: grid;
gap: 1rem;
}

.field label {
display: block;
Expand Down Expand Up @@ -165,11 +66,6 @@ button.primary:disabled {
cursor: not-allowed;
}

.help {
margin-top: 0.75rem;
color: var(--muted);
}

.error {
margin-top: 0.75rem;
color: var(--red);
Expand All @@ -193,87 +89,4 @@ button.primary:disabled {
justify-content: space-between;
gap: 1rem;
margin-bottom: 0.75rem;
}

.panel-header button {
padding: 0.5rem 0.8rem;
border-radius: 8px;
border: 1px solid var(--primary);
background: var(--primary);
color: #ffffff;
cursor: pointer;
}

.panel-body {
text-align: left;
}

.logbook-list {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 0.75rem;
}

.logbook-item {
border: 1px solid var(--border);
border-radius: 10px;
padding: 0.9rem 1rem;
background: #ffffff;
}

.logbook-item .meta {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 0.5rem;
color: var(--muted);
}

.badge {
display: inline-block;
padding: 0.15rem 0.5rem;
border: 1px solid #d1d5db;
border-radius: 9999px;
font-size: 0.75rem;
color: var(--text);
}

.text {
margin: 0.2rem 0 0.5rem 0;
}

.maplink {
font-size: 0.85rem;
color: var(--primary);
}

.muted {
color: var(--muted);
margin: 0;
}

.pill {
color: #ffffff;
text-decoration: none;
padding: 0.35rem 0.75rem;
border-radius: 999px;
border: 1px solid var(--primary);
background: var(--primary);
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 0.35rem;
font-size: 0.95rem;
}

.pill.ghost {
background: transparent;
color: var(--text);
border-color: #d1d5db;
}

.pill:hover {
filter: brightness(1.05);
}
}
13 changes: 8 additions & 5 deletions frontend/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import { AuthProvider } from '@/features/auth/context/AuthProvider'
import { router } from './router'
import { Toaster } from '@/components/ui/sonner'
import { ThemeProvider } from '@/components/theme-provider'
import { TooltipProvider } from '@/components/ui/tooltip'

const queryClient = new QueryClient()

function App() {
return (
<QueryClientProvider client={queryClient}>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<AuthProvider>
<RouterProvider router={router} />
<Toaster position="top-right" richColors />
</AuthProvider>
<ThemeProvider attribute="class" defaultTheme="light" enableSystem>
<TooltipProvider>
<AuthProvider>
<RouterProvider router={router} />
<Toaster position="top-right" richColors />
</AuthProvider>
</TooltipProvider>
</ThemeProvider>
</QueryClientProvider>
)
Expand Down
49 changes: 49 additions & 0 deletions frontend/src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { Slot } from "radix-ui"

import { cn } from "@/lib/utils"

const badgeVariants = cva(
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
secondary:
"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
destructive:
"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
outline:
"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
ghost:
"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
link: "text-primary underline-offset-4 hover:underline",
},
},
defaultVariants: {
variant: "default",
},
}
)

function Badge({
className,
variant = "default",
asChild = false,
...props
}: React.ComponentProps<"span"> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot.Root : "span"

return (
<Comp
data-slot="badge"
data-variant={variant}
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
)
}

export { Badge, badgeVariants }
Loading
Loading