Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add visited places in profile #147

Merged
merged 3 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions src/app/[locale]/(app)/profile/_components/tabs/saved-tab.tsx

This file was deleted.

29 changes: 29 additions & 0 deletions src/app/[locale]/(app)/profile/_components/tabs/visited-tab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useLocale, useTranslations } from 'next-intl'
import { FC } from 'react'
import { onlyTranslatableLocales } from '~/i18n'
import { trpc } from '~/trpc'
import { PlaceList } from '../../../explore/_components/place-list'

export const VisitedTab: FC = () => {
const t = useTranslations('profile.tabs.visited')
const locale = useLocale()
const { data: places } = trpc.placeLists.getVisitedPlaces.useQuery({
locale: onlyTranslatableLocales(locale),
})

return (
<>
<h2 className="text-center font-title font-medium">
{t('visited-places')}
</h2>

{!places ? (
<p className="mt-2 text-center text-gray-400">{t('loading')}</p>
) : places.length === 0 ? (
<p className="mt-2 text-center text-gray-400">{t('no-places')}</p>
) : (
<PlaceList places={places} />
)}
</>
)
}
11 changes: 6 additions & 5 deletions src/app/[locale]/(app)/profile/_components/user-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { FC } from 'react'
import { useCreateUrl } from '~/helpers/useCreateUrl'
import { JournalTab } from './tabs/journal-tab'
import { MeritsTab } from './tabs/merits-tab'
import { SavedTab } from './tabs/saved-tab'
import { VisitedTab } from './tabs/visited-tab'

export const UserTabs: FC = () => {
const t = useTranslations('profile.tabs')
Expand All @@ -35,10 +35,10 @@ export const UserTabs: FC = () => {
content: JournalTab,
},
{
key: 'saved',
key: 'visited',
icon: IconBookmark,
title: t('saved.tab-title'),
content: SavedTab,
title: t('visited.tab-title'),
content: VisitedTab,
},
]

Expand All @@ -52,6 +52,7 @@ export const UserTabs: FC = () => {
classNames={{
tabList: 'w-full p-0 overflow-visible mx-auto max-w-2xl',
tabContent: 'group-data-[selected=true]:font-semibold',
panel: 'p-0',
}}
items={tabs}
>
Expand All @@ -70,7 +71,7 @@ export const UserTabs: FC = () => {
}
href={createUrlWithSearchParams({ tab: item.key })}
>
<main className="mx-auto w-full max-w-2xl px-6 py-3">
<main className="mx-auto w-full max-w-2xl py-3">
<Content />
</main>
</Tab>
Expand Down
8 changes: 5 additions & 3 deletions src/messages/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,11 @@
"tab-title": "Diari",
"under-construction": "Pàgina en construcció..."
},
"saved": {
"tab-title": "Guardats",
"under-construction": "Pàgina en construcció..."
"visited": {
"tab-title": "Visitats",
"visited-places": "Llocs visitats",
"no-places": "Encara no has visitat cap lloc",
"loading": "Carregant llocs visitats..."
}
}
},
Expand Down
8 changes: 5 additions & 3 deletions src/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,11 @@
"tab-title": "Journal",
"under-construction": "Page under construction..."
},
"saved": {
"tab-title": "Saved",
"under-construction": "Page under construction..."
"visited": {
"tab-title": "Visited",
"visited-places": "Visited places",
"no-places": "No places saved",
"loading": "Loading saved places..."
}
}
},
Expand Down
6 changes: 6 additions & 0 deletions src/schemas/placeLists.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { z } from 'zod'
import { translatableLocales } from '~/i18n'

export const addToVisitedPlacesListSchema = z.object({
placeId: z.number().int().min(0).optional(),
})

export const getVisitedPlacesSchema = z.object({
locale: z.enum(translatableLocales).nullable(),
})

export type AddToVisitedPlacesListSchemaType = z.infer<
typeof addToVisitedPlacesListSchema
>
export type GetVisitedPlacesSchemaType = z.infer<typeof getVisitedPlacesSchema>
79 changes: 77 additions & 2 deletions src/server/api/router/placeLists.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import 'server-only'

import { sql } from 'drizzle-orm'
import { addToVisitedPlacesListSchema } from '~/schemas/placeLists'
import { calculateLocation } from '~/helpers/spatial-data'
import {
addToVisitedPlacesListSchema,
getVisitedPlacesSchema,
} from '~/schemas/placeLists'
import { db } from '~/server/db/db'
import { placeListToPlace } from '~/server/db/schema'
import { placeListToPlace, places } from '~/server/db/schema'
import { getVisitedPlaceListIdByUserId } from '~/server/helpers/db-queries/placeLists'
import { selectPoint } from '~/server/helpers/spatial-data'
import {
flattenTranslationsOnExecute,
withTranslations,
} from '~/server/helpers/translations/query/with-translations'
import { protectedProcedure, router } from '~/server/trpc'

const addToPlaceList = db
Expand All @@ -15,6 +24,54 @@ const addToPlaceList = db
})
.prepare()

const getPlacesFromPlaceListQuery = flattenTranslationsOnExecute(
db.query.placeListToPlace
.findMany({
columns: {
addedAt: true,
},
where: (placeList, { eq }) =>
eq(placeList.placeListId, sql.placeholder('placeListId')),

with: {
place: withTranslations({
columns: {
id: true,
mainImage: true,
name: true,
description: true,
},
extras: {
location: selectPoint('location', places.location),
},
with: {
categories: {
columns: {},
with: {
category: withTranslations({
columns: {
id: true,
icon: true,
name: true,
},
}),
},
},
mainCategory: withTranslations({
columns: {
id: true,
icon: true,
color: true,
name: true,
},
}),
},
}),
},
})
.prepare()
)

export const placeListsRouter = router({
addToVisitedPlacesList: protectedProcedure
.input(addToVisitedPlacesListSchema)
Expand All @@ -28,4 +85,22 @@ export const placeListsRouter = router({
placeId: input.placeId,
})
}),

getVisitedPlaces: protectedProcedure
.input(getVisitedPlacesSchema)
.query(async ({ input, ctx }) => {
const visitedPlaceListId = await getVisitedPlaceListIdByUserId(
ctx.session.user.id
)

const result = await getPlacesFromPlaceListQuery.execute({
locale: input.locale,
placeListId: visitedPlaceListId,
})

return result.map(({ addedAt, place }) => ({
...calculateLocation(place),
addedAt,
}))
}),
})
12 changes: 12 additions & 0 deletions src/server/db/schema/placeLists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
timestamp,
} from 'drizzle-orm/mysql-core'
import { userIdColumnType } from '../utilities'
import { places } from './places'
import { users } from './users'

export const placeLists = mysqlTable('placeList', {
Expand Down Expand Up @@ -37,3 +38,14 @@ export const placeListRelations = relations(placeLists, (r) => ({
references: [users.id],
}),
}))

export const placeListToPlaceRelations = relations(placeListToPlace, (r) => ({
place: r.one(places, {
fields: [placeListToPlace.placeId],
references: [places.id],
}),
placeList: r.one(placeLists, {
fields: [placeListToPlace.placeListId],
references: [placeLists.id],
}),
}))