Skip to content

Commit

Permalink
if ur reading this please save me from kyle
Browse files Browse the repository at this point in the history
  • Loading branch information
SashankBalusu committed Mar 3, 2025
1 parent 4454c72 commit 8099623
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 0 deletions.
45 changes: 45 additions & 0 deletions api/supabase/queries/dashboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { UUID } from 'crypto';

Check failure on line 1 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'UUID' is defined but never used

Check failure on line 1 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'UUID' is defined but never used

Check failure on line 1 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'UUID' is defined but never used

Check failure on line 1 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'UUID' is defined but never used
import { PlantTip } from '@/types/schema';
import supabase from '../createClient';

//quick lil documentation drop:
// Retrieve all tips from the database. Let’s say there are N tips.
// Determine the cycle number using cycleNumber = floor(today’s timestamp / (N * 86400000)).
// This ensures that after N days, a new cycle begins, and the order reshuffles.
// Shuffle tips using a deterministic seed (based on cycleNumber).
// This creates a unique but repeatable order for each cycle.
// Fisher-Yates shuffle ensures every tip appears exactly once before repeating.
// Select today's tip based on day position in the cycle.
// dayInCycle = (today’s date % N), ensuring each tip is picked once per cycle.

// Function to create a seeded shuffle (Fisher-Yates with a consistent seed)
const seededShuffle = (array: PlantTip[], seed: number): PlantTip[] => {
let shuffled = [...array];

Check failure on line 17 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'shuffled' is never reassigned. Use 'const' instead

Check failure on line 17 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'shuffled' is never reassigned. Use 'const' instead

Check failure on line 17 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'shuffled' is never reassigned. Use 'const' instead

Check failure on line 17 in api/supabase/queries/dashboard.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, Prettier, and TypeScript compiler

'shuffled' is never reassigned. Use 'const' instead
for (let i = shuffled.length - 1; i > 0; i--) {
const j = (seed * (i + 1)) % shuffled.length; // Deterministic shuffle
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
};

// Function to get a randomized but cycle-complete daily plant tip
export const getDailyPlantTip = async (): Promise<PlantTip | null> => {
const { data, error } = await supabase.from('gardening_tips').select('*');

if (error) {
throw new Error(`Error getting plant tip: ${error.message}`);
}

// Determine the cycle number (each cycle displays all tips once)
const cycleLength = data.length;
const cycleNumber = Math.floor(
new Date().getTime() / (cycleLength * 86400000),
); // New cycle every 'cycleLength' days

// Shuffle deterministically based on the cycle number
const shuffledTips = seededShuffle(data, cycleNumber);

// Select today's tip
const dayInCycle = new Date().getDate() % cycleLength;
return shuffledTips[dayInCycle];
};
88 changes: 88 additions & 0 deletions app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
'use client';

import { useEffect, useState } from 'react';
import { getDailyPlantTip } from '@/api/supabase/queries/dashboard';
import SingleTip from '@/components/SingleTip';
import { PlantTip } from '@/types/schema';
import { useAuth } from '@/utils/AuthProvider';
import {
ArrowIcon,
CalendarContainer,
Circle,
Container,
DashboardTitle,
Greeting,
Header,
InfoContainer,
InfoHead,
PlaceholderText,
ReminderContainer,
SeeAllLink,
TaskContainer,
Title,
WeatherContainer,
WeatherReminderWrapper,
} from './styles';

export default function Page() {
const [plantTip, setPlantTip] = useState<PlantTip | null>(null);
const { userId, loading: authLoading } = useAuth();

useEffect(() => {
if (!authLoading && userId) {
const fetchTip = async () => {
const tip = await getDailyPlantTip();

setPlantTip(tip);
};
fetchTip();
}
}, [authLoading, userId]);

return (
<div>
{authLoading || !userId ? (
<p>Log in please!</p>
) : (
<Container>
<Greeting>Hi, [Name]!</Greeting>
<DashboardTitle>My Dashboard</DashboardTitle>
<TaskContainer>
<PlaceholderText>Task Placeholder</PlaceholderText>
</TaskContainer>
<CalendarContainer>
<PlaceholderText>Calendar Placeholder</PlaceholderText>
</CalendarContainer>
<WeatherReminderWrapper>
<WeatherContainer>
<PlaceholderText>Weather Placeholder</PlaceholderText>
</WeatherContainer>
<ReminderContainer>
<PlaceholderText>Reminder Placeholder</PlaceholderText>
</ReminderContainer>
</WeatherReminderWrapper>
<Header>
<Title>Resources</Title>
<SeeAllLink href="/resources">
See All <ArrowIcon></ArrowIcon>
</SeeAllLink>
</Header>

<InfoContainer>
<Circle />
<InfoHead>Tips are refreshed daily!</InfoHead>
</InfoContainer>

{plantTip == null ? (
<p>Loading...</p>
) : (
<SingleTip
category={plantTip.category}
body_text={plantTip.body_text}
/>
)}
</Container>
)}
</div>
);
}
134 changes: 134 additions & 0 deletions app/dashboard/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import styled from 'styled-components';
import COLORS from '@/styles/colors';

export const Container = styled.div`
padding: 2rem;
max-width: 1000px;
margin: 0 auto;
`;

export const Header = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 4px;
`;

export const Title = styled.h1`
color: ${COLORS.shrub};
font-family: Lexend;
font-size: 16px;
font-style: normal;
font-weight: 300;
line-height: normal;
margin: 0;
`;

export const SeeAllLink = styled.a`
display: flex;
align-items: center;
color: ${COLORS.midgray};
font-family: Lexend;
font-size: 10px;
font-style: normal;
font-weight: 300;
line-height: normal;
text-decoration: none;
`;

export const ArrowIcon = styled.span`
margin-left: 5px;
`;

export const InfoContainer = styled.div`
display: flex;
align-items: center;
margin-bottom: 12px;
`;

export const InfoHead = styled.p`
color: ${COLORS.midgray};
font-family: Lexend;
font-size: 10px;
font-style: normal;
font-weight: 300;
line-height: normal;
`;

export const Circle = styled.div`
color: ${COLORS.midgray};
width: 10px;
height: 10px;
border: 1px solid #666;
border-radius: 50%;
margin-right: 10px;
`;

export const Greeting = styled.h2`
color: ${COLORS.shrub};
font-family: Lexend;
font-size: 28px;
font-style: normal;
font-weight: 400;
line-height: normal;
margin-bottom: 16px;
`;

export const DashboardTitle = styled.p`
color: ${COLORS.shrub};
font-family: Lexend;
font-size: 14px;
font-style: normal;
font-weight: 300;
line-height: normal;
margin-bottom: 8px;
`;

export const TaskContainer = styled.div`
background-color: #fff;
border-radius: 10px;
box-shadow: 2px 0px 8px 0px rgba(0, 0, 0, 0.1);
height: 200px;
margin-bottom: 8px;
`;
export const CalendarContainer = styled.div`
background-color: #fff;
border-radius: 10px;
box-shadow: 2px 0px 8px 0px rgba(0, 0, 0, 0.1);
height: 125px;
margin-bottom: 8px;
`;

export const PlaceholderText = styled.p`
color: ${COLORS.shrub};
font-family: Lexend;
font-size: 14px;
font-style: normal;
font-weight: 300;
line-height: normal;
padding: 20px;
`;
export const WeatherReminderWrapper = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 8px;
`;
export const WeatherContainer = styled.div`
background-color: #fff;
border-radius: 10px;
box-shadow: 2px 0px 8px 0px rgba(0, 0, 0, 0.1);
height: 125px;
width: 50%;
margin-bottom: 8px;
`;
export const ReminderContainer = styled.div`
background-color: #fff;
border-radius: 10px;
box-shadow: 2px 0px 8px 0px rgba(0, 0, 0, 0.1);
height: 125px;
width: 50%;
margin-bottom: 8px;
`;
33 changes: 33 additions & 0 deletions components/SingleTip/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { Category } from '@/types/schema';
import { Card, Text, Title } from './styles';

// Define the category type with specific values

// Map category values to headers
const categoryHeaders: Record<Category, string> = {
'Helpful Flowers for Your Garden': 'Helpful Flowers',
'Water Management': 'Water Tips',
Mulching: 'Mulching Tips',
Harvesting: 'Harvesting Tips',
Planting: 'Planting Tips',
Weeding: 'Weeding Tips',
};

// Define the prop type
interface TipCardProps {
category: Category;
body_text: string;
}

// Styled components

export default function TipCard({ category, body_text }: TipCardProps) {
return (
<Card>
<Title>Tip of the Day</Title>
<Text>{categoryHeaders[category]}</Text>
<Text>{body_text}</Text>
</Card>
);
}
31 changes: 31 additions & 0 deletions components/SingleTip/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import styled from 'styled-components';
import COLORS from '@/styles/colors';

export const Card = styled.div`
background-color: white;
box-shadow: 2px 0px 8px 0px rgba(0, 0, 0, 0.1);
border-radius: 10px;
padding: 24px;
height: 109px;
`;

export const Title = styled.h2`
color: ${COLORS.shrub};
font-family: Lexend;
font-size: 16px;
font-style: normal;
font-weight: 300;
line-height: normal;
margin-bottom: 6px;
text-align: center;
`;

export const Text = styled.p`
color: ${COLORS.midgray};
font-family: Lexend;
font-size: 10px;
font-style: normal;
font-weight: 300;
line-height: normal;
margin-bottom: 6px;
`;
14 changes: 14 additions & 0 deletions types/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,17 @@ export interface ConfirmAlertProps {
export interface InputProps {
initialValue?: string;
}

export interface PlantTip {
id: UUID;
category: Category;
body_text: string;
}

export type Category =
| 'Helpful Flowers for Your Garden'
| 'Water Management'
| 'Mulching'
| 'Harvesting'
| 'Planting'
| 'Weeding';

0 comments on commit 8099623

Please sign in to comment.