feat: Implemented Favouriting for a user

Co-Authored-By: Tadios Temesgen <tt2022@ic.ac.uk>
This commit is contained in:
Caspar Jojo Asaam
2025-06-13 03:36:16 +01:00
parent ba0ae11abd
commit be04f2d869
10 changed files with 249 additions and 38 deletions

View File

@@ -0,0 +1,40 @@
<script lang="ts">
interface Props {
isFavourite: boolean;
onToggleFavourite: () => void;
}
const { isFavourite, onToggleFavourite }: Props = $props();
function handleClick(event: MouseEvent) {
event.preventDefault();
event.stopPropagation();
onToggleFavourite();
}
</script>
<button
type="button"
class="fav-button"
onclick={handleClick}
aria-label="Toggle favourite"
style="color: {isFavourite ? 'red' : '#eaffeb'}"
>
{#if isFavourite}
❤️
{:else}
🤍
{/if}
</button>
<style>
.fav-button {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
display: block;
margin: 0.5rem auto 0;
line-height: 1;
}
</style>

View File

@@ -19,7 +19,7 @@
let openingDisplay = $state("");
if (todayHours) {
openingDisplay = todayHours.open_today_status
? "Open 24/7"
? "Open All Day"
: `${formatTime(todayHours.opens_at)} - ${formatTime(todayHours.closes_at)}`;
} else {
openingDisplay = "Closed";

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import CompulsoryTags from "./CompulsoryTags.svelte";
import OpeningTimes from "./OpeningTimes.svelte";
import Favourite from "./Favourite.svelte";
import type { Table } from "$lib";
interface Props {
@@ -9,13 +10,21 @@
alt: string;
imgSrc: string;
href?: string;
isFavourite: boolean;
onToggleFavourite: () => void;
}
const { space, hours, alt, imgSrc, href }: Props = $props();
const { space, hours, alt, imgSrc, href, isFavourite, onToggleFavourite }: Props = $props();
</script>
<a class="card" {href}>
<img src={imgSrc} {alt} />
<!-- <img src={imgSrc} {alt} /> -->
<div class="image-container">
<img src={imgSrc} {alt} />
<div class="fav-button">
<Favourite {isFavourite} {onToggleFavourite} />
</div>
</div>
<div class="description">
<h1>{space.location}</h1>
<div class="compulsoryContainer"><CompulsoryTags {space} /></div>
@@ -84,4 +93,17 @@
gap: 0.3rem;
font-size: 0.8rem;
}
.image-container {
position: relative;
}
.image-container .fav-button {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: rgba(11, 128, 34, 0.4);
border-radius: 50%;
padding: 0.25rem;
z-index: 1;
}
</style>

36
src/lib/database.d.ts vendored
View File

@@ -202,6 +202,42 @@ export type Database = {
}
Relationships: []
}
favourite_study_spaces: {
Row: {
user_id: string
study_space_id: string
created_at: string | null
updated_at: string | null
}
Insert: {
user_id: string
study_space_id: string
created_at?: string | null
updated_at?: string | null
}
Update: {
user_id?: string
study_space_id?: string
created_at?: string | null
updated_at?: string | null
}
Relationships: [
{
foreignKeyName: "favourite_study_spaces_user_id_fkey"
columns: ["user_id"]
isOneToOne: false
referencedRelation: "users"
referencedColumns: ["id"]
},
{
foreignKeyName: "favourite_study_spaces_study_space_id_fkey"
columns: ["study_space_id"]
isOneToOne: false
referencedRelation: "study_spaces"
referencedColumns: ["id"]
}
]
}
}
Views: {
[_ in never]: never