Add sub-categories to affirmation categories

Add self-referential parent/child relation on AffirmationCategory for
   one-level hierarchy. Update AffirmationForm with two-level category and
   sub-category dropdowns, server actions with find-or-create hierarchy
   logic, AffirmationList with Parent
This commit is contained in:
NeilClack
2026-02-23 10:53:15 -06:00
parent a230a1e36d
commit 3c201f9b66
14 changed files with 573 additions and 64 deletions
+11
View File
@@ -11,6 +11,17 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install dependencies
run: npm ci
- name: Run migrations
run: |
set -a
source /mnt/volume_nyc3_01/Portal/.env
set +a
export DO_CA_CERTIFICATE=/etc/ssl/certs/do-ca-certificate.crt
npx prisma migrate deploy
- name: Build image - name: Build image
run: podman build -t portal:latest . run: podman build -t portal:latest .
@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "AffirmationCategory" ADD COLUMN "parentId" INTEGER;
-- AddForeignKey
ALTER TABLE "AffirmationCategory" ADD CONSTRAINT "AffirmationCategory_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "AffirmationCategory"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+5 -2
View File
@@ -128,8 +128,11 @@ model SolfeggioFrequency {
} }
model AffirmationCategory { model AffirmationCategory {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
name String @unique name String @unique
parentId Int?
parent AffirmationCategory? @relation("CategoryHierarchy", fields: [parentId], references: [id])
children AffirmationCategory[] @relation("CategoryHierarchy")
affirmations Affirmation[] affirmations Affirmation[]
} }
+1 -1
View File
@@ -110,7 +110,7 @@
class="flex items-center gap-1 hover:text-gray-900" class="flex items-center gap-1 hover:text-gray-900"
onclick={() => toggleSort(field)} onclick={() => toggleSort(field)}
> >
{fieldNameToLabel(field.includes('.') ? (field.split('.').pop() ?? field) : field)} {fieldNameToLabel(field.includes('.') ? field.split('.')[0] : field)}
<span class="text-xs text-gray-400">{getSortIndicator(field)}</span> <span class="text-xs text-gray-400">{getSortIndicator(field)}</span>
</button> </button>
</th> </th>
@@ -4,6 +4,8 @@
type Category = { type Category = {
id: string; id: string;
name: string; name: string;
parentId?: number | null;
children?: Category[];
}; };
type Frequency = { type Frequency = {
@@ -18,6 +20,7 @@
price?: number; price?: number;
categoryId?: string; categoryId?: string;
solfeggioFrequencyId?: string; solfeggioFrequencyId?: string;
category?: { parentId?: number | null; parent?: { name: string } };
}; };
type FormData = { type FormData = {
@@ -27,6 +30,7 @@
price?: number; price?: number;
categoryId?: string; categoryId?: string;
categoryName?: string; categoryName?: string;
subCategoryName?: string;
solfeggioFrequencyId?: string; solfeggioFrequencyId?: string;
}; };
@@ -48,11 +52,74 @@
submitLabel = 'Save Affirmation' submitLabel = 'Save Affirmation'
}: Props = $props(); }: Props = $props();
const currentCategory = $derived( const topLevelCategories = $derived(categories.filter((c) => !c.parentId));
categories.find((c : Category) => c.id === (form?.categoryId ?? affirmation.categoryId))
);
let categoryInput = $derived(form?.categoryName ?? currentCategory?.name ?? ''); // Determine initial parent category name from form data or existing affirmation
function getInitialCategoryName(): string {
if (form?.categoryName) return form.categoryName;
if (affirmation.category?.parent) return affirmation.category.parent.name;
if (affirmation.categoryId) {
const cat = categories.find((c) => c.id === affirmation.categoryId);
if (cat?.parentId) {
const parent = categories.find((c) => String(c.id) === String(cat.parentId));
return parent?.name ?? '';
}
return cat?.name ?? '';
}
return '';
}
function getInitialSubCategoryName(): string {
if (form?.subCategoryName) return form.subCategoryName;
if (affirmation.categoryId) {
const cat = categories.find((c) => c.id === affirmation.categoryId);
if (cat?.parentId) return cat.name;
}
return '';
}
let categoryInput = $state(getInitialCategoryName());
let showNewCategory = $state(false);
let newCategoryName = $state('');
let subCategoryInput = $state(getInitialSubCategoryName());
let showNewSubCategory = $state(false);
let newSubCategoryName = $state('');
const selectedParent = $derived(topLevelCategories.find((c) => c.name === categoryInput));
const subCategories = $derived(selectedParent?.children ?? []);
function handleCategoryChange(e: Event) {
const value = (e.target as HTMLSelectElement).value;
if (value === '__new__') {
showNewCategory = true;
categoryInput = '';
} else {
showNewCategory = false;
newCategoryName = '';
categoryInput = value;
}
subCategoryInput = '';
showNewSubCategory = false;
newSubCategoryName = '';
}
function handleSubCategoryChange(e: Event) {
const value = (e.target as HTMLSelectElement).value;
if (value === '__new__') {
showNewSubCategory = true;
subCategoryInput = '';
} else {
showNewSubCategory = false;
newSubCategoryName = '';
subCategoryInput = value;
}
}
const effectiveCategoryName = $derived(showNewCategory ? newCategoryName : categoryInput);
const effectiveSubCategoryName = $derived(
showNewSubCategory ? newSubCategoryName : subCategoryInput
);
</script> </script>
<form method="POST" {action} class="space-y-5"> <form method="POST" {action} class="space-y-5">
@@ -60,6 +127,9 @@
<input type="hidden" name="id" value={form?.id ?? affirmation.id} /> <input type="hidden" name="id" value={form?.id ?? affirmation.id} />
{/if} {/if}
<input type="hidden" name="categoryName" value={effectiveCategoryName} />
<input type="hidden" name="subCategoryName" value={effectiveSubCategoryName} />
<div> <div>
<label for="name" class="mb-1 block text-sm font-medium text-gray-700">Name</label> <label for="name" class="mb-1 block text-sm font-medium text-gray-700">Name</label>
<input <input
@@ -102,24 +172,66 @@
</div> </div>
<div> <div>
<label for="categoryName" class="mb-1 block text-sm font-medium text-gray-700">Category</label> <label for="categorySelect" class="mb-1 block text-sm font-medium text-gray-700">
<input Category
type="text" </label>
id="categoryName" <select
name="categoryName" id="categorySelect"
bind:value={categoryInput} onchange={handleCategoryChange}
list="categories" class="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 outline-none transition-shadow focus:border-blue-500 focus:ring-2 focus:ring-blue-500"
required >
class="w-full rounded-lg border border-gray-300 px-3 py-2 outline-none transition-shadow focus:border-blue-500 focus:ring-2 focus:ring-blue-500" <option value="" disabled selected={!categoryInput && !showNewCategory}>
/> Select a category
<datalist id="categories"> </option>
{#each categories as category} {#each topLevelCategories as category}
<option value={category.name}>{category.name}</option> <option value={category.name} selected={category.name === categoryInput}>
{category.name}
</option>
{/each} {/each}
</datalist> <option value="__new__" selected={showNewCategory}>New...</option>
<p class="mt-1 text-sm text-gray-500">Select existing or type to create new</p> </select>
{#if showNewCategory}
<input
type="text"
placeholder="New category name"
bind:value={newCategoryName}
required
class="mt-2 w-full rounded-lg border border-gray-300 px-3 py-2 outline-none transition-shadow focus:border-blue-500 focus:ring-2 focus:ring-blue-500"
/>
{/if}
</div> </div>
{#if categoryInput || showNewCategory}
<div>
<label for="subCategorySelect" class="mb-1 block text-sm font-medium text-gray-700">
Sub-category
</label>
<select
id="subCategorySelect"
onchange={handleSubCategoryChange}
class="w-full rounded-lg border border-gray-300 bg-white px-3 py-2 outline-none transition-shadow focus:border-blue-500 focus:ring-2 focus:ring-blue-500"
>
<option value="" selected={!subCategoryInput && !showNewSubCategory}>None</option>
{#each subCategories as sub}
<option value={sub.name} selected={sub.name === subCategoryInput}>
{sub.name}
</option>
{/each}
<option value="__new__" selected={showNewSubCategory}>New...</option>
</select>
{#if showNewSubCategory}
<input
type="text"
placeholder="New sub-category name"
bind:value={newSubCategoryName}
class="mt-2 w-full rounded-lg border border-gray-300 px-3 py-2 outline-none transition-shadow focus:border-blue-500 focus:ring-2 focus:ring-blue-500"
/>
{/if}
</div>
{/if}
<div> <div>
<label for="price" class="mb-1 block text-sm font-medium text-gray-700">Price</label> <label for="price" class="mb-1 block text-sm font-medium text-gray-700">Price</label>
<div class="relative"> <div class="relative">
@@ -10,9 +10,16 @@
}; };
category?: { category?: {
name: string; name: string;
parent?: { name: string } | null;
}; };
}; };
function categoryDisplayName(category?: Affirmation['category']): string {
if (!category) return '';
if (category.parent) return `${category.parent.name} > ${category.name}`;
return category.name;
}
type SortKey = 'name' | 'category' | 'frequency' | 'price'; type SortKey = 'name' | 'category' | 'frequency' | 'price';
type SortDirection = 'asc' | 'desc'; type SortDirection = 'asc' | 'desc';
@@ -28,7 +35,7 @@
let sortKey = $state<SortKey>('name'); let sortKey = $state<SortKey>('name');
let sortDirection = $state<SortDirection>('asc'); let sortDirection = $state<SortDirection>('asc');
const categories = $derived([...new Set(affirmations.map((a) => a.category?.name).filter(Boolean))].sort()); const categories = $derived([...new Set(affirmations.map((a) => categoryDisplayName(a.category)).filter(Boolean))].sort());
const frequencies = $derived([...new Set(affirmations.map((a) => a.solfeggioFrequency?.name).filter(Boolean))].sort()); const frequencies = $derived([...new Set(affirmations.map((a) => a.solfeggioFrequency?.name).filter(Boolean))].sort());
const filteredAndSorted = $derived(() => { const filteredAndSorted = $derived(() => {
@@ -41,14 +48,14 @@
(a) => (a) =>
a.name.toLowerCase().includes(searchLower) || a.name.toLowerCase().includes(searchLower) ||
a.content.toLowerCase().includes(searchLower) || a.content.toLowerCase().includes(searchLower) ||
a.category?.name.toLowerCase().includes(searchLower) || categoryDisplayName(a.category).toLowerCase().includes(searchLower) ||
a.solfeggioFrequency?.name.toLowerCase().includes(searchLower) a.solfeggioFrequency?.name.toLowerCase().includes(searchLower)
); );
} }
// Category filter // Category filter
if (categoryFilter) { if (categoryFilter) {
result = result.filter((a) => a.category?.name === categoryFilter); result = result.filter((a) => categoryDisplayName(a.category) === categoryFilter);
} }
// Frequency filter // Frequency filter
@@ -67,8 +74,8 @@
bVal = b.name.toLowerCase(); bVal = b.name.toLowerCase();
break; break;
case 'category': case 'category':
aVal = a.category?.name?.toLowerCase() ?? ''; aVal = categoryDisplayName(a.category).toLowerCase();
bVal = b.category?.name?.toLowerCase() ?? ''; bVal = categoryDisplayName(b.category).toLowerCase();
break; break;
case 'frequency': case 'frequency':
aVal = a.solfeggioFrequency?.value ?? 0; aVal = a.solfeggioFrequency?.value ?? 0;
@@ -206,7 +213,7 @@
{#each filteredAndSorted() as affirmation} {#each filteredAndSorted() as affirmation}
<tr class="border-b border-gray-100 hover:bg-gray-50"> <tr class="border-b border-gray-100 hover:bg-gray-50">
<td class="px-4 py-3 font-medium text-gray-900">{affirmation.name}</td> <td class="px-4 py-3 font-medium text-gray-900">{affirmation.name}</td>
<td class="px-4 py-3 text-gray-600">{affirmation.category?.name ?? '—'}</td> <td class="px-4 py-3 text-gray-600">{categoryDisplayName(affirmation.category) || '—'}</td>
<td class="px-4 py-3 text-gray-600">{affirmation.solfeggioFrequency?.name ?? '—'}</td> <td class="px-4 py-3 text-gray-600">{affirmation.solfeggioFrequency?.name ?? '—'}</td>
<td class="px-4 py-3 text-right text-gray-600">${affirmation.price.toFixed(2)}</td> <td class="px-4 py-3 text-right text-gray-600">${affirmation.price.toFixed(2)}</td>
<td class="px-4 py-3 text-right"> <td class="px-4 py-3 text-right">
File diff suppressed because one or more lines are too long
@@ -1381,7 +1381,8 @@ export type SolfeggioFrequencyScalarFieldEnum = (typeof SolfeggioFrequencyScalar
export const AffirmationCategoryScalarFieldEnum = { export const AffirmationCategoryScalarFieldEnum = {
id: 'id', id: 'id',
name: 'name' name: 'name',
parentId: 'parentId'
} as const } as const
export type AffirmationCategoryScalarFieldEnum = (typeof AffirmationCategoryScalarFieldEnum)[keyof typeof AffirmationCategoryScalarFieldEnum] export type AffirmationCategoryScalarFieldEnum = (typeof AffirmationCategoryScalarFieldEnum)[keyof typeof AffirmationCategoryScalarFieldEnum]
@@ -194,7 +194,8 @@ export type SolfeggioFrequencyScalarFieldEnum = (typeof SolfeggioFrequencyScalar
export const AffirmationCategoryScalarFieldEnum = { export const AffirmationCategoryScalarFieldEnum = {
id: 'id', id: 'id',
name: 'name' name: 'name',
parentId: 'parentId'
} as const } as const
export type AffirmationCategoryScalarFieldEnum = (typeof AffirmationCategoryScalarFieldEnum)[keyof typeof AffirmationCategoryScalarFieldEnum] export type AffirmationCategoryScalarFieldEnum = (typeof AffirmationCategoryScalarFieldEnum)[keyof typeof AffirmationCategoryScalarFieldEnum]
@@ -28,50 +28,60 @@ export type AggregateAffirmationCategory = {
export type AffirmationCategoryAvgAggregateOutputType = { export type AffirmationCategoryAvgAggregateOutputType = {
id: number | null id: number | null
parentId: number | null
} }
export type AffirmationCategorySumAggregateOutputType = { export type AffirmationCategorySumAggregateOutputType = {
id: number | null id: number | null
parentId: number | null
} }
export type AffirmationCategoryMinAggregateOutputType = { export type AffirmationCategoryMinAggregateOutputType = {
id: number | null id: number | null
name: string | null name: string | null
parentId: number | null
} }
export type AffirmationCategoryMaxAggregateOutputType = { export type AffirmationCategoryMaxAggregateOutputType = {
id: number | null id: number | null
name: string | null name: string | null
parentId: number | null
} }
export type AffirmationCategoryCountAggregateOutputType = { export type AffirmationCategoryCountAggregateOutputType = {
id: number id: number
name: number name: number
parentId: number
_all: number _all: number
} }
export type AffirmationCategoryAvgAggregateInputType = { export type AffirmationCategoryAvgAggregateInputType = {
id?: true id?: true
parentId?: true
} }
export type AffirmationCategorySumAggregateInputType = { export type AffirmationCategorySumAggregateInputType = {
id?: true id?: true
parentId?: true
} }
export type AffirmationCategoryMinAggregateInputType = { export type AffirmationCategoryMinAggregateInputType = {
id?: true id?: true
name?: true name?: true
parentId?: true
} }
export type AffirmationCategoryMaxAggregateInputType = { export type AffirmationCategoryMaxAggregateInputType = {
id?: true id?: true
name?: true name?: true
parentId?: true
} }
export type AffirmationCategoryCountAggregateInputType = { export type AffirmationCategoryCountAggregateInputType = {
id?: true id?: true
name?: true name?: true
parentId?: true
_all?: true _all?: true
} }
@@ -164,6 +174,7 @@ export type AffirmationCategoryGroupByArgs<ExtArgs extends runtime.Types.Extensi
export type AffirmationCategoryGroupByOutputType = { export type AffirmationCategoryGroupByOutputType = {
id: number id: number
name: string name: string
parentId: number | null
_count: AffirmationCategoryCountAggregateOutputType | null _count: AffirmationCategoryCountAggregateOutputType | null
_avg: AffirmationCategoryAvgAggregateOutputType | null _avg: AffirmationCategoryAvgAggregateOutputType | null
_sum: AffirmationCategorySumAggregateOutputType | null _sum: AffirmationCategorySumAggregateOutputType | null
@@ -192,12 +203,18 @@ export type AffirmationCategoryWhereInput = {
NOT?: Prisma.AffirmationCategoryWhereInput | Prisma.AffirmationCategoryWhereInput[] NOT?: Prisma.AffirmationCategoryWhereInput | Prisma.AffirmationCategoryWhereInput[]
id?: Prisma.IntFilter<"AffirmationCategory"> | number id?: Prisma.IntFilter<"AffirmationCategory"> | number
name?: Prisma.StringFilter<"AffirmationCategory"> | string name?: Prisma.StringFilter<"AffirmationCategory"> | string
parentId?: Prisma.IntNullableFilter<"AffirmationCategory"> | number | null
parent?: Prisma.XOR<Prisma.AffirmationCategoryNullableScalarRelationFilter, Prisma.AffirmationCategoryWhereInput> | null
children?: Prisma.AffirmationCategoryListRelationFilter
affirmations?: Prisma.AffirmationListRelationFilter affirmations?: Prisma.AffirmationListRelationFilter
} }
export type AffirmationCategoryOrderByWithRelationInput = { export type AffirmationCategoryOrderByWithRelationInput = {
id?: Prisma.SortOrder id?: Prisma.SortOrder
name?: Prisma.SortOrder name?: Prisma.SortOrder
parentId?: Prisma.SortOrderInput | Prisma.SortOrder
parent?: Prisma.AffirmationCategoryOrderByWithRelationInput
children?: Prisma.AffirmationCategoryOrderByRelationAggregateInput
affirmations?: Prisma.AffirmationOrderByRelationAggregateInput affirmations?: Prisma.AffirmationOrderByRelationAggregateInput
} }
@@ -207,12 +224,16 @@ export type AffirmationCategoryWhereUniqueInput = Prisma.AtLeast<{
AND?: Prisma.AffirmationCategoryWhereInput | Prisma.AffirmationCategoryWhereInput[] AND?: Prisma.AffirmationCategoryWhereInput | Prisma.AffirmationCategoryWhereInput[]
OR?: Prisma.AffirmationCategoryWhereInput[] OR?: Prisma.AffirmationCategoryWhereInput[]
NOT?: Prisma.AffirmationCategoryWhereInput | Prisma.AffirmationCategoryWhereInput[] NOT?: Prisma.AffirmationCategoryWhereInput | Prisma.AffirmationCategoryWhereInput[]
parentId?: Prisma.IntNullableFilter<"AffirmationCategory"> | number | null
parent?: Prisma.XOR<Prisma.AffirmationCategoryNullableScalarRelationFilter, Prisma.AffirmationCategoryWhereInput> | null
children?: Prisma.AffirmationCategoryListRelationFilter
affirmations?: Prisma.AffirmationListRelationFilter affirmations?: Prisma.AffirmationListRelationFilter
}, "id" | "name"> }, "id" | "name">
export type AffirmationCategoryOrderByWithAggregationInput = { export type AffirmationCategoryOrderByWithAggregationInput = {
id?: Prisma.SortOrder id?: Prisma.SortOrder
name?: Prisma.SortOrder name?: Prisma.SortOrder
parentId?: Prisma.SortOrderInput | Prisma.SortOrder
_count?: Prisma.AffirmationCategoryCountOrderByAggregateInput _count?: Prisma.AffirmationCategoryCountOrderByAggregateInput
_avg?: Prisma.AffirmationCategoryAvgOrderByAggregateInput _avg?: Prisma.AffirmationCategoryAvgOrderByAggregateInput
_max?: Prisma.AffirmationCategoryMaxOrderByAggregateInput _max?: Prisma.AffirmationCategoryMaxOrderByAggregateInput
@@ -226,33 +247,43 @@ export type AffirmationCategoryScalarWhereWithAggregatesInput = {
NOT?: Prisma.AffirmationCategoryScalarWhereWithAggregatesInput | Prisma.AffirmationCategoryScalarWhereWithAggregatesInput[] NOT?: Prisma.AffirmationCategoryScalarWhereWithAggregatesInput | Prisma.AffirmationCategoryScalarWhereWithAggregatesInput[]
id?: Prisma.IntWithAggregatesFilter<"AffirmationCategory"> | number id?: Prisma.IntWithAggregatesFilter<"AffirmationCategory"> | number
name?: Prisma.StringWithAggregatesFilter<"AffirmationCategory"> | string name?: Prisma.StringWithAggregatesFilter<"AffirmationCategory"> | string
parentId?: Prisma.IntNullableWithAggregatesFilter<"AffirmationCategory"> | number | null
} }
export type AffirmationCategoryCreateInput = { export type AffirmationCategoryCreateInput = {
name: string name: string
parent?: Prisma.AffirmationCategoryCreateNestedOneWithoutChildrenInput
children?: Prisma.AffirmationCategoryCreateNestedManyWithoutParentInput
affirmations?: Prisma.AffirmationCreateNestedManyWithoutCategoryInput affirmations?: Prisma.AffirmationCreateNestedManyWithoutCategoryInput
} }
export type AffirmationCategoryUncheckedCreateInput = { export type AffirmationCategoryUncheckedCreateInput = {
id?: number id?: number
name: string name: string
parentId?: number | null
children?: Prisma.AffirmationCategoryUncheckedCreateNestedManyWithoutParentInput
affirmations?: Prisma.AffirmationUncheckedCreateNestedManyWithoutCategoryInput affirmations?: Prisma.AffirmationUncheckedCreateNestedManyWithoutCategoryInput
} }
export type AffirmationCategoryUpdateInput = { export type AffirmationCategoryUpdateInput = {
name?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string
parent?: Prisma.AffirmationCategoryUpdateOneWithoutChildrenNestedInput
children?: Prisma.AffirmationCategoryUpdateManyWithoutParentNestedInput
affirmations?: Prisma.AffirmationUpdateManyWithoutCategoryNestedInput affirmations?: Prisma.AffirmationUpdateManyWithoutCategoryNestedInput
} }
export type AffirmationCategoryUncheckedUpdateInput = { export type AffirmationCategoryUncheckedUpdateInput = {
id?: Prisma.IntFieldUpdateOperationsInput | number id?: Prisma.IntFieldUpdateOperationsInput | number
name?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string
parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null
children?: Prisma.AffirmationCategoryUncheckedUpdateManyWithoutParentNestedInput
affirmations?: Prisma.AffirmationUncheckedUpdateManyWithoutCategoryNestedInput affirmations?: Prisma.AffirmationUncheckedUpdateManyWithoutCategoryNestedInput
} }
export type AffirmationCategoryCreateManyInput = { export type AffirmationCategoryCreateManyInput = {
id?: number id?: number
name: string name: string
parentId?: number | null
} }
export type AffirmationCategoryUpdateManyMutationInput = { export type AffirmationCategoryUpdateManyMutationInput = {
@@ -262,6 +293,7 @@ export type AffirmationCategoryUpdateManyMutationInput = {
export type AffirmationCategoryUncheckedUpdateManyInput = { export type AffirmationCategoryUncheckedUpdateManyInput = {
id?: Prisma.IntFieldUpdateOperationsInput | number id?: Prisma.IntFieldUpdateOperationsInput | number
name?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string
parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null
} }
export type AffirmationCategoryScalarRelationFilter = { export type AffirmationCategoryScalarRelationFilter = {
@@ -269,27 +301,47 @@ export type AffirmationCategoryScalarRelationFilter = {
isNot?: Prisma.AffirmationCategoryWhereInput isNot?: Prisma.AffirmationCategoryWhereInput
} }
export type AffirmationCategoryNullableScalarRelationFilter = {
is?: Prisma.AffirmationCategoryWhereInput | null
isNot?: Prisma.AffirmationCategoryWhereInput | null
}
export type AffirmationCategoryListRelationFilter = {
every?: Prisma.AffirmationCategoryWhereInput
some?: Prisma.AffirmationCategoryWhereInput
none?: Prisma.AffirmationCategoryWhereInput
}
export type AffirmationCategoryOrderByRelationAggregateInput = {
_count?: Prisma.SortOrder
}
export type AffirmationCategoryCountOrderByAggregateInput = { export type AffirmationCategoryCountOrderByAggregateInput = {
id?: Prisma.SortOrder id?: Prisma.SortOrder
name?: Prisma.SortOrder name?: Prisma.SortOrder
parentId?: Prisma.SortOrder
} }
export type AffirmationCategoryAvgOrderByAggregateInput = { export type AffirmationCategoryAvgOrderByAggregateInput = {
id?: Prisma.SortOrder id?: Prisma.SortOrder
parentId?: Prisma.SortOrder
} }
export type AffirmationCategoryMaxOrderByAggregateInput = { export type AffirmationCategoryMaxOrderByAggregateInput = {
id?: Prisma.SortOrder id?: Prisma.SortOrder
name?: Prisma.SortOrder name?: Prisma.SortOrder
parentId?: Prisma.SortOrder
} }
export type AffirmationCategoryMinOrderByAggregateInput = { export type AffirmationCategoryMinOrderByAggregateInput = {
id?: Prisma.SortOrder id?: Prisma.SortOrder
name?: Prisma.SortOrder name?: Prisma.SortOrder
parentId?: Prisma.SortOrder
} }
export type AffirmationCategorySumOrderByAggregateInput = { export type AffirmationCategorySumOrderByAggregateInput = {
id?: Prisma.SortOrder id?: Prisma.SortOrder
parentId?: Prisma.SortOrder
} }
export type AffirmationCategoryCreateNestedOneWithoutAffirmationsInput = { export type AffirmationCategoryCreateNestedOneWithoutAffirmationsInput = {
@@ -306,13 +358,75 @@ export type AffirmationCategoryUpdateOneRequiredWithoutAffirmationsNestedInput =
update?: Prisma.XOR<Prisma.XOR<Prisma.AffirmationCategoryUpdateToOneWithWhereWithoutAffirmationsInput, Prisma.AffirmationCategoryUpdateWithoutAffirmationsInput>, Prisma.AffirmationCategoryUncheckedUpdateWithoutAffirmationsInput> update?: Prisma.XOR<Prisma.XOR<Prisma.AffirmationCategoryUpdateToOneWithWhereWithoutAffirmationsInput, Prisma.AffirmationCategoryUpdateWithoutAffirmationsInput>, Prisma.AffirmationCategoryUncheckedUpdateWithoutAffirmationsInput>
} }
export type AffirmationCategoryCreateNestedOneWithoutChildrenInput = {
create?: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutChildrenInput, Prisma.AffirmationCategoryUncheckedCreateWithoutChildrenInput>
connectOrCreate?: Prisma.AffirmationCategoryCreateOrConnectWithoutChildrenInput
connect?: Prisma.AffirmationCategoryWhereUniqueInput
}
export type AffirmationCategoryCreateNestedManyWithoutParentInput = {
create?: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutParentInput, Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput> | Prisma.AffirmationCategoryCreateWithoutParentInput[] | Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput[]
connectOrCreate?: Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput | Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput[]
createMany?: Prisma.AffirmationCategoryCreateManyParentInputEnvelope
connect?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
}
export type AffirmationCategoryUncheckedCreateNestedManyWithoutParentInput = {
create?: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutParentInput, Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput> | Prisma.AffirmationCategoryCreateWithoutParentInput[] | Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput[]
connectOrCreate?: Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput | Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput[]
createMany?: Prisma.AffirmationCategoryCreateManyParentInputEnvelope
connect?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
}
export type AffirmationCategoryUpdateOneWithoutChildrenNestedInput = {
create?: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutChildrenInput, Prisma.AffirmationCategoryUncheckedCreateWithoutChildrenInput>
connectOrCreate?: Prisma.AffirmationCategoryCreateOrConnectWithoutChildrenInput
upsert?: Prisma.AffirmationCategoryUpsertWithoutChildrenInput
disconnect?: Prisma.AffirmationCategoryWhereInput | boolean
delete?: Prisma.AffirmationCategoryWhereInput | boolean
connect?: Prisma.AffirmationCategoryWhereUniqueInput
update?: Prisma.XOR<Prisma.XOR<Prisma.AffirmationCategoryUpdateToOneWithWhereWithoutChildrenInput, Prisma.AffirmationCategoryUpdateWithoutChildrenInput>, Prisma.AffirmationCategoryUncheckedUpdateWithoutChildrenInput>
}
export type AffirmationCategoryUpdateManyWithoutParentNestedInput = {
create?: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutParentInput, Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput> | Prisma.AffirmationCategoryCreateWithoutParentInput[] | Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput[]
connectOrCreate?: Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput | Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput[]
upsert?: Prisma.AffirmationCategoryUpsertWithWhereUniqueWithoutParentInput | Prisma.AffirmationCategoryUpsertWithWhereUniqueWithoutParentInput[]
createMany?: Prisma.AffirmationCategoryCreateManyParentInputEnvelope
set?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
disconnect?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
delete?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
connect?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
update?: Prisma.AffirmationCategoryUpdateWithWhereUniqueWithoutParentInput | Prisma.AffirmationCategoryUpdateWithWhereUniqueWithoutParentInput[]
updateMany?: Prisma.AffirmationCategoryUpdateManyWithWhereWithoutParentInput | Prisma.AffirmationCategoryUpdateManyWithWhereWithoutParentInput[]
deleteMany?: Prisma.AffirmationCategoryScalarWhereInput | Prisma.AffirmationCategoryScalarWhereInput[]
}
export type AffirmationCategoryUncheckedUpdateManyWithoutParentNestedInput = {
create?: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutParentInput, Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput> | Prisma.AffirmationCategoryCreateWithoutParentInput[] | Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput[]
connectOrCreate?: Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput | Prisma.AffirmationCategoryCreateOrConnectWithoutParentInput[]
upsert?: Prisma.AffirmationCategoryUpsertWithWhereUniqueWithoutParentInput | Prisma.AffirmationCategoryUpsertWithWhereUniqueWithoutParentInput[]
createMany?: Prisma.AffirmationCategoryCreateManyParentInputEnvelope
set?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
disconnect?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
delete?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
connect?: Prisma.AffirmationCategoryWhereUniqueInput | Prisma.AffirmationCategoryWhereUniqueInput[]
update?: Prisma.AffirmationCategoryUpdateWithWhereUniqueWithoutParentInput | Prisma.AffirmationCategoryUpdateWithWhereUniqueWithoutParentInput[]
updateMany?: Prisma.AffirmationCategoryUpdateManyWithWhereWithoutParentInput | Prisma.AffirmationCategoryUpdateManyWithWhereWithoutParentInput[]
deleteMany?: Prisma.AffirmationCategoryScalarWhereInput | Prisma.AffirmationCategoryScalarWhereInput[]
}
export type AffirmationCategoryCreateWithoutAffirmationsInput = { export type AffirmationCategoryCreateWithoutAffirmationsInput = {
name: string name: string
parent?: Prisma.AffirmationCategoryCreateNestedOneWithoutChildrenInput
children?: Prisma.AffirmationCategoryCreateNestedManyWithoutParentInput
} }
export type AffirmationCategoryUncheckedCreateWithoutAffirmationsInput = { export type AffirmationCategoryUncheckedCreateWithoutAffirmationsInput = {
id?: number id?: number
name: string name: string
parentId?: number | null
children?: Prisma.AffirmationCategoryUncheckedCreateNestedManyWithoutParentInput
} }
export type AffirmationCategoryCreateOrConnectWithoutAffirmationsInput = { export type AffirmationCategoryCreateOrConnectWithoutAffirmationsInput = {
@@ -333,11 +447,128 @@ export type AffirmationCategoryUpdateToOneWithWhereWithoutAffirmationsInput = {
export type AffirmationCategoryUpdateWithoutAffirmationsInput = { export type AffirmationCategoryUpdateWithoutAffirmationsInput = {
name?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string
parent?: Prisma.AffirmationCategoryUpdateOneWithoutChildrenNestedInput
children?: Prisma.AffirmationCategoryUpdateManyWithoutParentNestedInput
} }
export type AffirmationCategoryUncheckedUpdateWithoutAffirmationsInput = { export type AffirmationCategoryUncheckedUpdateWithoutAffirmationsInput = {
id?: Prisma.IntFieldUpdateOperationsInput | number id?: Prisma.IntFieldUpdateOperationsInput | number
name?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string
parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null
children?: Prisma.AffirmationCategoryUncheckedUpdateManyWithoutParentNestedInput
}
export type AffirmationCategoryCreateWithoutChildrenInput = {
name: string
parent?: Prisma.AffirmationCategoryCreateNestedOneWithoutChildrenInput
affirmations?: Prisma.AffirmationCreateNestedManyWithoutCategoryInput
}
export type AffirmationCategoryUncheckedCreateWithoutChildrenInput = {
id?: number
name: string
parentId?: number | null
affirmations?: Prisma.AffirmationUncheckedCreateNestedManyWithoutCategoryInput
}
export type AffirmationCategoryCreateOrConnectWithoutChildrenInput = {
where: Prisma.AffirmationCategoryWhereUniqueInput
create: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutChildrenInput, Prisma.AffirmationCategoryUncheckedCreateWithoutChildrenInput>
}
export type AffirmationCategoryCreateWithoutParentInput = {
name: string
children?: Prisma.AffirmationCategoryCreateNestedManyWithoutParentInput
affirmations?: Prisma.AffirmationCreateNestedManyWithoutCategoryInput
}
export type AffirmationCategoryUncheckedCreateWithoutParentInput = {
id?: number
name: string
children?: Prisma.AffirmationCategoryUncheckedCreateNestedManyWithoutParentInput
affirmations?: Prisma.AffirmationUncheckedCreateNestedManyWithoutCategoryInput
}
export type AffirmationCategoryCreateOrConnectWithoutParentInput = {
where: Prisma.AffirmationCategoryWhereUniqueInput
create: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutParentInput, Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput>
}
export type AffirmationCategoryCreateManyParentInputEnvelope = {
data: Prisma.AffirmationCategoryCreateManyParentInput | Prisma.AffirmationCategoryCreateManyParentInput[]
skipDuplicates?: boolean
}
export type AffirmationCategoryUpsertWithoutChildrenInput = {
update: Prisma.XOR<Prisma.AffirmationCategoryUpdateWithoutChildrenInput, Prisma.AffirmationCategoryUncheckedUpdateWithoutChildrenInput>
create: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutChildrenInput, Prisma.AffirmationCategoryUncheckedCreateWithoutChildrenInput>
where?: Prisma.AffirmationCategoryWhereInput
}
export type AffirmationCategoryUpdateToOneWithWhereWithoutChildrenInput = {
where?: Prisma.AffirmationCategoryWhereInput
data: Prisma.XOR<Prisma.AffirmationCategoryUpdateWithoutChildrenInput, Prisma.AffirmationCategoryUncheckedUpdateWithoutChildrenInput>
}
export type AffirmationCategoryUpdateWithoutChildrenInput = {
name?: Prisma.StringFieldUpdateOperationsInput | string
parent?: Prisma.AffirmationCategoryUpdateOneWithoutChildrenNestedInput
affirmations?: Prisma.AffirmationUpdateManyWithoutCategoryNestedInput
}
export type AffirmationCategoryUncheckedUpdateWithoutChildrenInput = {
id?: Prisma.IntFieldUpdateOperationsInput | number
name?: Prisma.StringFieldUpdateOperationsInput | string
parentId?: Prisma.NullableIntFieldUpdateOperationsInput | number | null
affirmations?: Prisma.AffirmationUncheckedUpdateManyWithoutCategoryNestedInput
}
export type AffirmationCategoryUpsertWithWhereUniqueWithoutParentInput = {
where: Prisma.AffirmationCategoryWhereUniqueInput
update: Prisma.XOR<Prisma.AffirmationCategoryUpdateWithoutParentInput, Prisma.AffirmationCategoryUncheckedUpdateWithoutParentInput>
create: Prisma.XOR<Prisma.AffirmationCategoryCreateWithoutParentInput, Prisma.AffirmationCategoryUncheckedCreateWithoutParentInput>
}
export type AffirmationCategoryUpdateWithWhereUniqueWithoutParentInput = {
where: Prisma.AffirmationCategoryWhereUniqueInput
data: Prisma.XOR<Prisma.AffirmationCategoryUpdateWithoutParentInput, Prisma.AffirmationCategoryUncheckedUpdateWithoutParentInput>
}
export type AffirmationCategoryUpdateManyWithWhereWithoutParentInput = {
where: Prisma.AffirmationCategoryScalarWhereInput
data: Prisma.XOR<Prisma.AffirmationCategoryUpdateManyMutationInput, Prisma.AffirmationCategoryUncheckedUpdateManyWithoutParentInput>
}
export type AffirmationCategoryScalarWhereInput = {
AND?: Prisma.AffirmationCategoryScalarWhereInput | Prisma.AffirmationCategoryScalarWhereInput[]
OR?: Prisma.AffirmationCategoryScalarWhereInput[]
NOT?: Prisma.AffirmationCategoryScalarWhereInput | Prisma.AffirmationCategoryScalarWhereInput[]
id?: Prisma.IntFilter<"AffirmationCategory"> | number
name?: Prisma.StringFilter<"AffirmationCategory"> | string
parentId?: Prisma.IntNullableFilter<"AffirmationCategory"> | number | null
}
export type AffirmationCategoryCreateManyParentInput = {
id?: number
name: string
}
export type AffirmationCategoryUpdateWithoutParentInput = {
name?: Prisma.StringFieldUpdateOperationsInput | string
children?: Prisma.AffirmationCategoryUpdateManyWithoutParentNestedInput
affirmations?: Prisma.AffirmationUpdateManyWithoutCategoryNestedInput
}
export type AffirmationCategoryUncheckedUpdateWithoutParentInput = {
id?: Prisma.IntFieldUpdateOperationsInput | number
name?: Prisma.StringFieldUpdateOperationsInput | string
children?: Prisma.AffirmationCategoryUncheckedUpdateManyWithoutParentNestedInput
affirmations?: Prisma.AffirmationUncheckedUpdateManyWithoutCategoryNestedInput
}
export type AffirmationCategoryUncheckedUpdateManyWithoutParentInput = {
id?: Prisma.IntFieldUpdateOperationsInput | number
name?: Prisma.StringFieldUpdateOperationsInput | string
} }
@@ -346,10 +577,12 @@ export type AffirmationCategoryUncheckedUpdateWithoutAffirmationsInput = {
*/ */
export type AffirmationCategoryCountOutputType = { export type AffirmationCategoryCountOutputType = {
children: number
affirmations: number affirmations: number
} }
export type AffirmationCategoryCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { export type AffirmationCategoryCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
children?: boolean | AffirmationCategoryCountOutputTypeCountChildrenArgs
affirmations?: boolean | AffirmationCategoryCountOutputTypeCountAffirmationsArgs affirmations?: boolean | AffirmationCategoryCountOutputTypeCountAffirmationsArgs
} }
@@ -363,6 +596,13 @@ export type AffirmationCategoryCountOutputTypeDefaultArgs<ExtArgs extends runtim
select?: Prisma.AffirmationCategoryCountOutputTypeSelect<ExtArgs> | null select?: Prisma.AffirmationCategoryCountOutputTypeSelect<ExtArgs> | null
} }
/**
* AffirmationCategoryCountOutputType without action
*/
export type AffirmationCategoryCountOutputTypeCountChildrenArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
where?: Prisma.AffirmationCategoryWhereInput
}
/** /**
* AffirmationCategoryCountOutputType without action * AffirmationCategoryCountOutputType without action
*/ */
@@ -374,6 +614,9 @@ export type AffirmationCategoryCountOutputTypeCountAffirmationsArgs<ExtArgs exte
export type AffirmationCategorySelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ export type AffirmationCategorySelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
id?: boolean id?: boolean
name?: boolean name?: boolean
parentId?: boolean
parent?: boolean | Prisma.AffirmationCategory$parentArgs<ExtArgs>
children?: boolean | Prisma.AffirmationCategory$childrenArgs<ExtArgs>
affirmations?: boolean | Prisma.AffirmationCategory$affirmationsArgs<ExtArgs> affirmations?: boolean | Prisma.AffirmationCategory$affirmationsArgs<ExtArgs>
_count?: boolean | Prisma.AffirmationCategoryCountOutputTypeDefaultArgs<ExtArgs> _count?: boolean | Prisma.AffirmationCategoryCountOutputTypeDefaultArgs<ExtArgs>
}, ExtArgs["result"]["affirmationCategory"]> }, ExtArgs["result"]["affirmationCategory"]>
@@ -381,34 +624,48 @@ export type AffirmationCategorySelect<ExtArgs extends runtime.Types.Extensions.I
export type AffirmationCategorySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ export type AffirmationCategorySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
id?: boolean id?: boolean
name?: boolean name?: boolean
parentId?: boolean
parent?: boolean | Prisma.AffirmationCategory$parentArgs<ExtArgs>
}, ExtArgs["result"]["affirmationCategory"]> }, ExtArgs["result"]["affirmationCategory"]>
export type AffirmationCategorySelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{ export type AffirmationCategorySelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
id?: boolean id?: boolean
name?: boolean name?: boolean
parentId?: boolean
parent?: boolean | Prisma.AffirmationCategory$parentArgs<ExtArgs>
}, ExtArgs["result"]["affirmationCategory"]> }, ExtArgs["result"]["affirmationCategory"]>
export type AffirmationCategorySelectScalar = { export type AffirmationCategorySelectScalar = {
id?: boolean id?: boolean
name?: boolean name?: boolean
parentId?: boolean
} }
export type AffirmationCategoryOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name", ExtArgs["result"]["affirmationCategory"]> export type AffirmationCategoryOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "parentId", ExtArgs["result"]["affirmationCategory"]>
export type AffirmationCategoryInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { export type AffirmationCategoryInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
parent?: boolean | Prisma.AffirmationCategory$parentArgs<ExtArgs>
children?: boolean | Prisma.AffirmationCategory$childrenArgs<ExtArgs>
affirmations?: boolean | Prisma.AffirmationCategory$affirmationsArgs<ExtArgs> affirmations?: boolean | Prisma.AffirmationCategory$affirmationsArgs<ExtArgs>
_count?: boolean | Prisma.AffirmationCategoryCountOutputTypeDefaultArgs<ExtArgs> _count?: boolean | Prisma.AffirmationCategoryCountOutputTypeDefaultArgs<ExtArgs>
} }
export type AffirmationCategoryIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {} export type AffirmationCategoryIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
export type AffirmationCategoryIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {} parent?: boolean | Prisma.AffirmationCategory$parentArgs<ExtArgs>
}
export type AffirmationCategoryIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
parent?: boolean | Prisma.AffirmationCategory$parentArgs<ExtArgs>
}
export type $AffirmationCategoryPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = { export type $AffirmationCategoryPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
name: "AffirmationCategory" name: "AffirmationCategory"
objects: { objects: {
parent: Prisma.$AffirmationCategoryPayload<ExtArgs> | null
children: Prisma.$AffirmationCategoryPayload<ExtArgs>[]
affirmations: Prisma.$AffirmationPayload<ExtArgs>[] affirmations: Prisma.$AffirmationPayload<ExtArgs>[]
} }
scalars: runtime.Types.Extensions.GetPayloadResult<{ scalars: runtime.Types.Extensions.GetPayloadResult<{
id: number id: number
name: string name: string
parentId: number | null
}, ExtArgs["result"]["affirmationCategory"]> }, ExtArgs["result"]["affirmationCategory"]>
composites: {} composites: {}
} }
@@ -803,6 +1060,8 @@ readonly fields: AffirmationCategoryFieldRefs;
*/ */
export interface Prisma__AffirmationCategoryClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> { export interface Prisma__AffirmationCategoryClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
readonly [Symbol.toStringTag]: "PrismaPromise" readonly [Symbol.toStringTag]: "PrismaPromise"
parent<T extends Prisma.AffirmationCategory$parentArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.AffirmationCategory$parentArgs<ExtArgs>>): Prisma.Prisma__AffirmationCategoryClient<runtime.Types.Result.GetResult<Prisma.$AffirmationCategoryPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
children<T extends Prisma.AffirmationCategory$childrenArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.AffirmationCategory$childrenArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$AffirmationCategoryPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
affirmations<T extends Prisma.AffirmationCategory$affirmationsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.AffirmationCategory$affirmationsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$AffirmationPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null> affirmations<T extends Prisma.AffirmationCategory$affirmationsArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.AffirmationCategory$affirmationsArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$AffirmationPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
/** /**
* Attaches callbacks for the resolution and/or rejection of the Promise. * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -835,6 +1094,7 @@ export interface Prisma__AffirmationCategoryClient<T, Null = never, ExtArgs exte
export interface AffirmationCategoryFieldRefs { export interface AffirmationCategoryFieldRefs {
readonly id: Prisma.FieldRef<"AffirmationCategory", 'Int'> readonly id: Prisma.FieldRef<"AffirmationCategory", 'Int'>
readonly name: Prisma.FieldRef<"AffirmationCategory", 'String'> readonly name: Prisma.FieldRef<"AffirmationCategory", 'String'>
readonly parentId: Prisma.FieldRef<"AffirmationCategory", 'Int'>
} }
@@ -1084,6 +1344,10 @@ export type AffirmationCategoryCreateManyAndReturnArgs<ExtArgs extends runtime.T
*/ */
data: Prisma.AffirmationCategoryCreateManyInput | Prisma.AffirmationCategoryCreateManyInput[] data: Prisma.AffirmationCategoryCreateManyInput | Prisma.AffirmationCategoryCreateManyInput[]
skipDuplicates?: boolean skipDuplicates?: boolean
/**
* Choose, which related nodes to fetch as well
*/
include?: Prisma.AffirmationCategoryIncludeCreateManyAndReturn<ExtArgs> | null
} }
/** /**
@@ -1154,6 +1418,10 @@ export type AffirmationCategoryUpdateManyAndReturnArgs<ExtArgs extends runtime.T
* Limit how many AffirmationCategories to update. * Limit how many AffirmationCategories to update.
*/ */
limit?: number limit?: number
/**
* Choose, which related nodes to fetch as well
*/
include?: Prisma.AffirmationCategoryIncludeUpdateManyAndReturn<ExtArgs> | null
} }
/** /**
@@ -1222,6 +1490,49 @@ export type AffirmationCategoryDeleteManyArgs<ExtArgs extends runtime.Types.Exte
limit?: number limit?: number
} }
/**
* AffirmationCategory.parent
*/
export type AffirmationCategory$parentArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
/**
* Select specific fields to fetch from the AffirmationCategory
*/
select?: Prisma.AffirmationCategorySelect<ExtArgs> | null
/**
* Omit specific fields from the AffirmationCategory
*/
omit?: Prisma.AffirmationCategoryOmit<ExtArgs> | null
/**
* Choose, which related nodes to fetch as well
*/
include?: Prisma.AffirmationCategoryInclude<ExtArgs> | null
where?: Prisma.AffirmationCategoryWhereInput
}
/**
* AffirmationCategory.children
*/
export type AffirmationCategory$childrenArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
/**
* Select specific fields to fetch from the AffirmationCategory
*/
select?: Prisma.AffirmationCategorySelect<ExtArgs> | null
/**
* Omit specific fields from the AffirmationCategory
*/
omit?: Prisma.AffirmationCategoryOmit<ExtArgs> | null
/**
* Choose, which related nodes to fetch as well
*/
include?: Prisma.AffirmationCategoryInclude<ExtArgs> | null
where?: Prisma.AffirmationCategoryWhereInput
orderBy?: Prisma.AffirmationCategoryOrderByWithRelationInput | Prisma.AffirmationCategoryOrderByWithRelationInput[]
cursor?: Prisma.AffirmationCategoryWhereUniqueInput
take?: number
skip?: number
distinct?: Prisma.AffirmationCategoryScalarFieldEnum | Prisma.AffirmationCategoryScalarFieldEnum[]
}
/** /**
* AffirmationCategory.affirmations * AffirmationCategory.affirmations
*/ */
+16 -5
View File
@@ -96,7 +96,7 @@ const models: AdminModelConfig[] = [
displayName: 'Affirmations', displayName: 'Affirmations',
displayNameSingular: 'Affirmation', displayNameSingular: 'Affirmation',
idType: 'String', idType: 'String',
include: { solfeggioFrequency: true, category: true }, include: { solfeggioFrequency: true, category: { include: { parent: true } } },
listFields: ['name', 'category.name', 'solfeggioFrequency.name', 'price'], listFields: ['name', 'category.name', 'solfeggioFrequency.name', 'price'],
searchFields: ['name', 'content'], searchFields: ['name', 'content'],
formFields: ['name', 'content', 'solfeggioFrequencyId', 'categoryId', 'price'], formFields: ['name', 'content', 'solfeggioFrequencyId', 'categoryId', 'price'],
@@ -152,13 +152,17 @@ const models: AdminModelConfig[] = [
displayName: 'Affirmation Categories', displayName: 'Affirmation Categories',
displayNameSingular: 'Affirmation Category', displayNameSingular: 'Affirmation Category',
idType: 'Int', idType: 'Int',
include: { affirmations: true }, include: { affirmations: true, children: true, parent: true },
listFields: ['name'], listFields: ['name', 'parent.name'],
searchFields: ['name'], searchFields: ['name'],
formFields: ['name'], formFields: ['name', 'parentId'],
readonlyFields: ['id'], readonlyFields: ['id'],
fieldTypes: { fieldTypes: {
name: 'String' name: 'String',
parentId: 'Int'
},
relationOptions: {
parentId: { model: 'AffirmationCategory', labelField: 'name', valueField: 'id' }
}, },
relatedRecords: [ relatedRecords: [
{ {
@@ -167,6 +171,13 @@ const models: AdminModelConfig[] = [
type: 'has-many', type: 'has-many',
displayFields: ['name', 'price'], displayFields: ['name', 'price'],
editSlug: 'affirmations' editSlug: 'affirmations'
},
{
relationKey: 'children',
label: 'Sub-categories',
type: 'has-many',
displayFields: ['name'],
editSlug: 'affirmation-categories'
} }
] ]
}, },
+1 -1
View File
@@ -25,7 +25,7 @@ export type AdminModelConfig = {
displayName: string; displayName: string;
displayNameSingular: string; displayNameSingular: string;
idType: 'String' | 'Int'; idType: 'String' | 'Int';
include?: Record<string, boolean>; include?: Record<string, boolean | { include: Record<string, boolean> }>;
listFields: string[]; listFields: string[];
searchFields: string[]; searchFields: string[];
formFields: string[]; formFields: string[];
@@ -10,20 +10,49 @@ export const load: PageServerLoad = async ({ locals }) => {
const affirmations = await prisma.affirmation.findMany({ const affirmations = await prisma.affirmation.findMany({
include: { include: {
solfeggioFrequency: true, solfeggioFrequency: true,
category: true category: { include: { parent: true } }
} }
}); });
const affirmationCategories = await prisma.affirmationCategory.findMany(); const affirmationCategories = await prisma.affirmationCategory.findMany({
include: { children: true }
});
const solfeggioFrequencies = await prisma.solfeggioFrequency.findMany(); const solfeggioFrequencies = await prisma.solfeggioFrequency.findMany();
return { user, affirmationCategories, affirmations, solfeggioFrequencies }; return { user, affirmationCategories, affirmations, solfeggioFrequencies };
}; };
async function resolveCategory(categoryName: string, subCategoryName: string | null) {
let parent = await prisma.affirmationCategory.findFirst({
where: { name: categoryName, parentId: null }
});
if (!parent) {
parent = await prisma.affirmationCategory.create({
data: { name: categoryName }
});
}
if (!subCategoryName) return parent;
let child = await prisma.affirmationCategory.findFirst({
where: { name: subCategoryName, parentId: parent.id }
});
if (!child) {
child = await prisma.affirmationCategory.create({
data: { name: subCategoryName, parentId: parent.id }
});
}
return child;
}
export const actions: Actions = { export const actions: Actions = {
create: async ({ request }: RequestEvent) => { create: async ({ request }: RequestEvent) => {
const form = await request.formData(); const form = await request.formData();
const frequencyId = Number(form.get('solfeggioFrequencyId')?.toString()) || 0; const frequencyId = Number(form.get('solfeggioFrequencyId')?.toString()) || 0;
const price = Number(form.get('price')) || 0.0; const price = Number(form.get('price')) || 0.0;
const categoryName = form.get('categoryName') as string; const categoryName = form.get('categoryName') as string;
const subCategoryName = (form.get('subCategoryName') as string) || null;
if (frequencyId === 0) { if (frequencyId === 0) {
return fail(400, { return fail(400, {
@@ -39,15 +68,7 @@ export const actions: Actions = {
}); });
} }
let category = await prisma.affirmationCategory.findFirst({ where: { name: categoryName } }); const category = await resolveCategory(categoryName, subCategoryName);
if (!category) {
category = await prisma.affirmationCategory.create({
data: {
name: categoryName
}
});
}
try { try {
const newAffirmation = await prisma.affirmation.create({ const newAffirmation = await prisma.affirmation.create({
@@ -5,35 +5,59 @@ import { error, fail, type Actions, type RequestEvent, type ServerLoadEvent } fr
export const load: PageServerLoad = async ({ params }: ServerLoadEvent) => { export const load: PageServerLoad = async ({ params }: ServerLoadEvent) => {
const affirmation = await prisma.affirmation.findUnique({ const affirmation = await prisma.affirmation.findUnique({
where: { id: params.id }, where: { id: params.id },
include: { solfeggioFrequency: true, category: true } include: { solfeggioFrequency: true, category: { include: { parent: true } } }
}); });
const solfeggioFrequencies = await prisma.solfeggioFrequency.findMany(); const solfeggioFrequencies = await prisma.solfeggioFrequency.findMany();
const affirmationCategories = await prisma.affirmationCategory.findMany(); const affirmationCategories = await prisma.affirmationCategory.findMany({
include: { children: true }
});
if (!affirmation) { if (!affirmation) {
throw error(404, 'not found'); throw error(404, 'not found');
} }
console.log(affirmation);
return { affirmation, solfeggioFrequencies, affirmationCategories }; return { affirmation, solfeggioFrequencies, affirmationCategories };
}; };
async function resolveCategory(categoryName: string, subCategoryName: string | null) {
let parent = await prisma.affirmationCategory.findFirst({
where: { name: categoryName, parentId: null }
});
if (!parent) {
parent = await prisma.affirmationCategory.create({
data: { name: categoryName }
});
}
if (!subCategoryName) return parent;
let child = await prisma.affirmationCategory.findFirst({
where: { name: subCategoryName, parentId: parent.id }
});
if (!child) {
child = await prisma.affirmationCategory.create({
data: { name: subCategoryName, parentId: parent.id }
});
}
return child;
}
export const actions: Actions = { export const actions: Actions = {
update: async ({ request }: RequestEvent) => { update: async ({ request }: RequestEvent) => {
const form = await request.formData(); const form = await request.formData();
const frequencyId = Number(form.get('solfeggioFrequencyId')?.toString()) || 0; const frequencyId = Number(form.get('solfeggioFrequencyId')?.toString()) || 0;
const price = Number(form.get('price')) || 0.0; const price = Number(form.get('price')) || 0.0;
const categoryName = form.get('categoryName') as string; const categoryName = form.get('categoryName') as string;
const subCategoryName = (form.get('subCategoryName') as string) || null;
let category = await prisma.affirmationCategory.findFirst({ where: { name: categoryName } }); if (!categoryName) {
return fail(400, {
if (!category) { error: 'Category is required!',
category = await prisma.affirmationCategory.create({ ...Object.fromEntries(form)
data: {
name: categoryName
}
}); });
} }
@@ -44,6 +68,8 @@ export const actions: Actions = {
}); });
} }
const category = await resolveCategory(categoryName, subCategoryName);
try { try {
const updatedAffirmation = await prisma.affirmation.update({ const updatedAffirmation = await prisma.affirmation.update({
where: { where: {