-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from GouravNG/supabaseMigration
Supabase migration
- Loading branch information
Showing
19 changed files
with
890 additions
and
516 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const env = process.env.DOMAIN | ||
|
||
export const postRecipeURL = `${env}/rest/v1/recipe` | ||
export const postInstructionURL = `${env}/rest/v1/instruction` | ||
export const postIngredientsURL = `${env}/rest/v1/ingredient` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
"use client" | ||
|
||
import * as React from "react" | ||
import * as ToastPrimitives from "@radix-ui/react-toast" | ||
import { cva, type VariantProps } from "class-variance-authority" | ||
import { X } from "lucide-react" | ||
|
||
import { cn } from "@/lib/utils" | ||
|
||
const ToastProvider = ToastPrimitives.Provider | ||
|
||
const ToastViewport = React.forwardRef< | ||
React.ElementRef<typeof ToastPrimitives.Viewport>, | ||
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport> | ||
>(({ className, ...props }, ref) => ( | ||
<ToastPrimitives.Viewport | ||
ref={ref} | ||
className={cn( | ||
"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
)) | ||
ToastViewport.displayName = ToastPrimitives.Viewport.displayName | ||
|
||
const toastVariants = cva( | ||
"group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full", | ||
{ | ||
variants: { | ||
variant: { | ||
default: "border bg-background text-foreground", | ||
destructive: | ||
"destructive group border-destructive bg-destructive text-destructive-foreground", | ||
}, | ||
}, | ||
defaultVariants: { | ||
variant: "default", | ||
}, | ||
} | ||
) | ||
|
||
const Toast = React.forwardRef< | ||
React.ElementRef<typeof ToastPrimitives.Root>, | ||
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> & | ||
VariantProps<typeof toastVariants> | ||
>(({ className, variant, ...props }, ref) => { | ||
return ( | ||
<ToastPrimitives.Root | ||
ref={ref} | ||
className={cn(toastVariants({ variant }), className)} | ||
{...props} | ||
/> | ||
) | ||
}) | ||
Toast.displayName = ToastPrimitives.Root.displayName | ||
|
||
const ToastAction = React.forwardRef< | ||
React.ElementRef<typeof ToastPrimitives.Action>, | ||
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action> | ||
>(({ className, ...props }, ref) => ( | ||
<ToastPrimitives.Action | ||
ref={ref} | ||
className={cn( | ||
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
)) | ||
ToastAction.displayName = ToastPrimitives.Action.displayName | ||
|
||
const ToastClose = React.forwardRef< | ||
React.ElementRef<typeof ToastPrimitives.Close>, | ||
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close> | ||
>(({ className, ...props }, ref) => ( | ||
<ToastPrimitives.Close | ||
ref={ref} | ||
className={cn( | ||
"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600", | ||
className | ||
)} | ||
toast-close="" | ||
{...props} | ||
> | ||
<X className="h-4 w-4" /> | ||
</ToastPrimitives.Close> | ||
)) | ||
ToastClose.displayName = ToastPrimitives.Close.displayName | ||
|
||
const ToastTitle = React.forwardRef< | ||
React.ElementRef<typeof ToastPrimitives.Title>, | ||
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title> | ||
>(({ className, ...props }, ref) => ( | ||
<ToastPrimitives.Title | ||
ref={ref} | ||
className={cn("text-sm font-semibold", className)} | ||
{...props} | ||
/> | ||
)) | ||
ToastTitle.displayName = ToastPrimitives.Title.displayName | ||
|
||
const ToastDescription = React.forwardRef< | ||
React.ElementRef<typeof ToastPrimitives.Description>, | ||
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description> | ||
>(({ className, ...props }, ref) => ( | ||
<ToastPrimitives.Description | ||
ref={ref} | ||
className={cn("text-sm opacity-90", className)} | ||
{...props} | ||
/> | ||
)) | ||
ToastDescription.displayName = ToastPrimitives.Description.displayName | ||
|
||
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast> | ||
|
||
type ToastActionElement = React.ReactElement<typeof ToastAction> | ||
|
||
export { | ||
type ToastProps, | ||
type ToastActionElement, | ||
ToastProvider, | ||
ToastViewport, | ||
Toast, | ||
ToastTitle, | ||
ToastDescription, | ||
ToastClose, | ||
ToastAction, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
"use client" | ||
|
||
import { useToast } from "@/components/hooks/use-toast" | ||
import { | ||
Toast, | ||
ToastClose, | ||
ToastDescription, | ||
ToastProvider, | ||
ToastTitle, | ||
ToastViewport, | ||
} from "@/components/ui/toast" | ||
|
||
export function Toaster() { | ||
const { toasts } = useToast() | ||
|
||
return ( | ||
<ToastProvider> | ||
{toasts.map(function ({ id, title, description, action, ...props }) { | ||
return ( | ||
<Toast key={id} {...props}> | ||
<div className="grid gap-1"> | ||
{title && <ToastTitle>{title}</ToastTitle>} | ||
{description && ( | ||
<ToastDescription>{description}</ToastDescription> | ||
)} | ||
</div> | ||
{action} | ||
<ToastClose /> | ||
</Toast> | ||
) | ||
})} | ||
<ToastViewport /> | ||
</ToastProvider> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,86 @@ | ||
Table User { | ||
id UUID [pk, unique, not null] | ||
username String [not null, unique] | ||
email String [not null, unique] | ||
password String [not null] | ||
created_at Timestamp [not null, default: `now()`] | ||
updated_at Timestamp [not null, default: `now()`] | ||
} | ||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; | ||
|
||
Table Recipe { | ||
id UUID [pk, unique, not null] | ||
title String [not null] | ||
description Text | ||
servings Integer [not null] | ||
prep_time Integer [not null] // in minutes | ||
cook_time Integer [not null] // in minutes | ||
main_img String [not null] // URL or path to the main image | ||
main_img_alt String // Alt text for the main image | ||
created_at Timestamp [not null, default: `now()`] | ||
updated_at Timestamp [not null, default: `now()`] | ||
user_id UUID [not null, ref: > User.id] | ||
category_id UUID [not null, ref: > Category.id] // References a category (can be main or sub) | ||
} | ||
CREATE TABLE | ||
public.category ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
NAME TEXT NOT NULL UNIQUE, | ||
description TEXT, | ||
parent_id UUID REFERENCES public.category (id) ON DELETE SET NULL, | ||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
Table Category { | ||
id UUID [pk, unique, not null] | ||
name String [not null, unique] | ||
description Text | ||
parent_id UUID [ref: > Category.id] // Self-referential foreign key for subcategories | ||
created_at Timestamp [not null, default: `now()`] | ||
updated_at Timestamp [not null, default: `now()`] | ||
} | ||
CREATE TABLE | ||
public.user ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
username TEXT NOT NULL UNIQUE, | ||
email TEXT NOT NULL UNIQUE, | ||
PASSWORD TEXT NOT NULL, | ||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
Table Ingredient { | ||
id UUID [pk, unique, not null] | ||
name String [not null] | ||
quantity String [not null] // e.g., "1 cup", "2 tbsp" | ||
recipe_id UUID [not null, ref: > Recipe.id] | ||
} | ||
CREATE TABLE | ||
public.recipe ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
NAME TEXT NOT NULL, | ||
description TEXT, | ||
preview TEXT, | ||
servings INTEGER NOT NULL, | ||
prep_time TEXT NOT NULL, | ||
cook_time TEXT NOT NULL, | ||
main_img TEXT NOT NULL, | ||
main_img_alt TEXT, | ||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
user_id UUID NOT NULL REFERENCES public.user (id), | ||
category_id UUID NOT NULL REFERENCES public.category (id) | ||
); | ||
|
||
Table RecipeImage { | ||
id UUID [pk, unique, not null] | ||
image_url String [not null] // URL or path to the image | ||
alt_text String // Alt text for the image | ||
recipe_id UUID [not null, ref: > Recipe.id] | ||
} | ||
CREATE TABLE | ||
public.recipeimage ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
image_url TEXT NOT NULL, | ||
alt_text TEXT, | ||
recipe_id UUID NOT NULL REFERENCES public.recipe (id) ON DELETE CASCADE | ||
); | ||
|
||
Table Instruction { | ||
id UUID [pk, unique, not null] | ||
step_number Integer [not null] | ||
description Text [not null] | ||
image_id UUID [ref: > RecipeImage.id] // Optional image for this step | ||
recipe_id UUID [not null, ref: > Recipe.id] | ||
} | ||
CREATE TABLE | ||
public.ingredient ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
NAME TEXT NOT NULL, | ||
quantity TEXT NOT NULL, | ||
recipe_id UUID NOT NULL REFERENCES public.recipe (id) ON DELETE CASCADE | ||
); | ||
|
||
Table Like { | ||
id UUID [pk, unique, not null] | ||
user_id UUID [not null, ref: > User.id] | ||
recipe_id UUID [not null, ref: > Recipe.id] | ||
created_at Timestamp [not null, default: `now()`] | ||
} | ||
CREATE TABLE | ||
public.instruction ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
step_number INTEGER NOT NULL, | ||
description TEXT NOT NULL, | ||
image_id UUID REFERENCES public.recipeimage (id) ON DELETE SET NULL, | ||
recipe_id UUID NOT NULL REFERENCES public.recipe (id) ON DELETE CASCADE | ||
); | ||
|
||
Table Review { | ||
id UUID [pk, unique, not null] | ||
user_id UUID [not null, ref: > User.id] | ||
recipe_id UUID [not null, ref: > Recipe.id] | ||
rating Integer [not null] // Star rating out of 5 | ||
review_text Text // Actual review text | ||
created_at Timestamp [not null, default: `now()`] | ||
updated_at Timestamp [not null, default: `now()`] | ||
} | ||
CREATE TABLE | ||
public.like ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
user_id UUID NOT NULL REFERENCES public.user (id), | ||
recipe_id UUID NOT NULL REFERENCES public.recipe (id), | ||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
UNIQUE (user_id, recipe_id) | ||
); | ||
|
||
CREATE TABLE | ||
public.review ( | ||
id UUID NOT NULL DEFAULT uuid_generate_v4 () PRIMARY KEY, | ||
user_id UUID NOT NULL REFERENCES public.user (id), | ||
recipe_id UUID NOT NULL REFERENCES public.recipe (id), | ||
rating INTEGER NOT NULL CHECK ( | ||
rating >= 1 | ||
AND rating <= 5 | ||
), | ||
review_text TEXT, | ||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP | ||
); |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.