feat: habbits and schedules

This commit is contained in:
Yehoshua Sandler 2025-05-18 15:27:06 -05:00
parent 0a8f9da009
commit b51a35ab15
13 changed files with 314 additions and 54 deletions

View File

@ -4,6 +4,7 @@ export const ExerciseTypes: CollectionConfig = {
slug: 'exerciseTypes',
admin: {
useAsTitle: 'name',
group: 'Exercise',
},
fields: [
{
@ -25,6 +26,7 @@ export const MuscleGroups: CollectionConfig = {
slug: 'muscleGroups',
admin: {
useAsTitle: 'name',
group: 'Exercise',
},
fields: [
{
@ -46,6 +48,7 @@ export const Equipments: CollectionConfig = {
slug: 'equipments',
admin: {
useAsTitle: 'name',
group: 'Exercise',
},
fields: [
{
@ -68,6 +71,7 @@ export const Exercises: CollectionConfig = {
slug: 'exercises',
admin: {
useAsTitle: 'name',
group: 'Exercise',
},
fields: [
{

View File

@ -0,0 +1,20 @@
import { CollectionConfig } from "payload";
export const HabbitCategories: CollectionConfig = {
slug: 'habbitCategories',
admin: {
useAsTitle: 'name',
group: 'Habbits',
},
fields: [
{
name: 'name',
type: 'text',
unique: true,
},
{
name: 'description',
type: 'textarea',
},
],
}

View File

@ -0,0 +1,25 @@
import { CollectionConfig } from "payload";
export const HabbitEntries: CollectionConfig = {
slug: 'habbitEntries',
admin: {
useAsTitle: 'completedDate',
group: 'User Data',
},
fields: [
{
name: 'habbit',
type: 'relationship',
relationTo: 'habbits'
},
{
name: 'completedDate',
type: 'date',
admin: {
date: {
pickerAppearance: 'dayAndTime'
}
}
},
],
}

View File

@ -0,0 +1,42 @@
import { CollectionConfig } from "payload";
export const Habbits: CollectionConfig = {
slug: 'habbits',
admin: {
useAsTitle: 'name',
group: 'User Data',
},
fields: [
{
name: 'name',
type: 'text',
},
{
name: 'description',
type: 'textarea',
},
{
name: 'category',
type: 'relationship',
relationTo: 'habbitCategories',
},
{
name: 'instructions',
type: 'richText',
},
{
name: 'unitValue',
type: 'number',
},
{
name: 'unitName',
type: 'text',
},
{
name: 'user',
type: 'relationship',
relationTo: 'users',
hasMany: false,
},
],
}

View File

@ -4,6 +4,7 @@ export const Ingredients: CollectionConfig = {
slug: 'ingredients',
admin: {
useAsTitle: 'name',
group: 'Nutrition',
},
fields: [
{

View File

@ -7,6 +7,7 @@ export const MealItems: CollectionConfig = {
admin: {
description: 'Items that make up a meal, such as mashed potatoes, salad, grilled chicken, etc.',
useAsTitle: 'name',
group: 'Nutrition',
},
fields: [
{

View File

@ -5,6 +5,7 @@ export const Meals: CollectionConfig = {
slug: 'meals',
admin: {
useAsTitle: 'name',
group: 'Nutrition',
},
fields: [
{

View File

@ -0,0 +1,37 @@
import { CollectionConfig } from "payload";
export const Schedules: CollectionConfig = {
slug: 'schedules',
admin: {
group: 'User Data',
},
fields: [
{
name: 'user',
type: 'relationship',
relationTo: 'users',
hasMany: false,
},
{
name: 'scheduledItems',
type: 'array',
fields: [
{
name: 'item',
type: 'relationship',
relationTo: ['workouts', 'meals', 'habbits'],
hasMany: false,
},
{
name: 'dateTime',
type: 'date',
admin: {
date: {
pickerAppearance: 'dayAndTime'
}
}
},
],
},
],
}

View File

@ -48,6 +48,7 @@ export const Users: CollectionConfig = {
admin: {
defaultColumns: ['name', 'email'],
useAsTitle: 'username',
group: 'User Data',
},
auth: true,
endpoints: [externalUsersLogin],

View File

@ -46,6 +46,7 @@ export const WorkoutTypes: CollectionConfig = {
slug: 'workoutTypes',
admin: {
useAsTitle: 'name',
group: 'Exercise',
},
fields: [
{
@ -67,6 +68,7 @@ export const Workouts: CollectionConfig = {
slug: 'workouts',
admin: {
useAsTitle: 'name',
group: 'Exercise',
},
fields: [
{

View File

@ -82,6 +82,10 @@ export interface Config {
ingredients: Ingredient;
mealItems: MealItem;
meals: Meal;
habbitCategories: HabbitCategory;
habbits: Habbit;
habbitEntries: HabbitEntry;
schedules: Schedule;
redirects: Redirect;
forms: Form;
'form-submissions': FormSubmission;
@ -108,6 +112,10 @@ export interface Config {
ingredients: IngredientsSelect<false> | IngredientsSelect<true>;
mealItems: MealItemsSelect<false> | MealItemsSelect<true>;
meals: MealsSelect<false> | MealsSelect<true>;
habbitCategories: HabbitCategoriesSelect<false> | HabbitCategoriesSelect<true>;
habbits: HabbitsSelect<false> | HabbitsSelect<true>;
habbitEntries: HabbitEntriesSelect<false> | HabbitEntriesSelect<true>;
schedules: SchedulesSelect<false> | SchedulesSelect<true>;
redirects: RedirectsSelect<false> | RedirectsSelect<true>;
forms: FormsSelect<false> | FormsSelect<true>;
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
@ -1093,6 +1101,91 @@ export interface Meal {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "habbitCategories".
*/
export interface HabbitCategory {
id: number;
tenant?: (number | null) | Tenant;
name?: string | null;
description?: string | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "habbits".
*/
export interface Habbit {
id: number;
tenant?: (number | null) | Tenant;
name?: string | null;
description?: string | null;
category?: (number | null) | HabbitCategory;
instructions?: {
root: {
type: string;
children: {
type: string;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
} | null;
unitValue?: number | null;
unitName?: string | null;
user?: (number | null) | User;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "habbitEntries".
*/
export interface HabbitEntry {
id: number;
tenant?: (number | null) | Tenant;
habbit?: (number | null) | Habbit;
completedDate?: string | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "schedules".
*/
export interface Schedule {
id: number;
tenant?: (number | null) | Tenant;
user?: (number | null) | User;
scheduledItems?:
| {
item?:
| ({
relationTo: 'workouts';
value: number | Workout;
} | null)
| ({
relationTo: 'meals';
value: number | Meal;
} | null)
| ({
relationTo: 'habbits';
value: number | Habbit;
} | null);
dateTime?: string | null;
id?: string | null;
}[]
| null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "redirects".
@ -1325,6 +1418,22 @@ export interface PayloadLockedDocument {
relationTo: 'meals';
value: number | Meal;
} | null)
| ({
relationTo: 'habbitCategories';
value: number | HabbitCategory;
} | null)
| ({
relationTo: 'habbits';
value: number | Habbit;
} | null)
| ({
relationTo: 'habbitEntries';
value: number | HabbitEntry;
} | null)
| ({
relationTo: 'schedules';
value: number | Schedule;
} | null)
| ({
relationTo: 'redirects';
value: number | Redirect;
@ -1866,6 +1975,61 @@ export interface MealsSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "habbitCategories_select".
*/
export interface HabbitCategoriesSelect<T extends boolean = true> {
tenant?: T;
name?: T;
description?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "habbits_select".
*/
export interface HabbitsSelect<T extends boolean = true> {
tenant?: T;
name?: T;
description?: T;
category?: T;
instructions?: T;
unitValue?: T;
unitName?: T;
user?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "habbitEntries_select".
*/
export interface HabbitEntriesSelect<T extends boolean = true> {
tenant?: T;
habbit?: T;
completedDate?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "schedules_select".
*/
export interface SchedulesSelect<T extends boolean = true> {
tenant?: T;
user?: T;
scheduledItems?:
| T
| {
item?: T;
dateTime?: T;
id?: T;
};
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "redirects_select".

View File

@ -20,6 +20,10 @@ import { Tenants } from './collections/Tenants'
import { Equipments, Exercises, ExerciseTypes, MuscleGroups } from './collections/Exercises'
import { Workouts, WorkoutTypes } from './collections/Workouts'
import { Ingredients, MealItems, Meals } from './collections/Meals'
import { HabbitCategories } from './collections/Habbits/HabbitCategories'
import { Habbits } from './collections/Habbits/Habbits'
import { HabbitEntries } from './collections/Habbits/HabbitEntry'
import { Schedules } from './collections/Schedules'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@ -68,7 +72,7 @@ export default buildConfig({
connectionString: process.env.DATABASE_URI || '',
},
}),
collections: [Pages, Posts, Media, Categories, Users, Tenants, Exercises, ExerciseTypes, MuscleGroups, Equipments, Workouts, WorkoutTypes, Ingredients, MealItems, Meals],
collections: [Pages, Posts, Media, Categories, Users, Tenants, Exercises, ExerciseTypes, MuscleGroups, Equipments, Workouts, WorkoutTypes, Ingredients, MealItems, Meals, HabbitCategories, Habbits, HabbitEntries, Schedules],
cors: [getServerSideURL()].filter(Boolean),
globals: [Header, Footer],
plugins: [

View File

@ -15,7 +15,8 @@ import { beforeSyncWithSearch } from '@/search/beforeSync'
import { Config, Page, Post, User } from '@/payload-types'
import { getServerSideURL } from '@/utilities/getURL'
import { UserAccessLevel } from '@/collections/Users'
import { isSuperAdmin } from '@/access/admin'
import { isSuperAdmin } from '@/access/isSuperAdmin'
import { getUserTenantIDs } from '@/utilities/getUserTenantIds'
const generateTitle: GenerateTitle<Post | Page> = ({ doc }) => {
return doc?.title ? `${doc.title} | Payload Website Template` : 'Payload Website Template'
@ -108,6 +109,10 @@ export const plugins: Plugin[] = [
ingredients: {},
mealItems: {},
meals: {},
habbitCategories: {},
habbits: {},
habbitEntries: {},
schedules: {},
},
tenantsArrayField: {
includeDefaultField: false,
@ -116,18 +121,11 @@ export const plugins: Plugin[] = [
tenantField: {
access: {
read: () => true,
update: (data) => {
update: ({ req }) => {
if (isSuperAdmin(req.user)) {
return true
// const { req, doc } = data
//
// if (isSuperAdmin({ req })) return true
//
// if (!req.user) return false
//
// const userTentants = req.user.tenants || []
// if (userTentants.includes(doc.tenant)) return true
//
// return false
}
return getUserTenantIDs(req.user).length > 0
},
create: () => true,
},
@ -135,43 +133,3 @@ export const plugins: Plugin[] = [
}),
]
//mport type { CollectionConfig } from 'payload'
//
//mport { authenticated } from '../../access/authenticated'
//
//xport const Exercises: CollectionConfig = {
// slug: 'exercises',
// access: {
// create: authenticated,
// delete: authenticated,
// read: authenticated,
// update: authenticated,
// },
// admin: {
// useAsTitle: 'name',
// },
// fields: [
// {
// name: 'name',
// type: 'text',
// required: true,
// unique: true,
// },
// {
// name: 'instuctions',
// type: 'text',
// },
//
// {
// name: 'images',
// type: 'relationship',
// relationTo: 'media',
// hasMany: true,
// },
// // add these relationships
// // categories - strength, cardio etc
// // muscle group
// // exercise Type - Bodyweight, dumbells etc
// ],
//