diff --git a/app/[locale]/festival/_components/festival-tabs.tsx b/app/[locale]/festival/_components/festival-tabs.tsx
index bfadde1..4504de1 100644
--- a/app/[locale]/festival/_components/festival-tabs.tsx
+++ b/app/[locale]/festival/_components/festival-tabs.tsx
@@ -30,6 +30,8 @@ export const FestivalTabs = async () => {
diff --git a/app/[locale]/festival/page.tsx b/app/[locale]/festival/page.tsx
index 8b3ace7..f230622 100644
--- a/app/[locale]/festival/page.tsx
+++ b/app/[locale]/festival/page.tsx
@@ -5,6 +5,7 @@ import { Suspense } from "react";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { FestivalTabs } from "./_components/festival-tabs";
+import { Loader2 } from "lucide-react";
type Props = {
params: { locale: string; username: string };
@@ -45,7 +46,13 @@ export default function Festival({
{/*
foo
*/}
- loading...}>
+
+
+
+ }
+ >
diff --git a/components/Ranking/Cadenas.tsx b/components/Ranking/Cadenas.tsx
index a6ef193..4b702d7 100644
--- a/components/Ranking/Cadenas.tsx
+++ b/components/Ranking/Cadenas.tsx
@@ -9,11 +9,13 @@ import LoadingSkeleton from "./LoadingSkeleton";
interface Props {
highlines_ids: string[];
+ startDate?: Date;
+ endDate?: Date;
}
const PAGE_SIZE = 5;
-function Cadenas({ highlines_ids }: Props) {
+function Cadenas({ highlines_ids, startDate, endDate }: Props) {
const supabase = useSupabaseBrowser();
async function fetchCadenas({ pageParam = 1 }) {
@@ -21,6 +23,8 @@ function Cadenas({ highlines_ids }: Props) {
highline_ids: highlines_ids,
page_number: pageParam,
page_size: PAGE_SIZE,
+ start_date: startDate?.toISOString(),
+ end_date: endDate?.toISOString(),
});
return data;
}
diff --git a/components/Ranking/Distance.tsx b/components/Ranking/Distance.tsx
index 77bc7ec..7e49fa5 100644
--- a/components/Ranking/Distance.tsx
+++ b/components/Ranking/Distance.tsx
@@ -9,18 +9,22 @@ import LoadingSkeleton from "./LoadingSkeleton";
interface Props {
highlines_ids: string[];
+ startDate?: Date;
+ endDate?: Date;
}
const PAGE_SIZE = 5;
-function Distance({ highlines_ids }: Props) {
+function Distance({ highlines_ids, startDate, endDate }: Props) {
const supabase = useSupabaseBrowser();
async function fetchEntries({ pageParam = 1 }) {
- const { data, error } = await supabase.rpc("get_total_walked", {
+ const { data } = await supabase.rpc("get_total_walked", {
highline_ids: highlines_ids,
page_number: pageParam,
page_size: PAGE_SIZE,
+ start_date: startDate?.toISOString(),
+ end_date: endDate?.toISOString(),
});
return data;
}
diff --git a/components/Ranking/FullLine.tsx b/components/Ranking/FullLine.tsx
index 813bd39..16843a8 100644
--- a/components/Ranking/FullLine.tsx
+++ b/components/Ranking/FullLine.tsx
@@ -9,11 +9,13 @@ import LoadingSkeleton from "./LoadingSkeleton";
interface Props {
highlines_ids: string[];
+ startDate?: Date;
+ endDate?: Date;
}
const PAGE_SIZE = 5;
-function FullLine({ highlines_ids }: Props) {
+function FullLine({ highlines_ids, startDate, endDate }: Props) {
const supabase = useSupabaseBrowser();
async function fetchFullLine({ pageParam = 1 }) {
@@ -21,6 +23,8 @@ function FullLine({ highlines_ids }: Props) {
highline_ids: highlines_ids,
page_number: pageParam,
page_size: PAGE_SIZE,
+ start_date: startDate?.toISOString(),
+ end_date: endDate?.toISOString(),
});
return data;
}
diff --git a/components/Ranking/index.tsx b/components/Ranking/index.tsx
index b3e8906..28dab91 100644
--- a/components/Ranking/index.tsx
+++ b/components/Ranking/index.tsx
@@ -11,6 +11,8 @@ import Speedline from "./Speedline";
interface Props {
highlines_ids: string[];
visibleCategories?: Category[];
+ startDate?: Date;
+ endDate?: Date;
}
export type Category = "speedline" | "distance" | "cadenas" | "fullLine";
@@ -19,17 +21,35 @@ const CategoryRenderer: React.FC<
Props & {
category: Category;
}
-> = ({ category, highlines_ids, visibleCategories }) => {
+> = ({ category, highlines_ids, visibleCategories, startDate, endDate }) => {
if (!visibleCategories?.includes(category)) return null;
switch (category) {
case "speedline":
return ;
case "distance":
- return ;
+ return (
+
+ );
case "cadenas":
- return ;
+ return (
+
+ );
case "fullLine":
- return ;
+ return (
+
+ );
default:
return null;
}
@@ -38,6 +58,8 @@ const CategoryRenderer: React.FC<
export const Ranking: React.FC = ({
highlines_ids,
visibleCategories = ["cadenas", "distance", "fullLine", "speedline"], // All categories visible by default,
+ startDate,
+ endDate,
}) => {
const { searchParams } = useQueryString();
const selectedCategory =
diff --git a/supabase/migrations/20240522152724_ranking_with_date_range.sql b/supabase/migrations/20240522152724_ranking_with_date_range.sql
new file mode 100644
index 0000000..1dc75b8
--- /dev/null
+++ b/supabase/migrations/20240522152724_ranking_with_date_range.sql
@@ -0,0 +1,84 @@
+set check_function_bodies = off;
+
+DROP FUNCTION IF EXISTS public.get_total_cadenas (
+ highline_ids UUID[],
+ page_number INTEGER,
+ page_size INTEGER
+);
+
+CREATE OR REPLACE FUNCTION public.get_total_cadenas(highline_ids uuid[], page_number integer, page_size integer, start_date timestamp with time zone DEFAULT NULL::timestamp with time zone, end_date timestamp with time zone DEFAULT NULL::timestamp with time zone)
+ RETURNS TABLE(instagram text, total_cadenas integer, profile_picture text)
+ LANGUAGE plpgsql
+AS $function$
+BEGIN
+RETURN QUERY
+SELECT e.instagram, SUM(e.cadenas)::integer AS total_cadenas, COALESCE(p.profile_picture, '') AS profile_picture
+FROM public.entry e
+LEFT JOIN public.profiles p ON e.instagram = p.username
+WHERE e.highline_id = ANY(get_total_cadenas.highline_ids)
+AND (e.created_at >= COALESCE(start_date, '1970-01-01'::timestamp) OR start_date IS NULL)
+AND (e.created_at <= COALESCE(end_date, now()) OR end_date IS NULL)
+GROUP BY e.instagram, p.profile_picture
+HAVING SUM(e.cadenas) > 0
+ORDER BY total_cadenas DESC
+OFFSET (get_total_cadenas.page_number - 1) * get_total_cadenas.page_size
+LIMIT get_total_cadenas.page_size;
+END;
+$function$
+;
+
+DROP FUNCTION IF EXISTS public.get_total_full_lines (
+ highline_ids UUID[],
+ page_number INTEGER,
+ page_size INTEGER
+);
+
+CREATE OR REPLACE FUNCTION public.get_total_full_lines(highline_ids uuid[], page_number integer, page_size integer, start_date timestamp with time zone DEFAULT NULL::timestamp with time zone, end_date timestamp with time zone DEFAULT NULL::timestamp with time zone)
+ RETURNS TABLE(instagram text, total_full_lines integer, profile_picture text)
+ LANGUAGE plpgsql
+AS $function$
+BEGIN
+RETURN QUERY
+SELECT e.instagram, SUM(e.full_lines)::integer AS total_full_lines, COALESCE(p.profile_picture, '') AS profile_picture
+FROM public.entry e
+LEFT JOIN public.profiles p ON e.instagram = p.username
+WHERE e.highline_id = ANY(get_total_full_lines.highline_ids)
+AND (e.created_at >= COALESCE(start_date, '1970-01-01'::timestamp) OR start_date IS NULL)
+AND (e.created_at <= COALESCE(end_date, now()) OR end_date IS NULL)
+GROUP BY e.instagram, p.profile_picture
+HAVING SUM(e.full_lines) > 0
+ORDER BY total_full_lines DESC
+OFFSET (get_total_full_lines.page_number - 1) * get_total_full_lines.page_size
+LIMIT get_total_full_lines.page_size;
+END;
+$function$
+;
+
+DROP FUNCTION IF EXISTS public.get_total_walked (
+ highline_ids UUID[],
+ page_number INTEGER,
+ page_size INTEGER
+);
+
+CREATE OR REPLACE FUNCTION public.get_total_walked(highline_ids uuid[], page_number integer, page_size integer, start_date timestamp with time zone DEFAULT NULL::timestamp with time zone, end_date timestamp with time zone DEFAULT NULL::timestamp with time zone)
+ RETURNS TABLE(instagram text, total_distance_walked integer, profile_picture text)
+ LANGUAGE plpgsql
+AS $function$
+BEGIN
+RETURN QUERY
+SELECT e.instagram, SUM(e.distance_walked)::integer AS total_distance_walked, COALESCE(p.profile_picture, '') AS profile_picture
+FROM public.entry e
+LEFT JOIN public.profiles p ON e.instagram = p.username
+WHERE e.highline_id = ANY(get_total_walked.highline_ids)
+AND (e.created_at >= COALESCE(start_date, '1970-01-01'::timestamp) OR start_date IS NULL)
+AND (e.created_at <= COALESCE(end_date, now()) OR end_date IS NULL)
+AND e.distance_walked IS NOT NULL
+GROUP BY e.instagram, p.profile_picture
+ORDER BY total_distance_walked DESC
+OFFSET (get_total_walked.page_number - 1) * get_total_walked.page_size
+LIMIT page_size;
+END;
+$function$
+;
+
+
diff --git a/utils/supabase/database.types.ts b/utils/supabase/database.types.ts
index 7bc2f09..47e5b14 100644
--- a/utils/supabase/database.types.ts
+++ b/utils/supabase/database.types.ts
@@ -264,6 +264,8 @@ export type Database = {
highline_ids: string[];
page_number: number;
page_size: number;
+ start_date?: string;
+ end_date?: string;
};
Returns: {
instagram: string;
@@ -276,6 +278,8 @@ export type Database = {
highline_ids: string[];
page_number: number;
page_size: number;
+ start_date?: string;
+ end_date?: string;
};
Returns: {
instagram: string;
@@ -288,6 +292,8 @@ export type Database = {
highline_ids: string[];
page_number: number;
page_size: number;
+ start_date?: string;
+ end_date?: string;
};
Returns: {
instagram: string;