From 12f9970f0040971b56ecfda33c350303649ae859 Mon Sep 17 00:00:00 2001 From: Kyle Ramachandran Date: Sun, 29 Sep 2024 17:57:33 -0700 Subject: [PATCH 1/4] create supabase client --- api/supabase/createClient.ts | 20 ++++++++++++++++++++ api/supabase/queries/plantSeasonality.ts | 9 +++++++++ 2 files changed, 29 insertions(+) create mode 100644 api/supabase/createClient.ts create mode 100644 api/supabase/queries/plantSeasonality.ts diff --git a/api/supabase/createClient.ts b/api/supabase/createClient.ts new file mode 100644 index 0000000..5389233 --- /dev/null +++ b/api/supabase/createClient.ts @@ -0,0 +1,20 @@ +import { createClient } from '@supabase/supabase-js'; +import dotenv from 'dotenv'; + +dotenv.config(); + +if ( + !process.env.NEXT_PUBLIC_SUPABASE_URL || + !process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY +) { + throw new Error( + 'No Supabase environment variables detected, please make sure they are in place!', + ); +} + +const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, +); + +export default supabase; diff --git a/api/supabase/queries/plantSeasonality.ts b/api/supabase/queries/plantSeasonality.ts new file mode 100644 index 0000000..ec80e53 --- /dev/null +++ b/api/supabase/queries/plantSeasonality.ts @@ -0,0 +1,9 @@ +import { Plant } from '@/types/schema'; +import supabase from '../createClient'; + +export async function getPlantSeasonality(): Promise { + const { data, error } = await supabase.rpc('get_plant_seasonality'); + if (error) + throw new Error(`Error fetching plant seasonality: ${error.message}`); + return data; +} From b268565fb6d5943e61897b48377fdfecd9773361 Mon Sep 17 00:00:00 2001 From: Kyle Ramachandran Date: Sun, 29 Sep 2024 18:44:09 -0700 Subject: [PATCH 2/4] added Plant type --- package.json | 2 + pnpm-lock.yaml | 152 ++++++++++++++++++++++++++++++++++++++++++++++ types/schema.d.ts | 24 ++++++++ 3 files changed, 178 insertions(+) create mode 100644 types/schema.d.ts diff --git a/package.json b/package.json index 2525fd8..66a7b2a 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ }, "dependencies": { "next": "^14.2.10", + "@supabase/supabase-js": "^2.45.4", + "dotenv": "^16.4.5", "react": "^18", "react-dom": "^18", "styled-components": "^6.1.13" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0fb4771..600f359 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,12 @@ settings: importers: .: dependencies: + '@supabase/supabase-js': + specifier: ^2.45.4 + version: 2.45.4 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 next: specifier: ^14.2.10 version: 14.2.13(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -446,6 +452,49 @@ packages: integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==, } + '@supabase/auth-js@2.65.0': + resolution: + { + integrity: sha512-+wboHfZufAE2Y612OsKeVP4rVOeGZzzMLD/Ac3HrTQkkY4qXNjI6Af9gtmxwccE5nFvTiF114FEbIQ1hRq5uUw==, + } + + '@supabase/functions-js@2.4.1': + resolution: + { + integrity: sha512-8sZ2ibwHlf+WkHDUZJUXqqmPvWQ3UHN0W30behOJngVh/qHHekhJLCFbh0AjkE9/FqqXtf9eoVvmYgfCLk5tNA==, + } + + '@supabase/node-fetch@2.6.15': + resolution: + { + integrity: sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==, + } + engines: { node: 4.x || >=6.0.0 } + + '@supabase/postgrest-js@1.16.1': + resolution: + { + integrity: sha512-EOSEZFm5pPuCPGCmLF1VOCS78DfkSz600PBuvBND/IZmMciJ1pmsS3ss6TkB6UkuvTybYiBh7gKOYyxoEO3USA==, + } + + '@supabase/realtime-js@2.10.2': + resolution: + { + integrity: sha512-qyCQaNg90HmJstsvr2aJNxK2zgoKh9ZZA8oqb7UT2LCh3mj9zpa3Iwu167AuyNxsxrUE8eEJ2yH6wLCij4EApA==, + } + + '@supabase/storage-js@2.7.0': + resolution: + { + integrity: sha512-iZenEdO6Mx9iTR6T7wC7sk6KKsoDPLq8rdu5VRy7+JiT1i8fnqfcOr6mfF2Eaqky9VQzhP8zZKQYjzozB65Rig==, + } + + '@supabase/supabase-js@2.45.4': + resolution: + { + integrity: sha512-E5p8/zOLaQ3a462MZnmnz03CrduA5ySH9hZyL03Y+QZLIOO4/Gs8Rdy4ZCKDHsN7x0xdanVEWWFN3pJFQr9/hg==, + } + '@swc/counter@0.1.3': resolution: { @@ -476,6 +525,12 @@ packages: integrity: sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==, } + '@types/phoenix@1.6.5': + resolution: + { + integrity: sha512-xegpDuR+z0UqG9fwHqNoy3rI7JDlvaPh2TY47Fl80oq6g+hXT+c/LEuE43X48clZ6lOfANl5WrPur9fYO1RJ/w==, + } + '@types/prop-types@15.7.12': resolution: { @@ -1000,6 +1055,13 @@ packages: } engines: { node: '>=6.0.0' } + dotenv@16.4.5: + resolution: + { + integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==, + } + engines: { node: '>=12' } + eastasianwidth@0.2.0: resolution: { @@ -2675,6 +2737,12 @@ packages: } engines: { node: '>=8.0' } + tr46@0.0.3: + resolution: + { + integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, + } + ts-api-utils@1.3.0: resolution: { @@ -2779,6 +2847,18 @@ packages: integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, } + webidl-conversions@3.0.1: + resolution: + { + integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, + } + + whatwg-url@5.0.0: + resolution: + { + integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, + } + which-boxed-primitive@1.0.2: resolution: { @@ -2841,6 +2921,21 @@ packages: integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, } + ws@8.18.0: + resolution: + { + integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==, + } + engines: { node: '>=10.0.0' } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + yallist@3.1.1: resolution: { @@ -3114,6 +3209,48 @@ snapshots: '@rushstack/eslint-patch@1.10.4': {} + '@supabase/auth-js@2.65.0': + dependencies: + '@supabase/node-fetch': 2.6.15 + + '@supabase/functions-js@2.4.1': + dependencies: + '@supabase/node-fetch': 2.6.15 + + '@supabase/node-fetch@2.6.15': + dependencies: + whatwg-url: 5.0.0 + + '@supabase/postgrest-js@1.16.1': + dependencies: + '@supabase/node-fetch': 2.6.15 + + '@supabase/realtime-js@2.10.2': + dependencies: + '@supabase/node-fetch': 2.6.15 + '@types/phoenix': 1.6.5 + '@types/ws': 8.5.12 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@supabase/storage-js@2.7.0': + dependencies: + '@supabase/node-fetch': 2.6.15 + + '@supabase/supabase-js@2.45.4': + dependencies: + '@supabase/auth-js': 2.65.0 + '@supabase/functions-js': 2.4.1 + '@supabase/node-fetch': 2.6.15 + '@supabase/postgrest-js': 1.16.1 + '@supabase/realtime-js': 2.10.2 + '@supabase/storage-js': 2.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.5': @@ -3129,6 +3266,8 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/phoenix@1.6.5': {} + '@types/prop-types@15.7.12': {} '@types/react-dom@18.3.0': @@ -3502,6 +3641,8 @@ snapshots: dependencies: esutils: 2.0.3 + dotenv@16.4.5: {} + eastasianwidth@0.2.0: {} electron-to-chromium@1.5.23: {} @@ -4638,6 +4779,8 @@ snapshots: dependencies: is-number: 7.0.0 + tr46@0.0.3: {} + ts-api-utils@1.3.0(typescript@5.6.2): dependencies: typescript: 5.6.2 @@ -4712,6 +4855,13 @@ snapshots: dependencies: punycode: 2.3.1 + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 @@ -4770,6 +4920,8 @@ snapshots: wrappy@1.0.2: {} + ws@8.18.0: {} + yallist@3.1.1: {} yarnhook@0.6.2: diff --git a/types/schema.d.ts b/types/schema.d.ts new file mode 100644 index 0000000..ba520d3 --- /dev/null +++ b/types/schema.d.ts @@ -0,0 +1,24 @@ +import type { UUID } from 'crypto'; + +export type Season = 'SPRING' | 'SUMMER' | 'FALL' | 'WINTER'; + +export interface Plant { + id: UUID; + plant_name: string; + state: string; + harvest_season: Season; + water_num_times_per_week: number; + plant_seed_indoors_start: string; + plant_seed_indoors_end: string; + plant_seed_outdoors_start: string; + plant_seed_outdoors_end: string; + plant_transplant_start: string; + plant_transplant_end: string; + harvest_start: string; + harvest_end: string; + water_inches_per_week: number; + harvest_days_after_plant: number; + sunlight_required: string; + beginner_friendly: boolean; + plant_tips: string; +} From 5df80896e255f63b05e99403e998e67aabbba41d Mon Sep 17 00:00:00 2001 From: Kyle Ramachandran Date: Sun, 29 Sep 2024 18:45:48 -0700 Subject: [PATCH 3/4] created PlantList type and getPlantSeasonality query --- api/supabase/queries/plantSeasonality.ts | 8 ++++++-- components/PlantList.tsx | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 components/PlantList.tsx diff --git a/api/supabase/queries/plantSeasonality.ts b/api/supabase/queries/plantSeasonality.ts index ec80e53..8fdda29 100644 --- a/api/supabase/queries/plantSeasonality.ts +++ b/api/supabase/queries/plantSeasonality.ts @@ -1,8 +1,12 @@ import { Plant } from '@/types/schema'; import supabase from '../createClient'; -export async function getPlantSeasonality(): Promise { - const { data, error } = await supabase.rpc('get_plant_seasonality'); +export async function getPlantSeasonality( + input_state: string, +): Promise { + const { data, error } = await supabase.rpc('get_plant_seasonality', { + input_state, + }); if (error) throw new Error(`Error fetching plant seasonality: ${error.message}`); return data; diff --git a/components/PlantList.tsx b/components/PlantList.tsx new file mode 100644 index 0000000..7acdd34 --- /dev/null +++ b/components/PlantList.tsx @@ -0,0 +1,24 @@ +import React, { useEffect, useState } from 'react'; +import { getPlantSeasonality } from '@/api/supabase/queries/plantSeasonality'; +import { Plant } from '@/types/schema'; + +export const PlantList = () => { + const [plants, setPlants] = useState([]); + + useEffect(() => { + const fetchPlantSeasonality = async () => { + const plantList = await getPlantSeasonality('Tennessee'); + setPlants(plantList); + }; + + fetchPlantSeasonality(); + }, []); + + return ( +
+ {plants.map((plant, key) => ( +
{plant.plant_name}
+ ))} +
+ ); +}; From 923fbae4d0986aee5639699406404adc85532a24 Mon Sep 17 00:00:00 2001 From: Kyle Ramachandran Date: Mon, 30 Sep 2024 14:09:35 -0700 Subject: [PATCH 4/4] run prettier --- api/supabase/queries/plantSeasonality.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/api/supabase/queries/plantSeasonality.ts b/api/supabase/queries/plantSeasonality.ts index 8fdda29..005f90c 100644 --- a/api/supabase/queries/plantSeasonality.ts +++ b/api/supabase/queries/plantSeasonality.ts @@ -4,9 +4,10 @@ import supabase from '../createClient'; export async function getPlantSeasonality( input_state: string, ): Promise { - const { data, error } = await supabase.rpc('get_plant_seasonality', { - input_state, - }); + const { data, error } = await supabase + .from('plant_seasonality') + .select('*') + .eq('state', input_state); if (error) throw new Error(`Error fetching plant seasonality: ${error.message}`); return data;