Back to Archive
Case Study ยท 2025FeaturedLIVE

Ashly

Ashly

Enterprise-grade intranet for streamlined maritime and engineering operations.

Ashly
Synced in 1.5s

A comprehensive internal platform built with Next.js and Prisma to centralize project management, field reporting, and document control. It features dynamic inspection wizards and a recursive file management system for industrial-scale operations.

Problem Visual
The Problem

Fragmented operations and manual reporting.

Maritime and engineering firms often operate across fragmented environments where site inspections, expense claims, and resource tracking are handled via manual paperwork or siloed spreadsheets. This lack of synchronization leads to operational bottlenecks, delayed project visibility, and significant friction in maintaining compliance and personnel safety records across remote job sites.

Solution Visual
The Solution

Unified Control.
Zero Friction.

The platform provides a unified 'Command Center' that aggregates data from across the organization using Prisma for type-safe database interactions. It implements a custom recursive file system for complex document hierarchies and a state-driven form engine for site inspections, ensuring that field data is captured accurately and synced instantly to a central PostgreSQL store with media handling via Cloudflare R2.

Feature Visual
Implementation

Recursive Document Management

Recursive File System
Multi-step Inspection Engine
Real-time Resource Dashboard
Dynamic Material Tracking
Anonymous Reporting Portal

System Core // findFolderById

const findFolderById = (node, id) => {
  if (!node) return null;
  if (node.id === id) return node;
  if (node.children) {
    for (let child of node.children) {
      if (child.type === 'folder') {
        const found = findFolderById(child, id);
        if (found) return found;
      }
    }
  }
  return null;
};

const handleNavigate = (folderId, folderName) => {
  setIsLoading(true);
  setTimeout(() => {
    setCurrentFolderId(folderId);
    setBreadcrumbs(prev => {
      const existingIndex = prev.findIndex(b => b.id === folderId);
      if (existingIndex >= 0) return prev.slice(0, existingIndex + 1);
      return [...prev, { id: folderId, name: folderName }];
    });
    setIsLoading(false);
  }, 200);
};
javascript
Next Project

Next Case Study

CML Kothamangalam