Merge pull request #536 from trails-cool/home-statrow-consistency
home: shared StatRow + SportBadge on activity cards
This commit is contained in:
commit
8cacc7d91e
2 changed files with 29 additions and 16 deletions
|
|
@ -8,10 +8,12 @@ import { getSessionUser } from "~/lib/auth/session.server";
|
||||||
import { getDb } from "~/lib/db";
|
import { getDb } from "~/lib/db";
|
||||||
import { credentials } from "@trails-cool/db/schema/journal";
|
import { credentials } from "@trails-cool/db/schema/journal";
|
||||||
import { listActivities, listRecentPublicActivities } from "~/lib/activities.server";
|
import { listActivities, listRecentPublicActivities } from "~/lib/activities.server";
|
||||||
|
import type { SportType } from "@trails-cool/db/schema/journal";
|
||||||
|
|
||||||
export interface HomeActivityCard {
|
export interface HomeActivityCard {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
sportType: SportType | null;
|
||||||
distance: number | null;
|
distance: number | null;
|
||||||
elevationGain: number | null;
|
elevationGain: number | null;
|
||||||
duration: number | null;
|
duration: number | null;
|
||||||
|
|
@ -57,6 +59,7 @@ export async function loadHomeData(request: Request): Promise<HomeLoaderData> {
|
||||||
activities = rows.slice(0, 20).map((a) => ({
|
activities = rows.slice(0, 20).map((a) => ({
|
||||||
id: a.id,
|
id: a.id,
|
||||||
name: a.name,
|
name: a.name,
|
||||||
|
sportType: a.sportType,
|
||||||
distance: a.distance,
|
distance: a.distance,
|
||||||
elevationGain: a.elevationGain,
|
elevationGain: a.elevationGain,
|
||||||
duration: a.duration,
|
duration: a.duration,
|
||||||
|
|
@ -71,6 +74,7 @@ export async function loadHomeData(request: Request): Promise<HomeLoaderData> {
|
||||||
activities = rows.map((a) => ({
|
activities = rows.map((a) => ({
|
||||||
id: a.id,
|
id: a.id,
|
||||||
name: a.name,
|
name: a.name,
|
||||||
|
sportType: a.sportType,
|
||||||
distance: a.distance,
|
distance: a.distance,
|
||||||
elevationGain: a.elevationGain,
|
elevationGain: a.elevationGain,
|
||||||
duration: a.duration,
|
duration: a.duration,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ import { useTranslation } from "react-i18next";
|
||||||
import type { Route } from "./+types/home";
|
import type { Route } from "./+types/home";
|
||||||
import { ClientDate } from "~/components/ClientDate";
|
import { ClientDate } from "~/components/ClientDate";
|
||||||
import { ClientMap } from "~/components/ClientMap";
|
import { ClientMap } from "~/components/ClientMap";
|
||||||
|
import { SportBadge } from "~/components/SportBadge";
|
||||||
|
import { StatRow } from "~/components/StatRow";
|
||||||
|
import { activityStatItems } from "~/lib/stats";
|
||||||
import { loadHomeData } from "./home.server";
|
import { loadHomeData } from "./home.server";
|
||||||
|
|
||||||
export function meta(_args: Route.MetaArgs) {
|
export function meta(_args: Route.MetaArgs) {
|
||||||
|
|
@ -146,15 +149,18 @@ export default function Home({ loaderData }: Route.ComponentProps) {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 flex-col justify-between">
|
<div className="flex flex-1 flex-col justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-lg font-medium text-gray-900">{a.name}</h2>
|
<div className="flex items-center gap-2">
|
||||||
<div className="mt-1 flex gap-4 text-sm text-gray-500">
|
<h2 className="text-lg font-medium text-gray-900">{a.name}</h2>
|
||||||
{a.distance != null && (
|
<SportBadge sportType={a.sportType} />
|
||||||
<span>{(a.distance / 1000).toFixed(1)} km</span>
|
|
||||||
)}
|
|
||||||
{a.elevationGain != null && (
|
|
||||||
<span>↑ {Math.round(a.elevationGain)} m</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
<StatRow
|
||||||
|
className="mt-1"
|
||||||
|
items={activityStatItems(
|
||||||
|
{ distance: a.distance, durationSec: a.duration, sportType: a.sportType },
|
||||||
|
t,
|
||||||
|
{ compact: true },
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-gray-400">
|
<span className="text-sm text-gray-400">
|
||||||
<ClientDate iso={a.startedAt ?? a.createdAt} />
|
<ClientDate iso={a.startedAt ?? a.createdAt} />
|
||||||
|
|
@ -266,7 +272,10 @@ export default function Home({ loaderData }: Route.ComponentProps) {
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 flex-col justify-between">
|
<div className="flex flex-1 flex-col justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="text-base font-medium text-gray-900">{a.name}</h3>
|
<div className="flex items-center gap-2">
|
||||||
|
<h3 className="text-base font-medium text-gray-900">{a.name}</h3>
|
||||||
|
<SportBadge sportType={a.sportType} />
|
||||||
|
</div>
|
||||||
<div className="mt-1 text-sm text-gray-500">
|
<div className="mt-1 text-sm text-gray-500">
|
||||||
{a.ownerUsername && (
|
{a.ownerUsername && (
|
||||||
<>
|
<>
|
||||||
|
|
@ -282,14 +291,14 @@ export default function Home({ loaderData }: Route.ComponentProps) {
|
||||||
)}
|
)}
|
||||||
<ClientDate iso={a.startedAt ?? a.createdAt} />
|
<ClientDate iso={a.startedAt ?? a.createdAt} />
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-1 flex gap-4 text-sm text-gray-500">
|
<StatRow
|
||||||
{a.distance != null && (
|
className="mt-1"
|
||||||
<span>{(a.distance / 1000).toFixed(1)} km</span>
|
items={activityStatItems(
|
||||||
|
{ distance: a.distance, durationSec: a.duration, sportType: a.sportType },
|
||||||
|
t,
|
||||||
|
{ compact: true },
|
||||||
)}
|
)}
|
||||||
{a.elevationGain != null && (
|
/>
|
||||||
<span>↑ {Math.round(a.elevationGain)} m</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue