Skip to content

Commit

Permalink
fix: day slider colors
Browse files Browse the repository at this point in the history
  • Loading branch information
trevorpfiz committed Aug 12, 2024
1 parent 5126910 commit 4bd331e
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 78 deletions.
19 changes: 10 additions & 9 deletions apps/expo/src/app/(app)/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ import { Separator } from "~/components/ui/separator";
export default function HomeScreen() {
return (
<SafeAreaView style={{ flex: 1 }} edges={["top", "left", "right"]}>
<ScrollView style={{ flex: 1 }} showsVerticalScrollIndicator={true}>
{/* Header */}
<HomeHeader />
{/* Header */}
<HomeHeader />

{/* Metabolic Scores Slider */}
<View>
<DaySlider />
<Separator />
{/* <Separator className="mx-auto mb-4 bg-red-500" orientation="vertical" /> */}
</View>
{/* Metabolic Scores Slider */}
<View>
<DaySlider />
<Separator />
{/* <Separator className="mx-auto mb-4 bg-red-500" orientation="vertical" /> */}
</View>

{/* Main Content */}
<ScrollView style={{ flex: 1 }} showsVerticalScrollIndicator={true}>
{/* Overview Pager */}
<View className="h-64">
<OverviewPager />
Expand Down
11 changes: 4 additions & 7 deletions apps/expo/src/components/calendar/basic-calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { CALENDAR_THEME } from "~/lib/constants";
import { ChevronLeft } from "~/lib/icons/chevron-left";
import { ChevronRight } from "~/lib/icons/chevron-right";
import { useColorScheme } from "~/lib/use-color-scheme";
import { getScoreColors } from "~/lib/utils";

const DAY_HEIGHT = 40;
const MONTH_HEADER_HEIGHT = 40;
Expand All @@ -29,12 +30,6 @@ export function BasicCalendar(props: BasicCalendarProps) {
const isDark = colorScheme === "dark";
const theme = isDark ? CALENDAR_THEME.dark : CALENDAR_THEME.light;

function getScoreColor(score: number) {
if (score >= 70) return theme.good;
if (score >= 50) return theme.ok;
return theme.bad;
}

const calendarTheme: CalendarTheme = {
rowMonth: {
container: {
Expand Down Expand Up @@ -64,7 +59,9 @@ export function BasicCalendar(props: BasicCalendarProps) {
itemDay: {
base: ({ isPressed, isDisabled, id }) => {
const score = mockScoresData.find((s) => s.date === id)?.value;
const scoreColor = score ? getScoreColor(score) : theme.text;
const scoreColor = score
? getScoreColors(score, isDark).text
: theme.text;

return {
container: {
Expand Down
120 changes: 67 additions & 53 deletions apps/expo/src/components/home/day-slider.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
import React, { useCallback, useEffect, useRef } from "react";
import React, { useCallback, useEffect, useMemo, useRef } from "react";
import { Dimensions, Pressable, View } from "react-native";
import { FlashList } from "@shopify/flash-list";
import { format } from "date-fns";
import { format, parseISO } from "date-fns";

import type { ScoresData } from "~/data/scores";
import { Text } from "~/components/ui/text";
import { cn } from "~/lib/utils";
import { mockScoresData } from "~/data/scores";
import { useColorScheme } from "~/lib/use-color-scheme";
import { cn, getScoreColors } from "~/lib/utils";
import { useDateStore } from "~/stores/dateStore";

const mockScoreData = [
{ date: new Date(2024, 7, 8), score: 99 },
{ date: new Date(2024, 7, 7), score: 79 },
{ date: new Date(2024, 7, 6), score: 63 },
{ date: new Date(2024, 7, 5), score: 91 },
{ date: new Date(2024, 7, 4), score: 45 },
{ date: new Date(2024, 7, 3), score: 87 },
{ date: new Date(2024, 7, 2), score: 69 },
{ date: new Date(2024, 7, 1), score: 93 },
{ date: new Date(2024, 6, 31), score: 58 },
{ date: new Date(2024, 6, 30), score: 82 },
{ date: new Date(2024, 6, 29), score: 75 },
];

export type ScoreData = (typeof mockScoreData)[number];

const screenWidth = Dimensions.get("window").width;
// IMPORTANT: w-16 = 4rem = 14 (default rem value in nativewind) * 4 = 56
const itemWidth = 56;
Expand All @@ -33,40 +20,67 @@ const DayItem = React.memo(
item,
isSelected,
onPress,
isDark,
}: {
item: ScoreData;
item: ScoresData;
isSelected: boolean;
onPress: () => void;
}) => (
<Pressable onPress={onPress} className="h-20 w-16">
<View className="flex-col items-center gap-1">
<View
className={cn(
"h-6 w-6 items-center justify-center rounded-full",
isSelected && "bg-primary",
)}
>
<Text
isDark: boolean;
}) => {
const date = parseISO(item.date);
const scoreColors = getScoreColors(item.value, isDark);

return (
<Pressable onPress={onPress} className="h-20 w-16">
<View className="flex-col items-center gap-1">
<View
className={cn(
"text-xs font-semibold text-gray-400",
isSelected && "text-secondary",
"h-6 w-6 items-center justify-center rounded-full",
isSelected && "bg-primary",
)}
>
{format(item.date, "EEEEE").toUpperCase()}
</Text>
</View>
<Text
className={cn(
"text-xs font-semibold",
isSelected ? "text-secondary" : "text-gray-400",
)}
>
{format(date, "EEEEE").toUpperCase()}
</Text>
</View>

<View className="h-12 w-12 items-center justify-center rounded-full bg-green-900">
<Text className="text-xl font-semibold">{item.score}</Text>
<View
className="h-12 w-12 items-center justify-center rounded-full"
style={{
backgroundColor: scoreColors.background,
}}
>
<Text
className="text-xl font-semibold"
style={{
color: scoreColors.text,
}}
>
{item.value}
</Text>
</View>
</View>
</View>
</Pressable>
),
</Pressable>
);
},
);

export function DaySlider() {
const { selectedDate, setSelectedDate } = useDateStore();
const listRef = useRef<FlashList<ScoreData> | null>(null);
const listRef = useRef<FlashList<ScoresData> | null>(null);
const { colorScheme } = useColorScheme();
const isDark = colorScheme === "dark";

const sortedData = useMemo(() => {
return [...mockScoresData].sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
);
}, []);

// const scrollToIndex = useCallback((index: number) => {
// listRef.current?.scrollToIndex({
Expand All @@ -85,46 +99,46 @@ export function DaySlider() {
}, []);

const scrollToSelectedDate = useCallback(() => {
const selectedIndex = mockScoreData.findIndex(
(item) => item.date.toDateString() === selectedDate.toDateString(),
const selectedIndex = sortedData.findIndex(
(item) =>
parseISO(item.date).toDateString() === selectedDate.toDateString(),
);

if (selectedIndex !== -1) {
// scrollToIndex(selectedIndex);
scrollToOffset(selectedIndex);
}
}, [selectedDate, scrollToOffset]);
}, [selectedDate, scrollToOffset, sortedData]);

useEffect(() => {
scrollToSelectedDate();
}, [selectedDate, scrollToSelectedDate]);

const renderItem = useCallback(
({ item }: { item: ScoreData }) => {
({ item }: { item: ScoresData }) => {
const itemDate = parseISO(item.date);
const isSelected =
item.date.toDateString() === selectedDate.toDateString();
itemDate.toDateString() === selectedDate.toDateString();
return (
<DayItem
item={item}
isSelected={isSelected}
onPress={() => {
setSelectedDate(item.date);
setSelectedDate(itemDate);
}}
isDark={isDark}
/>
);
},
[selectedDate, setSelectedDate],
[selectedDate, setSelectedDate, isDark],
);

const keyExtractor = useCallback(
(item: ScoreData) => item.date.toISOString(),
[],
);
const keyExtractor = useCallback((item: ScoresData) => item.date, []);

return (
<FlashList
ref={listRef}
data={mockScoreData}
data={sortedData}
extraData={selectedDate}
renderItem={renderItem}
keyExtractor={keyExtractor}
Expand Down
6 changes: 3 additions & 3 deletions apps/expo/src/components/home/home-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ export default function HomeHeader() {
>
<HomeCalendar />
<DialogFooter className="flex-row-reverse px-4 pb-4">
<Text className="font-semibold" style={{ color: theme.good }}>
<Text className="font-semibold" style={{ color: theme.good.text }}>
{"\u2022 >=70"}
</Text>
<Text className="font-semibold" style={{ color: theme.ok }}>
<Text className="font-semibold" style={{ color: theme.ok.text }}>
{"\u2022 50-69"}
</Text>
<Text className="font-semibold" style={{ color: theme.bad }}>
<Text className="font-semibold" style={{ color: theme.bad.text }}>
{"\u2022 <50"}
</Text>
</DialogFooter>
Expand Down
51 changes: 45 additions & 6 deletions apps/expo/src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
import colors from "tailwindcss/colors";

export const convertHexToRGBA = (hexCode: string, opacity = 1) => {
let hex = hexCode.replace("#", "");

if (hex.length === 3) {
hex = `${hex[0]}${hex[0]}${hex[1]}${hex[1]}${hex[2]}${hex[2]}`;
}

const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);

/* Backward compatibility for whole number based opacity values. */
if (opacity > 1 && opacity <= 100) {
opacity = opacity / 100;
}

return `rgba(${r},${g},${b},${opacity})`;
};

console.log(convertHexToRGBA(colors.green[400], 0.2), "testesset");

export const NAV_THEME = {
light: {
background: "hsl(0 0% 100%)", // background
Expand Down Expand Up @@ -29,9 +50,18 @@ export const CALENDAR_THEME = {
disabled: "rgba(0, 0, 0, .3)",
active: "rgba(0, 0, 0, .1)",
highlight: "rgba(0, 0, 0, .1)",
good: colors.green[500],
ok: colors.yellow[500],
bad: colors.red[500],
good: {
background: convertHexToRGBA(colors.green[500], 0.2),
text: colors.green[500],
},
ok: {
background: convertHexToRGBA(colors.yellow[500], 0.2),
text: colors.yellow[500],
},
bad: {
background: convertHexToRGBA(colors.red[500], 0.2),
text: colors.red[500],
},
},
dark: {
background: colors.gray[900],
Expand All @@ -40,9 +70,18 @@ export const CALENDAR_THEME = {
disabled: "rgba(255, 255, 255, .3)",
active: "rgba(255, 255, 255, .1)",
highlight: "rgba(255, 255, 255, .1)",
good: colors.green[400],
ok: colors.yellow[400],
bad: colors.red[500],
good: {
background: convertHexToRGBA(colors.green[400], 0.2),
text: colors.green[400],
},
ok: {
background: convertHexToRGBA(colors.yellow[400], 0.2),
text: colors.yellow[400],
},
bad: {
background: convertHexToRGBA(colors.red[500], 0.2),
text: colors.red[500],
},
},
};

Expand Down
10 changes: 10 additions & 0 deletions apps/expo/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { ClassValue } from "clsx";
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";

import { CALENDAR_THEME } from "~/lib/constants";

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Expand All @@ -28,3 +30,11 @@ export const getFormattedDateTime = () => {

return `${month}/${day}/${year} ${hours}:${minutes} ${ampm}`;
};

export function getScoreColors(score: number, isDark: boolean) {
const theme = isDark ? CALENDAR_THEME.dark : CALENDAR_THEME.light;

if (score >= 70) return theme.good;
if (score >= 50) return theme.ok;
return theme.bad;
}

0 comments on commit 4bd331e

Please sign in to comment.