styles: refactor codebase base style
This commit is contained in:
@@ -4,7 +4,6 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
import { Building2, Plus } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PERMISSIONS } from '@/constants/permissions';
|
||||
import { PermissionGuard } from '@/guards';
|
||||
@@ -120,8 +119,6 @@ export default function ClientsPage() {
|
||||
onLimitChange={setLimit}
|
||||
onSortingChange={setSorting}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<ClientSheet
|
||||
|
||||
@@ -33,7 +33,6 @@ import { Project } from '@/types';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { DashboardSkeleton } from '@/components/dashboard/dashboard-skeleton';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { toast } from 'sonner';
|
||||
import { Reveal, StaggerContainer, StaggerItem } from '@/components/ui/reveal';
|
||||
|
||||
@@ -636,8 +635,6 @@ export default function DashboardPage() {
|
||||
</Reveal>
|
||||
</>
|
||||
)}
|
||||
|
||||
<PoweredBy />
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
|
||||
@@ -13,13 +13,12 @@ const ModulesLayout = ({
|
||||
}>) => {
|
||||
return (
|
||||
<AuthGuard>
|
||||
<SidebarProvider className="bg-transparent overflow-hidden">
|
||||
<AppSidebar className="bg-transparent" />
|
||||
<main className="flex flex-1 flex-col w-full h-screen overflow-hidden bg-transparent">
|
||||
<SidebarProvider>
|
||||
<AppSidebar />
|
||||
<main className="flex flex-1 flex-col w-full h-screen overflow-hidden">
|
||||
<div className="flex-1 overflow-auto">
|
||||
{/* Centering container wrapper */}
|
||||
<div className="max-w-380 mx-auto w-full flex flex-col min-h-full">
|
||||
<div className="flex gap-3 items-center sticky top-0 bg-background/30 backdrop-blur-xl z-30 py-3 px-6 border-b border-border/10">
|
||||
<div className="flex gap-3 items-center sticky top-0 bg-background z-50 py-3 px-6 border-b border-border">
|
||||
<SidebarTrigger />
|
||||
<ModeToggle />
|
||||
<Separator orientation="vertical" className="mx-2 h-4" />
|
||||
|
||||
@@ -35,14 +35,14 @@ function StateBadges({ value }: { value: string | null }) {
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center justify-center rounded-full border border-border/40 bg-muted/50 px-1.5 py-0.5 text-[10px] font-bold text-muted-foreground transition-colors hover:bg-muted"
|
||||
className="flex items-center justify-center rounded-full border border-border/40 bg-muted/50 px-1.5 py-0.5 text-muted-foreground transition-colors hover:bg-muted"
|
||||
>
|
||||
+{remainingStates.length}
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-2" align="start">
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<p className="mb-0.5 px-1 text-[10px] font-bold uppercase tracking-wider text-muted-foreground">
|
||||
<p className="mb-0.5 px-1 text-muted-foreground">
|
||||
Other States
|
||||
</p>
|
||||
{remainingStates.map((state) => (
|
||||
@@ -64,7 +64,7 @@ export function usePackageColumns(projects: Project[]) {
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Package Name',
|
||||
cell: ({ row }) => <div className="font-semibold">{row.original.name}</div>,
|
||||
cell: ({ row }) => <div>{row.original.name}</div>,
|
||||
},
|
||||
{
|
||||
accessorKey: 'project_id',
|
||||
|
||||
@@ -70,13 +70,13 @@ export function PackageDialog({
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-2xl" onOpenAutoFocus={(event) => event.preventDefault()}>
|
||||
<DialogHeader className="gap-2">
|
||||
<DialogTitle className="flex items-center gap-3 text-xl">
|
||||
<DialogTitle className="flex items-center gap-3">
|
||||
<div className="rounded-lg bg-primary p-2 text-primary-foreground shadow-sm">
|
||||
<PackageIcon className="size-5" />
|
||||
</div>
|
||||
{packageId ? 'Edit Package Details' : 'Create New Package'}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-sm">
|
||||
<DialogDescription>
|
||||
{packageId
|
||||
? 'Update the technical specifications for your road infrastructure package.'
|
||||
: 'Select a project and provide the essential data to establish a new package.'}
|
||||
@@ -89,7 +89,7 @@ export function PackageDialog({
|
||||
<Select value={projectId} onValueChange={onProjectChange}>
|
||||
<SelectTrigger aria-invalid={!!projectErrorMessage}>
|
||||
{isProjectsLoading ? (
|
||||
<span className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<span className="flex items-center gap-2 text-muted-foreground">
|
||||
<Loader2 className="size-4 animate-spin" />
|
||||
Loading...
|
||||
</span>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useCallback, useState } from 'react';
|
||||
import { Package as PackageIcon, Plus } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import type { Package } from '@/types';
|
||||
|
||||
@@ -108,8 +107,6 @@ export default function PackagePage() {
|
||||
onEdit={openEdit}
|
||||
onDelete={deletePackage}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<PackageDialog
|
||||
|
||||
@@ -47,8 +47,8 @@ export function usePlanColumns({
|
||||
header: 'Plan',
|
||||
cell: ({ row }) => (
|
||||
<div>
|
||||
<p className="font-medium">{row.original.name}</p>
|
||||
<p className="text-xs text-muted-foreground">{row.original.slug}</p>
|
||||
<p>{row.original.name}</p>
|
||||
<p className="text-muted-foreground">{row.original.slug}</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@@ -67,7 +67,7 @@ export function usePlanColumns({
|
||||
header: 'Limits',
|
||||
enableSorting: false,
|
||||
cell: ({ row }) => (
|
||||
<div className="text-xs text-muted-foreground">
|
||||
<div className="text-muted-foreground">
|
||||
<p>{row.original.max_projects} projects</p>
|
||||
<p>{row.original.max_users} users</p>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +93,7 @@ export function PlanSheet({
|
||||
placeholder="Basic plan for small teams"
|
||||
{...register('description', { required: true })}
|
||||
required
|
||||
className="min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
className="min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -180,7 +180,7 @@ export function PlanSheet({
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-5">
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<label className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="size-4 rounded border-border accent-primary"
|
||||
@@ -188,7 +188,7 @@ export function PlanSheet({
|
||||
/>
|
||||
Active
|
||||
</label>
|
||||
<label className="flex items-center gap-2 text-sm">
|
||||
<label className="flex items-center gap-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="size-4 rounded border-border accent-primary"
|
||||
@@ -201,10 +201,10 @@ export function PlanSheet({
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<Label>Permissions</Label>
|
||||
<span className="text-xs text-muted-foreground">{permissionIds.length} selected</span>
|
||||
<span className="text-muted-foreground">{permissionIds.length} selected</span>
|
||||
</div>
|
||||
{isPermissionsLoading ? (
|
||||
<div className="rounded-md border p-6 text-sm text-muted-foreground">
|
||||
<div className="rounded-md border p-6 text-muted-foreground">
|
||||
Loading permissions...
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { BadgeIndianRupee, Plus } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PERMISSIONS } from '@/constants/permissions';
|
||||
import { PermissionGuard } from '@/guards';
|
||||
@@ -174,8 +173,6 @@ export default function PlansPage() {
|
||||
onLimitChange={setLimit}
|
||||
onSortingChange={setSorting}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<PlanSheet
|
||||
|
||||
@@ -35,14 +35,14 @@ function StateBadges({ value }: { value: string | null }) {
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center justify-center rounded-full border border-border/40 bg-muted/50 px-1.5 py-0.5 text-[10px] font-bold text-muted-foreground transition-colors hover:bg-muted"
|
||||
className="flex items-center justify-center rounded-full border border-border/40 bg-muted/50 px-1.5 py-0.5 text-muted-foreground transition-colors hover:bg-muted"
|
||||
>
|
||||
+{remainingStates.length}
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-2" align="start">
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<p className="mb-0.5 px-1 text-[10px] font-bold uppercase tracking-wider text-muted-foreground">
|
||||
<p className="mb-0.5 px-1 text-muted-foreground">
|
||||
Other States
|
||||
</p>
|
||||
{remainingStates.map((state) => (
|
||||
@@ -64,7 +64,7 @@ export function useProjectColumns() {
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Project Name',
|
||||
cell: ({ row }) => <div className="font-semibold">{row.original.name}</div>,
|
||||
cell: ({ row }) => <div>{row.original.name}</div>,
|
||||
},
|
||||
{
|
||||
accessorKey: 'state',
|
||||
|
||||
@@ -51,13 +51,13 @@ export function ProjectDialog({
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-2xl" onOpenAutoFocus={(event) => event.preventDefault()}>
|
||||
<DialogHeader className="gap-2">
|
||||
<DialogTitle className="flex items-center gap-3 text-xl">
|
||||
<DialogTitle className="flex items-center gap-3">
|
||||
<div className="rounded-lg bg-primary p-2 text-primary-foreground shadow-sm">
|
||||
<Layers className="size-5" />
|
||||
</div>
|
||||
{projectId ? 'Edit Project Details' : 'Create New Project'}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-sm">
|
||||
<DialogDescription>
|
||||
{projectId
|
||||
? 'Update the technical specifications for your road infrastructure project.'
|
||||
: 'Provide the essential road data to establish a new analysis project.'}
|
||||
@@ -97,7 +97,7 @@ export function ProjectDialog({
|
||||
|
||||
<div className="grid gap-8 pt-2 md:grid-cols-2">
|
||||
<div className="space-y-4">
|
||||
<p className="flex items-center gap-2 text-[11px] font-black tracking-widest text-muted-foreground">
|
||||
<p className="flex items-center gap-2 text-muted-foreground">
|
||||
<MapPin className="size-3.5 opacity-60" />
|
||||
START POINT
|
||||
</p>
|
||||
@@ -108,7 +108,7 @@ export function ProjectDialog({
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="0.0000"
|
||||
className="font-mono text-xs"
|
||||
className="font-mono"
|
||||
aria-invalid={!!startLatErrorMessage}
|
||||
{...register('start_lat')}
|
||||
/>
|
||||
@@ -119,7 +119,7 @@ export function ProjectDialog({
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="0.0000"
|
||||
className="font-mono text-xs"
|
||||
className="font-mono"
|
||||
aria-invalid={!!startLngErrorMessage}
|
||||
{...register('start_lng')}
|
||||
/>
|
||||
@@ -128,7 +128,7 @@ export function ProjectDialog({
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<p className="flex items-center gap-2 text-[11px] font-black tracking-widest text-muted-foreground">
|
||||
<p className="flex items-center gap-2 text-muted-foreground">
|
||||
<MapPin className="size-3.5 opacity-60" />
|
||||
END POINT
|
||||
</p>
|
||||
@@ -139,7 +139,7 @@ export function ProjectDialog({
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="0.0000"
|
||||
className="font-mono text-xs"
|
||||
className="font-mono"
|
||||
aria-invalid={!!endLatErrorMessage}
|
||||
{...register('end_lat')}
|
||||
/>
|
||||
@@ -150,7 +150,7 @@ export function ProjectDialog({
|
||||
type="number"
|
||||
step="any"
|
||||
placeholder="0.0000"
|
||||
className="font-mono text-xs"
|
||||
className="font-mono"
|
||||
aria-invalid={!!endLngErrorMessage}
|
||||
{...register('end_lng')}
|
||||
/>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useCallback, useState } from 'react';
|
||||
import { Layers, Plus } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import type { Project } from '@/types';
|
||||
|
||||
@@ -100,8 +99,6 @@ export default function ProjectPage() {
|
||||
onEdit={openEdit}
|
||||
onDelete={deleteProject}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<ProjectDialog
|
||||
|
||||
@@ -6,7 +6,6 @@ import { Button } from '@/components/ui/button';
|
||||
import { Loader2, TrendingUp, ArrowUp, ArrowDown } from 'lucide-react';
|
||||
import VideoPlayerSection from '@/components/video-player-section';
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { sessionService, videoService } from '@/services/api';
|
||||
import { SessionContext, DetectionData, DetectionType } from '@/types';
|
||||
import { getVideoFile, clearVideoFile } from '@/lib/video-storage';
|
||||
@@ -182,7 +181,6 @@ export default function VideoResultsPage() {
|
||||
projectId={session?.projectId || undefined}
|
||||
/>
|
||||
)}
|
||||
<PoweredBy />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,6 @@ import { Button } from '@/components/ui/button';
|
||||
import { Loader2, TrendingUp } from 'lucide-react';
|
||||
import VideoPlayerSection from '@/components/video-player-section';
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { sessionService } from '@/services/api';
|
||||
import { SessionContext, DetectionData, DetectionType } from '@/types';
|
||||
import { clearVideoFile } from '@/lib/video-storage';
|
||||
@@ -147,7 +146,6 @@ export default function ResultsPage() {
|
||||
projectId={session?.projectId || undefined}
|
||||
/>
|
||||
)}
|
||||
<PoweredBy />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -30,7 +30,7 @@ export function useRoleColumns({
|
||||
{
|
||||
accessorKey: 'name',
|
||||
header: 'Name',
|
||||
cell: ({ row }) => <span className="font-medium">{row.original.name}</span>,
|
||||
cell: ({ row }) => <span>{row.original.name}</span>,
|
||||
},
|
||||
{
|
||||
accessorKey: 'display_name',
|
||||
|
||||
@@ -117,11 +117,11 @@ export function RoleSheet({
|
||||
error={errors.permission_ids?.message}
|
||||
className="space-y-3"
|
||||
labelEnd={
|
||||
<span className="text-xs text-muted-foreground">{permissionIds.length} selected</span>
|
||||
<span className="text-muted-foreground">{permissionIds.length} selected</span>
|
||||
}
|
||||
>
|
||||
{isPermissionsLoading ? (
|
||||
<div className="rounded-md border p-6 text-sm text-muted-foreground">
|
||||
<div className="rounded-md border p-6 text-muted-foreground">
|
||||
Loading permissions...
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useCallback, useState } from 'react';
|
||||
import { Plus, ShieldCheck } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PERMISSIONS } from '@/constants/permissions';
|
||||
import { PermissionGuard } from '@/guards';
|
||||
@@ -136,8 +135,6 @@ export default function RolesPage() {
|
||||
onLimitChange={setLimit}
|
||||
onSortingChange={setSorting}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<RoleSheet
|
||||
|
||||
@@ -36,14 +36,14 @@ function StateBadges({ value }: { value: string | null }) {
|
||||
<PopoverTrigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center justify-center rounded-full border border-border/40 bg-muted/50 px-1.5 py-0.5 text-[10px] font-bold text-muted-foreground transition-colors hover:bg-muted"
|
||||
className="flex items-center justify-center rounded-full border border-border/40 bg-muted/50 px-1.5 py-0.5 text-muted-foreground transition-colors hover:bg-muted"
|
||||
>
|
||||
+{remainingStates.length}
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-2" align="start">
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<p className="mb-0.5 px-1 text-[10px] font-bold uppercase tracking-wider text-muted-foreground">
|
||||
<p className="mb-0.5 px-1 text-muted-foreground">
|
||||
Other States
|
||||
</p>
|
||||
{remainingStates.map((state) => (
|
||||
@@ -65,7 +65,7 @@ export function useSegmentColumns(projects: Project[], packages: Package[]) {
|
||||
{
|
||||
accessorKey: 'segment_name',
|
||||
header: 'Segment Name',
|
||||
cell: ({ row }) => <div className="font-semibold">{row.original.segment_name}</div>,
|
||||
cell: ({ row }) => <div>{row.original.segment_name}</div>,
|
||||
},
|
||||
{
|
||||
accessorKey: 'package_id',
|
||||
@@ -101,7 +101,7 @@ export function useSegmentColumns(projects: Project[], packages: Package[]) {
|
||||
<div className="flex flex-row gap-2">
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center gap-1.5 border-amber-500/50 font-bold text-amber-500"
|
||||
className="flex items-center gap-1.5 border-amber-500/50 text-amber-500"
|
||||
>
|
||||
<Milestone className="size-3" />
|
||||
{segment.chainage_start_km} - {segment.chainage_end_km}
|
||||
@@ -124,7 +124,7 @@ export function useSegmentColumns(projects: Project[], packages: Package[]) {
|
||||
cell: ({ row }) => (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center gap-1.5 border-blue-500/50 font-bold text-blue-500"
|
||||
className="flex items-center gap-1.5 border-blue-500/50 text-blue-500"
|
||||
>
|
||||
<MapPin className="size-3" />
|
||||
{row.original.start_lat.toFixed(4)}, {row.original.start_lng.toFixed(4)}
|
||||
@@ -137,7 +137,7 @@ export function useSegmentColumns(projects: Project[], packages: Package[]) {
|
||||
cell: ({ row }) => (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="flex items-center gap-1.5 border-blue-500/50 font-bold text-blue-500"
|
||||
className="flex items-center gap-1.5 border-blue-500/50 text-blue-500"
|
||||
>
|
||||
<MapPin className="size-3" />
|
||||
{row.original.end_lat.toFixed(4)}, {row.original.end_lng.toFixed(4)}
|
||||
|
||||
@@ -79,13 +79,13 @@ export function SegmentDialog({
|
||||
onOpenAutoFocus={(event) => event.preventDefault()}
|
||||
>
|
||||
<DialogHeader className="gap-2">
|
||||
<DialogTitle className="flex items-center gap-3 text-xl">
|
||||
<DialogTitle className="flex items-center gap-3">
|
||||
<div className="rounded-lg bg-primary p-2 text-primary-foreground shadow-sm">
|
||||
<Milestone className="size-5" />
|
||||
</div>
|
||||
{segmentId ? 'Edit Segment' : 'Create Segment'}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-sm">
|
||||
<DialogDescription>
|
||||
{segmentId
|
||||
? 'Update the technical specifications for your road segment.'
|
||||
: 'Select a project and package, then provide the segment data.'}
|
||||
@@ -99,7 +99,7 @@ export function SegmentDialog({
|
||||
<Select value={projectId} onValueChange={onProjectChange}>
|
||||
<SelectTrigger aria-invalid={!!getError('project_id')}>
|
||||
{isProjectsLoading ? (
|
||||
<span className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<span className="flex items-center gap-2 text-muted-foreground">
|
||||
<Loader2 className="size-4 animate-spin" />
|
||||
Loading...
|
||||
</span>
|
||||
@@ -126,7 +126,7 @@ export function SegmentDialog({
|
||||
>
|
||||
<SelectTrigger aria-invalid={!!getError('package_id')}>
|
||||
{isPackagesLoading ? (
|
||||
<span className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<span className="flex items-center gap-2 text-muted-foreground">
|
||||
<Loader2 className="size-4 animate-spin" />
|
||||
Loading...
|
||||
</span>
|
||||
@@ -211,7 +211,7 @@ export function SegmentDialog({
|
||||
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<div className="space-y-4">
|
||||
<p className="flex items-center gap-2 text-[11px] font-black tracking-widest text-muted-foreground">
|
||||
<p className="flex items-center gap-2 text-muted-foreground">
|
||||
<MapPin className="size-3.5 opacity-60" />
|
||||
START COORDINATES
|
||||
</p>
|
||||
@@ -244,7 +244,7 @@ export function SegmentDialog({
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<p className="flex items-center gap-2 text-[11px] font-black tracking-widest text-muted-foreground">
|
||||
<p className="flex items-center gap-2 text-muted-foreground">
|
||||
<MapPin className="size-3.5 opacity-60" />
|
||||
END COORDINATES
|
||||
</p>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useCallback, useState } from 'react';
|
||||
import { Milestone, Plus } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import type { Chainage } from '@/types';
|
||||
|
||||
@@ -119,8 +118,6 @@ export default function SegmentPage() {
|
||||
onEdit={openEdit}
|
||||
onDelete={deleteSegment}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<SegmentDialog
|
||||
|
||||
@@ -41,8 +41,8 @@ export function useTenantColumns({
|
||||
header: 'Tenant',
|
||||
cell: ({ row }) => (
|
||||
<div>
|
||||
<p className="font-medium">{row.original.name}</p>
|
||||
<p className="text-xs text-muted-foreground">{row.original.slug}</p>
|
||||
<p>{row.original.name}</p>
|
||||
<p className="text-muted-foreground">{row.original.slug}</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -74,8 +74,8 @@ export function TenantSheet({
|
||||
</DialogHeader>
|
||||
<form onSubmit={onSubmit} className="flex flex-1 flex-col gap-5 px-4">
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium">Basic Information</p>
|
||||
<p className="text-xs text-muted-foreground">Tenant identity and subscription binding.</p>
|
||||
<p>Basic Information</p>
|
||||
<p className="text-muted-foreground">Tenant identity and subscription binding.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
@@ -147,7 +147,7 @@ export function TenantSheet({
|
||||
id="tenant-description"
|
||||
placeholder="North zone operations"
|
||||
{...register('description')}
|
||||
className="min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
className="min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -155,8 +155,8 @@ export function TenantSheet({
|
||||
{!isEditMode ? (
|
||||
<>
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium">Tenant Administrator</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
<p>Tenant Administrator</p>
|
||||
<p className="text-muted-foreground">
|
||||
Invitation details for the primary tenant admin account.
|
||||
</p>
|
||||
</div>
|
||||
@@ -204,10 +204,10 @@ export function TenantSheet({
|
||||
</div>
|
||||
</>
|
||||
) : adminEmail ? (
|
||||
<div className="rounded-md border bg-muted/40 p-4 text-sm text-muted-foreground">
|
||||
<div className="rounded-md border bg-muted/40 p-4 text-muted-foreground">
|
||||
Admin invitation details cannot be changed after tenant creation.
|
||||
<p className="mt-1 text-foreground">
|
||||
Current admin email: <span className="font-medium">{adminEmail}</span>
|
||||
Current admin email: <span>{adminEmail}</span>
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
import { Globe, Plus } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PERMISSIONS } from '@/constants/permissions';
|
||||
import { PermissionGuard } from '@/guards';
|
||||
@@ -171,8 +170,6 @@ export default function TenantsPage() {
|
||||
onLimitChange={setLimit}
|
||||
onSortingChange={setSorting}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<TenantSheet
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useRouter, useParams } from 'next/navigation';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Loader2, TrendingUp, ArrowUp, ArrowDown } from 'lucide-react';
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { sessionService, videoService } from '@/services/api';
|
||||
import { SessionContext } from '@/types';
|
||||
import { ROUTES } from '@/utils/routes';
|
||||
@@ -241,8 +240,6 @@ export default function VideoProcessingPage() {
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<PoweredBy />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
} from '@/components/ui/select';
|
||||
import { Loader2, TrendingUp, ChevronRight } from 'lucide-react';
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { sessionService, videoService } from '@/services/api';
|
||||
import { SessionContext } from '@/types';
|
||||
import { storeVideoFile } from '@/lib/video-storage';
|
||||
@@ -265,12 +264,6 @@ export default function UploadPage() {
|
||||
</Card>
|
||||
</Reveal>
|
||||
</div>
|
||||
|
||||
<div className="mt-12">
|
||||
<Reveal delay={0.4}>
|
||||
<PoweredBy />
|
||||
</Reveal>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -40,7 +40,7 @@ export function useUserColumns({
|
||||
accessorKey: 'first_name',
|
||||
header: 'Name',
|
||||
cell: ({ row }) => (
|
||||
<span className="font-medium">
|
||||
<span>
|
||||
{[row.original.first_name, row.original.last_name].filter(Boolean).join(' ') ||
|
||||
row.original.username}
|
||||
</span>
|
||||
|
||||
@@ -19,8 +19,8 @@ export function UserStats({ total, activeCount, inactiveCount, pendingCount }: U
|
||||
<div className="grid gap-3 md:grid-cols-4">
|
||||
{stats.map((stat) => (
|
||||
<div key={stat.label} className="rounded-lg border bg-card p-4">
|
||||
<p className="text-xs text-muted-foreground">{stat.label}</p>
|
||||
<p className="mt-1 text-2xl font-semibold">{stat.value}</p>
|
||||
<p className="text-muted-foreground">{stat.label}</p>
|
||||
<p>{stat.value}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
import { Plus, Users } from 'lucide-react';
|
||||
|
||||
import { PageHeader } from '@/components/page-header';
|
||||
import { PoweredBy } from '@/components/powered-by';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PERMISSIONS } from '@/constants/permissions';
|
||||
import { PermissionGuard } from '@/guards';
|
||||
@@ -139,8 +138,6 @@ export default function UsersPage() {
|
||||
onLimitChange={setLimit}
|
||||
onSortingChange={setSorting}
|
||||
/>
|
||||
|
||||
<PoweredBy />
|
||||
</main>
|
||||
|
||||
<UserSheet
|
||||
|
||||
Reference in New Issue
Block a user