Commit 4bdd4089 authored by Labros Papadopoulos's avatar Labros Papadopoulos
Browse files

Merge branch 'develop' into fix-coppilot-issue

parents 1833bf4d f028409a
Loading
Loading
Loading
Loading
Loading

actions/geocode.ts

0 → 100644
+31 −0
Original line number Diff line number Diff line
'use server';

import { geocode } from 'opencage-api-client';

export interface GeoCoordinates {
  lat: number;
  lng: number;
}

export async function geocodeAddress(address: string): Promise<GeoCoordinates> {
  const geocodeApiKey = process.env.GEOCODE_API_KEY;

  if (!geocodeApiKey) {
    throw new Error('GEOCODE_API_KEY is not set on the server');
  }

  const geocodeResponse = await geocode({
    key: geocodeApiKey,
    q: address,
    language: 'en',
    limit: 1,
    no_annotations: 1,
  });

  if (!geocodeResponse || geocodeResponse.results.length === 0) {
    throw new Error('No geocoding results found for the provided address.');
  }

  const { lat, lng } = geocodeResponse.results[0].geometry;
  return { lat, lng };
}
+6 −7
Original line number Diff line number Diff line
@@ -14,12 +14,12 @@ import { hasAccessToView } from '@/actions/roles-viewAccess';

export const dynamic = 'force-dynamic';

function getCurrentPath() {
  if (typeof window !== 'undefined') {
    return window.location.pathname;
  }
  return '';
}
// function getCurrentPath() {
//   if (typeof window !== 'undefined') {
//     return window.location.pathname;
//   }
//   return '';
// }

export default async function Marketplace({
  searchParams,
@@ -78,7 +78,6 @@ export default async function Marketplace({
                {data.serviceSpecifications?.data?.map((serviceSpecification) => (
                  <ServiceSpecificationCard
                    userId={data.session?.user?.name || ''}
                    currentPath={getCurrentPath()}
                    key={serviceSpecification.id}
                    serviceSpecification={serviceSpecification}
                  />
+53 −15
Original line number Diff line number Diff line
@@ -25,19 +25,43 @@ export default function NavigationTree({
  const treeRef = useRef<HTMLDivElement>(null);

  const [isOpen, setIsOpen] = useState(false);
  const [selectedPath, setSelectedPath] = useState<string | undefined>(undefined);

  //   const [selectedPath, setSelectedPath] = useState<string | undefined>(undefined);
  const selectedPath = searchParams?.get('categoryPath') || undefined;
  useEffect(() => {
    if (level == 0) {
    if (level === 0) {
      setIsOpen(true);
    } else if (selectedPath && hierarchy?.children?.some((child) => child.path === selectedPath)) {
      setIsOpen(true);
    }
  }, [level]);
  }, [level, selectedPath, hierarchy?.children]);

  useEffect(() => {
    if (level !== 0) return; // Attach listener only at root tree level

    const handleClickOutside = (event: MouseEvent) => {
      if (treeRef.current && !treeRef.current.contains(event.target as Node)) {
        setSelectedPath(undefined);
        router.replace(pathname || '');
      const target = event.target as HTMLElement;

      // Ignore if click is inside the tree itself
      if (treeRef.current && treeRef.current.contains(target)) {
        return;
      }

      // Ignore if click is on a spec card, modal, search input, or sorting dropdown
      if (
        target.closest('.group\\/item') || // Spec card
        target.closest('[role="dialog"]') || // Modal detail view
        target.closest('input') || // Search box
        target.closest('button') // Sorting / load buttons
      ) {
        return;
      }

      // Clear category filter when clicking empty background space
      const params = new URLSearchParams(searchParams?.toString() || '');
      if (params.has('categoryPath')) {
        params.delete('categoryPath');
        const queryString = params.toString();
        router.replace(queryString ? `${pathname}?${queryString}` : pathname);
      }
    };

@@ -45,18 +69,26 @@ export default function NavigationTree({
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [treeRef]);
  }, [level, pathname, searchParams, router]);

  const onSelected = (path: string | undefined) => {
    const params = new URLSearchParams(searchParams?.toString() || '');
    params.set('searchText', '');
    params.set('categoryPath', path || '');
    router.replace(pathname + '?' + params.toString());
    setSelectedPath(path);

    if (path) {
      params.set('categoryPath', path);
    } else {
      params.delete('categoryPath');
    }

    // Retains all other search params (like searchText, status, etc.)
    const queryString = params.toString();
    const newUrl = queryString ? `${pathname}?${queryString}` : pathname;

    router.replace(newUrl);
  };

  const isCurrentPath = (path: string | undefined) => {
    return selectedPath === path;
    return Boolean(path && selectedPath === path);
  };

  const levelPaddings = ['pl-0', 'pl-0', 'pl-6', 'pl-10'];
@@ -74,13 +106,19 @@ export default function NavigationTree({
                <IoMdArrowDropdown
                  className="min-w-4"
                  color="#98A2B3"
                  onClick={() => setIsOpen(!isOpen)}
                  onClick={(e) => {
                    e.stopPropagation();
                    setIsOpen(!isOpen);
                  }}
                />
              ) : (
                <IoMdArrowDropright
                  className="min-w-4"
                  color="#98A2B3"
                  onClick={() => setIsOpen(!isOpen)}
                  onClick={(e) => {
                    e.stopPropagation();
                    setIsOpen(!isOpen);
                  }}
                />
              )
            ) : (
+7 −3
Original line number Diff line number Diff line
@@ -26,11 +26,15 @@ export function SearchBox({

  useEffect(() => {
    const params = new URLSearchParams(searchParams?.toString() || '');

    if (debouncedValue) {
      params.set('categoryPath', '');
    }
      params.set('searchText', debouncedValue);
    router.replace(pathname + '?' + params.toString());
    } else {
      params.delete('searchText');
    }

    const queryString = params.toString();
    router.replace(queryString ? `${pathname}?${queryString}` : pathname);
  }, [debouncedValue]);

  return (
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ export default function ServiceInfoComponent({
    ? new Date(serviceSpecificationDetails.lastUpdate)
    : new Date();

  const formattedDate = new Intl.DateTimeFormat(undefined, {
  const formattedDate = new Intl.DateTimeFormat('en-US', {
    day: 'numeric',
    month: 'short',
    year: 'numeric',
Loading