feat: added migration for a study_space_hours table and allowed for the user to make time inputs when submitting a new space
Co-Authored-By: Tadios Temesgen <tt2022@ic.ac.uk>
This commit is contained in:
41
src/lib/database.d.ts
vendored
41
src/lib/database.d.ts
vendored
@@ -140,6 +140,47 @@ export type Database = {
|
|||||||
}
|
}
|
||||||
Relationships: []
|
Relationships: []
|
||||||
}
|
}
|
||||||
|
study_space_hours: {
|
||||||
|
Row: {
|
||||||
|
id: string
|
||||||
|
study_space_id: string
|
||||||
|
day_of_week: number
|
||||||
|
opens_at: string
|
||||||
|
closes_at: string
|
||||||
|
is_24_7: boolean
|
||||||
|
created_at: string | null
|
||||||
|
updated_at: string | null
|
||||||
|
}
|
||||||
|
Insert: {
|
||||||
|
id?: string
|
||||||
|
study_space_id: string
|
||||||
|
day_of_week: number
|
||||||
|
opens_at: string
|
||||||
|
closes_at: string
|
||||||
|
is_24_7: boolean
|
||||||
|
created_at?: string | null
|
||||||
|
updated_at?: string | null
|
||||||
|
}
|
||||||
|
Update: {
|
||||||
|
id?: string
|
||||||
|
study_space_id?: string
|
||||||
|
day_of_week?: number
|
||||||
|
opens_at?: string
|
||||||
|
closes_at?: string
|
||||||
|
is_24_7?: boolean
|
||||||
|
created_at?: string | null
|
||||||
|
updated_at?: string | null
|
||||||
|
}
|
||||||
|
Relationships: [
|
||||||
|
{
|
||||||
|
foreignKeyName: "study_space_hours_study_space_id_fkey"
|
||||||
|
columns: ["study_space_id"]
|
||||||
|
isOneToOne: false
|
||||||
|
referencedRelation: "study_spaces"
|
||||||
|
referencedColumns: ["id"]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Views: {
|
Views: {
|
||||||
[_ in never]: never
|
[_ in never]: never
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ type StudySpaceData = Omit<
|
|||||||
> & {
|
> & {
|
||||||
id?: string;
|
id?: string;
|
||||||
building_location?: google.maps.places.PlaceResult;
|
building_location?: google.maps.places.PlaceResult;
|
||||||
|
opening_times?: {
|
||||||
|
day_of_week: number;
|
||||||
|
opens_at: string;
|
||||||
|
closes_at: string;
|
||||||
|
is_24_7: boolean;
|
||||||
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ params, locals: { supabase } }) => {
|
export const load: PageServerLoad = async ({ params, locals: { supabase } }) => {
|
||||||
@@ -34,6 +40,13 @@ export const load: PageServerLoad = async ({ params, locals: { supabase } }) =>
|
|||||||
const studySpaceData = space as StudySpaceData & Partial<typeof space>;
|
const studySpaceData = space as StudySpaceData & Partial<typeof space>;
|
||||||
|
|
||||||
const images = studySpaceData.study_space_images || [];
|
const images = studySpaceData.study_space_images || [];
|
||||||
|
const { data: hours, error: hoursErr } = await supabase
|
||||||
|
.from("study_space_hours")
|
||||||
|
.select("day_of_week, opens_at, closes_at, is_24_7")
|
||||||
|
.eq("study_space_id", params.id)
|
||||||
|
.order("day_of_week", { ascending: true });
|
||||||
|
if (hoursErr) error(500, "Failed to load opening times");
|
||||||
|
studySpaceData.opening_times = hours;
|
||||||
|
|
||||||
delete studySpaceData.created_at;
|
delete studySpaceData.created_at;
|
||||||
delete studySpaceData.updated_at;
|
delete studySpaceData.updated_at;
|
||||||
|
|||||||
@@ -20,10 +20,35 @@
|
|||||||
const { supabase } = $derived(data);
|
const { supabase } = $derived(data);
|
||||||
|
|
||||||
const { space, images } = $derived(data);
|
const { space, images } = $derived(data);
|
||||||
const studySpaceData = $derived({
|
// Days of week for opening times
|
||||||
|
const daysOfWeek = [
|
||||||
|
"Sunday",
|
||||||
|
"Monday",
|
||||||
|
"Tuesday",
|
||||||
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday"
|
||||||
|
];
|
||||||
|
const studySpaceData = $state({
|
||||||
|
opening_times: daysOfWeek.map((_, index) => ({
|
||||||
|
day_of_week: index,
|
||||||
|
opens_at: "",
|
||||||
|
closes_at: "",
|
||||||
|
is_24_7: false
|
||||||
|
})),
|
||||||
...space
|
...space
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (!space) return;
|
||||||
|
const { opening_times, ...rest } = space;
|
||||||
|
Object.assign(studySpaceData, rest);
|
||||||
|
if (opening_times) {
|
||||||
|
studySpaceData.opening_times = opening_times;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let scrollPosition = $state(0);
|
let scrollPosition = $state(0);
|
||||||
const existingImages = $derived(
|
const existingImages = $derived(
|
||||||
Promise.all(
|
Promise.all(
|
||||||
@@ -46,11 +71,13 @@
|
|||||||
if (!spaceImgs || spaceImgs.length < 1) return alert("Please select an image file.");
|
if (!spaceImgs || spaceImgs.length < 1) return alert("Please select an image file.");
|
||||||
if (!studySpaceData.building_location) return alert("Please select a building location.");
|
if (!studySpaceData.building_location) return alert("Please select a building location.");
|
||||||
|
|
||||||
|
const { opening_times, ...spacePayload } = studySpaceData;
|
||||||
|
|
||||||
const { data: studySpaceInsert, error: studySpaceError } = await supabase
|
const { data: studySpaceInsert, error: studySpaceError } = await supabase
|
||||||
.from("study_spaces")
|
.from("study_spaces")
|
||||||
.upsert(
|
.upsert(
|
||||||
{
|
{
|
||||||
...studySpaceData,
|
...spacePayload,
|
||||||
building_location: studySpaceData.building_location as Json
|
building_location: studySpaceData.building_location as Json
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -102,6 +129,23 @@
|
|||||||
.select();
|
.select();
|
||||||
if (imageInsertError) return alert(`Error creating image: ${imageInsertError.message}`);
|
if (imageInsertError) return alert(`Error creating image: ${imageInsertError.message}`);
|
||||||
|
|
||||||
|
const { error: deleteErr } = await supabase
|
||||||
|
.from("study_space_hours")
|
||||||
|
.delete()
|
||||||
|
.eq("study_space_id", studySpaceInsert.id);
|
||||||
|
if (deleteErr) return alert(`Error clearing old hours: ${deleteErr.message}`);
|
||||||
|
|
||||||
|
const { error: hoursErr } = await supabase.from("study_space_hours").insert(
|
||||||
|
opening_times.map((h) => ({
|
||||||
|
study_space_id: studySpaceInsert.id,
|
||||||
|
day_of_week: h.day_of_week,
|
||||||
|
opens_at: h.opens_at,
|
||||||
|
closes_at: h.closes_at,
|
||||||
|
is_24_7: h.is_24_7
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
if (hoursErr) return alert(`Error saving opening times: ${hoursErr.message}`);
|
||||||
|
|
||||||
alert("Thank you for your contribution!");
|
alert("Thank you for your contribution!");
|
||||||
// Redirect to the new study space page
|
// Redirect to the new study space page
|
||||||
await goto(`/space/${studySpaceInsert.id}`, {
|
await goto(`/space/${studySpaceInsert.id}`, {
|
||||||
@@ -254,6 +298,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<label for="opening-times-label">Opening Times:</label>
|
||||||
|
<div class="opening-times">
|
||||||
|
{#each daysOfWeek as day, index (index)}
|
||||||
|
<div class="opening-time-item">
|
||||||
|
<label for={"opens-" + index}>{day}</label>
|
||||||
|
<input
|
||||||
|
id={"opens-" + index}
|
||||||
|
type="time"
|
||||||
|
bind:value={studySpaceData.opening_times[index].opens_at}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<span>to</span>
|
||||||
|
<input
|
||||||
|
id={"closes-" + index}
|
||||||
|
type="time"
|
||||||
|
bind:value={studySpaceData.opening_times[index].closes_at}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<label for={"is247-" + index}>
|
||||||
|
<input
|
||||||
|
id={"is247-" + index}
|
||||||
|
type="checkbox"
|
||||||
|
bind:checked={studySpaceData.opening_times[index].is_24_7}
|
||||||
|
/>
|
||||||
|
24/7
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
<label for="tags">Additional tags:</label>
|
<label for="tags">Additional tags:</label>
|
||||||
<div class="tagDisplay">
|
<div class="tagDisplay">
|
||||||
{#each studySpaceData.tags as tagName (tagName)}
|
{#each studySpaceData.tags as tagName (tagName)}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
CREATE TABLE study_space_hours (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
study_space_id UUID REFERENCES study_spaces(id) ON DELETE CASCADE,
|
||||||
|
day_of_week INT CHECK (day_of_week BETWEEN 0 AND 6), -- 0 = Sunday, 6 = Saturday
|
||||||
|
opens_at TIME NOT NULL,
|
||||||
|
closes_at TIME NOT NULL,
|
||||||
|
is_24_7 BOOLEAN DEFAULT FALSE,
|
||||||
|
created_at timestamp with time zone DEFAULT now(),
|
||||||
|
updated_at timestamp with time zone DEFAULT now()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER study_space_hours_updated_at
|
||||||
|
AFTER UPDATE ON study_space_hours
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION handle_updated_at();
|
||||||
@@ -18,6 +18,7 @@ CREATE TABLE study_spaces (
|
|||||||
volume text NOT NULL,
|
volume text NOT NULL,
|
||||||
wifi text NOT NULL,
|
wifi text NOT NULL,
|
||||||
power text NOT NULL,
|
power text NOT NULL,
|
||||||
|
|
||||||
created_at timestamp with time zone DEFAULT now(),
|
created_at timestamp with time zone DEFAULT now(),
|
||||||
updated_at timestamp with time zone DEFAULT now()
|
updated_at timestamp with time zone DEFAULT now()
|
||||||
);
|
);
|
||||||
@@ -39,6 +40,17 @@ CREATE TABLE reports (
|
|||||||
content text
|
content text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE study_space_hours (
|
||||||
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
study_space_id UUID REFERENCES study_spaces(id) ON DELETE CASCADE,
|
||||||
|
day_of_week INT CHECK (day_of_week BETWEEN 0 AND 6), -- 0 = Sunday, 6 = Saturday
|
||||||
|
opens_at TIME NOT NULL,
|
||||||
|
closes_at TIME NOT NULL,
|
||||||
|
is_24_7 BOOLEAN DEFAULT FALSE,
|
||||||
|
created_at timestamp with time zone DEFAULT now(),
|
||||||
|
updated_at timestamp with time zone DEFAULT now()
|
||||||
|
);
|
||||||
|
|
||||||
-- Triggers
|
-- Triggers
|
||||||
CREATE TRIGGER study_spaces_updated_at
|
CREATE TRIGGER study_spaces_updated_at
|
||||||
AFTER UPDATE ON study_spaces
|
AFTER UPDATE ON study_spaces
|
||||||
@@ -51,3 +63,7 @@ FOR EACH ROW EXECUTE FUNCTION handle_updated_at();
|
|||||||
CREATE TRIGGER reports_updated_at
|
CREATE TRIGGER reports_updated_at
|
||||||
AFTER UPDATE ON reports
|
AFTER UPDATE ON reports
|
||||||
FOR EACH ROW EXECUTE FUNCTION handle_updated_at();
|
FOR EACH ROW EXECUTE FUNCTION handle_updated_at();
|
||||||
|
|
||||||
|
CREATE TRIGGER study_space_hours_updated_at
|
||||||
|
AFTER UPDATE ON study_space_hours
|
||||||
|
FOR EACH ROW EXECUTE FUNCTION handle_updated_at();
|
||||||
|
|||||||
Reference in New Issue
Block a user