Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/godiet 71 planning meal implements method to save new name for each food when creating a plan #19

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
966503e
chore(GODIET-71): :label: rename types
vitorrsousaa Mar 22, 2024
0c12e4d
chore(GODIET-71): :wrench: update page template scaffolding
vitorrsousaa Mar 22, 2024
11d11ac
feat(GODIET-71): :package: add command ui package
vitorrsousaa Mar 22, 2024
1f8c9cc
feat(GODIET-71): :lipstick: add new components
vitorrsousaa Mar 22, 2024
4f4f465
chore(GODIET-71): :arrow_down: downgrade cmdk dependencies
vitorrsousaa Mar 22, 2024
62f2c08
feat(GODIET-71): :lipstick: add scroll area component
vitorrsousaa Mar 22, 2024
638cf03
chore(GODIET-71): :package: add scroll area component package
vitorrsousaa Mar 22, 2024
78a4526
feat(GODIET-71): :sparkles: update combobox with new properties to ex…
vitorrsousaa Mar 22, 2024
221ca1d
feat(GODIET-71): :sparkles: add combobox component
vitorrsousaa Mar 22, 2024
13a74d5
fix(GODIET-71): :lipstick: change icon of combobox
vitorrsousaa Mar 22, 2024
4605d55
fix(GODIET-71): :bug: fixes the label to show when selected a favorit…
vitorrsousaa Mar 22, 2024
049e58f
fix(GODIET-71): :bug: remove unnused code
vitorrsousaa Mar 22, 2024
7371730
feat(GODIET-71): :sparkles: add editable table
vitorrsousaa Mar 23, 2024
7dce6ec
fix(GODIET-71): :adhesive_bandage: update button with loading status
vitorrsousaa Mar 23, 2024
6887875
refactor(GODIET-71): :chart_with_upwards_trend: update componente wit…
vitorrsousaa Mar 23, 2024
945b51d
feat(GODIET-71): :rocket: update table info with edit name of food
vitorrsousaa Mar 23, 2024
d5e4dd8
feat(GODIET-71): :zap: update mapper with the name of food
vitorrsousaa Mar 23, 2024
041867e
feat(GODIET-71): :busts_in_silhouette: create a simple template for a…
vitorrsousaa Mar 23, 2024
90b3230
feat(GODIET-71): :label: add new types for meal food name and impleme…
vitorrsousaa Mar 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions .scaffolding/component.vsc-template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
(function Template() {
const toPascalCase = (str) =>
str
.replace(/(?:^\w|[A-Z]|\b\w)/g, (fl) => fl.toUpperCase())
.replace(/\W+/g, '');

const toCamelCase = (str) =>
toPascalCase(str).replace(/^./, (firstLetter) => firstLetter.toLowerCase());

return {
userInputs: [
{
title: 'Component page name',
argumentName: 'name',
defaultValue: 'Sample',
},
],
template: [
{
type: 'folder',
name: (inputs) => `${toPascalCase(inputs.name)}`,
children: [
{
type: 'file',
name: 'index.ts',
content: (inputs) => `import { ${toPascalCase(
inputs.name
)}, ${toPascalCase(
inputs.name
)}Props } from './${toCamelCase(inputs.name)}';

export { ${toPascalCase(inputs.name)} };
export type { ${toPascalCase(inputs.name)}Props };
`,
},
{
type: 'file',
name: (inputs) => `${toCamelCase(inputs.name)}.tsx`,
content: (
inputs
) => `import { use${toPascalCase(inputs.name)}Hook } from './${toCamelCase(inputs.name)}.hook';

export interface ${toPascalCase(inputs.name)}Props {
data: string;
}

export function ${toPascalCase(inputs.name)}(props: ${toPascalCase(inputs.name)}Props) {
const { data } = props;

const { state } = use${toPascalCase(inputs.name)}Hook(props);
return (
<div>
<h1>${toPascalCase(inputs.name)}</h1>
{data} {state}
</div>
);
}
`,
},
{
type: 'file',
name: (inputs) => `${toCamelCase(inputs.name)}.hook.ts`,
content: (inputs) => `import React from 'react';

import { ${toPascalCase(inputs.name)}Props } from './${toCamelCase(inputs.name)}';

export function use${toPascalCase(inputs.name)}Hook(props: ${toPascalCase(inputs.name)}Props) {
const { data } = props;

const [state] = React.useState(data);

return {
state,
};
}

`,
},
{
type: 'file',
name: (inputs) => `${toCamelCase(inputs.name)}.spec.tsx`,
content: (inputs) => `
import {
render,
renderHook,
ReturnRenderHookType,
ReturnRenderType,
} from '@testing-react';
import { clearAllMocks } from '@testing-suit';

import { ${toPascalCase(inputs.name)}, ${toPascalCase(inputs.name)}Props } from './${toCamelCase(inputs.name)}';
import { use${toPascalCase(inputs.name)}Hook } from './${toCamelCase(inputs.name)}.hook';

describe('${toPascalCase(inputs.name)}', () => {
beforeEach(() => {
clearAllMocks();
});

describe('render', () => {
let rendered: ReturnRenderType;

beforeEach(() => {
clearAllMocks();
});

afterEach(() => {
rendered.unmount();
});

it('Should render the view with default props', () => {
// Arrange

// Act
rendered = render(<${toPascalCase(inputs.name)} data={'0'} />);

// Assert
expect(rendered.getByText('${toPascalCase(inputs.name)}'));
});
});

describe('hook', () => {
let rendered: ReturnRenderHookType<typeof use${toPascalCase(inputs.name)}Hook>;

beforeEach(() => {
clearAllMocks();
});

afterEach(() => {
rendered.unmount();
});

it('Should render the hook with default props', () => {
// Arrange
const props: ${toPascalCase(inputs.name)}Props = {
data: 'teste',
};

// Act
rendered = renderHook(() => use${toPascalCase(inputs.name)}Hook(props));

// Assert
expect(rendered.result.current.state).toEqual('teste');
});
});
});
`,
},
],
},
],
};
});
4 changes: 2 additions & 2 deletions .scaffolding/page.vsc-template.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
name: 'index.ts',
content: (inputs) => `import { ${toPascalCase(
inputs.name
)}Controller } from './controller';
)} } from './${toCamelCase(inputs.name)}';

export { ${toPascalCase(inputs.name)}Controller };
export { ${toPascalCase(inputs.name)} };
`,
},
{
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
Expand All @@ -45,6 +46,7 @@
"axios": "^1.6.8",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "0.2.1",
"date-fns": "^3.3.1",
"jspdf": "^2.5.1",
"lodash": "^4.17.21",
Expand All @@ -60,6 +62,7 @@
"tailwind-merge": "^2.2.2",
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "^1.0.7",
"use-debounce": "^10.0.0",
"zod": "^3.22.4"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions src/app/entities/planningMeal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface TMealFood {
qty: number;
options: [];
food: TFood;
name: string;
}

export interface TMeal {
Expand Down
4 changes: 3 additions & 1 deletion src/app/services/planningMeal/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface TCreatePlanningMeal {
time: string;
mealFoods: {
foodId: string;
name: string;
qty: number;
measure: {
name: string;
Expand Down Expand Up @@ -43,7 +44,8 @@ function mapper(planningMeal: TCreatePlanningMealDTO): TCreatePlanningMeal {
time: meal.time,
name: meal.name,
mealFoods: meal.mealFoods.map((mealFood) => ({
foodId: mealFood.id,
foodId: mealFood.foodId,
name: mealFood.name,
qty: mealFood.qty,
measure: mealFood.measure,
options: [],
Expand Down
4 changes: 2 additions & 2 deletions src/app/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface PageStatus {
/**
* Interface que define o retorno inicial de um hook.
*/
interface DefaultReturnHookPage {
interface IBaseReturnHook {
/**
* O status da página, incluindo isLoading, isError e noData.
*/
Expand All @@ -33,4 +33,4 @@ interface DefaultReturnHookPage {
*
* @template T - Tipo dos outros itens específicos do usuário.
*/
export type ReturnHookPage<T> = DefaultReturnHookPage & T;
export type ReturnHookPage<T> = IBaseReturnHook & T;
2 changes: 1 addition & 1 deletion src/view/components/CardMeal/Options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function Options(props: OptionsProps) {
className
)}
>
{mealFood.food.name} - {mealFood.qty} {mealFood.measure.name}
{mealFood.name} - {mealFood.qty} {mealFood.measure.name}
</small>
</div>
<div className="flex w-full flex-col gap-2">
Expand Down
5 changes: 2 additions & 3 deletions src/view/pages/CreatePlanning/CreatePlanning.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import * as z from 'zod';

export const CreateMealFoodSchema = z.object({
name: z.string(),
id: z.string().uuid(),
foodId: z.string().uuid(),
qty: z.number().min(1),
measure: z.object({
name: z.string(),
Expand Down Expand Up @@ -79,7 +79,7 @@ export function useCreatePlanningHook() {
planningMeal: data,
});

toast.success('Plano alimentar criado com sucesso!');
toast.success('Plano alimentar criado!');
} catch (error) {
toast.error('Erro ao criar o plano alimentar');
} finally {
Expand Down Expand Up @@ -109,7 +109,6 @@ export function useCreatePlanningHook() {
);

return {
control,
methods,
errors,
meals: watchMeals,
Expand Down
3 changes: 0 additions & 3 deletions src/view/pages/CreatePlanning/CreatePlanning.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Button } from '@godiet-ui/Button';
import { Input } from '@godiet-ui/Input';

import { DevTool } from '@hookform/devtools';
import { PlusIcon } from '@radix-ui/react-icons';
import { FormProvider } from 'react-hook-form';

Expand All @@ -10,7 +9,6 @@ import { useCreatePlanningHook } from './CreatePlanning.hook';

export function CreatePlanning() {
const {
control,
methods,
errors,
meals,
Expand All @@ -23,7 +21,6 @@ export function CreatePlanning() {

return (
<FormProvider {...methods}>
<DevTool control={control} />
<form>
<div className="flex flex-col gap-4">
<h3 className="pb-2 text-lg font-bold text-foreground">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { useCallback, useMemo, useReducer, useState } from 'react';

import { TCreatePlanningMealDTO } from '@godiet-pages/CreatePlanning/CreatePlanning.hook';
import {
CreateMealFoodSchema,
TCreatePlanningMealDTO,
} from '@godiet-pages/CreatePlanning/CreatePlanning.hook';

import { useFieldArray, useFormContext, useWatch } from 'react-hook-form';
import * as z from 'zod';

import { CreateMealProps } from './CreateMeal';

Expand All @@ -17,6 +21,10 @@ interface FoodsByMeal {
name: string;
}

type TSelectedFoodToEdit = z.infer<typeof CreateMealFoodSchema> & {
mealFoodIndex: number;
};

export function useCreateMealHook(props: CreateMealProps) {
const { mealIndex } = props;

Expand Down Expand Up @@ -50,12 +58,8 @@ export function useCreateMealHook(props: CreateMealProps) {
null
);

const [selectedFoodToEdit, setSelectedFoodToEdit] = useState<{
id: string;
measure: { name: string; qty: number };
qty: number;
mealFoodIndex: number;
} | null>(null);
const [selectedFoodToEdit, setSelectedFoodToEdit] =
useState<TSelectedFoodToEdit | null>(null);

const { register, control } = useFormContext<TCreatePlanningMealDTO>();

Expand All @@ -78,7 +82,7 @@ export function useCreateMealHook(props: CreateMealProps) {
const initialFoodsByMeal: FoodsByMeal[] = [];
watchMeal.mealFoods.forEach((food) => {
initialFoodsByMeal.push({
id: food.id,
id: food.foodId,
measure: food.measure,
qty: food.qty,
prot: 0.6 * 20,
Expand All @@ -95,7 +99,7 @@ export function useCreateMealHook(props: CreateMealProps) {
const generateHashKey = useMemo(() => {
if (!selectedFoodToEdit) return 'food-to-edit';

const hashId = selectedFoodToEdit.id;
const hashId = selectedFoodToEdit.foodId;
const hashMeasureName = selectedFoodToEdit.measure.name
.trim()
.replace(' ', '-');
Expand All @@ -120,10 +124,11 @@ export function useCreateMealHook(props: CreateMealProps) {
toggleSelectedMealIndex(mealIndex);

setSelectedFoodToEdit({
id: selectedFood.id,
foodId: selectedFood.id,
measure: selectedFood.measure,
qty: selectedFood.qty,
mealFoodIndex: mealFoodIndex,
name: selectedFood.name,
});
toggleModalEditFoodOpen();
},
Expand Down
14 changes: 10 additions & 4 deletions src/view/pages/CreatePlanning/components/CreateMeal/CreateMeal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,16 @@ export function CreateMeal(props: CreateMealProps) {

<Separator />

<Card.Footer className="flex flex-col gap-2">
<h1 className="text-md mt-4 font-semibold text-muted-foreground">
Alimentos selecionados
</h1>
<Card.Footer className="flex flex-col gap-4">
<div className="text-center">
<h1 className="text-md mt-4 font-semibold text-muted-foreground">
Alimentos selecionados
</h1>
<small className="text-muted-foreground">
Você pode editar o título dos alimentos selecionados na tabela
abaixo.
</small>
</div>
<TableFoodsByMeal
mealIndex={mealIndex}
onOpenModalRemove={handleOpenModalRemoveFood}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@ export function useTableFoodsByMealHook(props: TableFoodsByMealProps) {
const initialFoodsByMeal: FoodsByMeal[] = [];
watchMeal.mealFoods.forEach((food) => {
const selectedFood = foods.find(
(foodDatabase) => foodDatabase.id === food.id
(foodDatabase) => foodDatabase.id === food.foodId
);

if (!selectedFood) return;

const mealFoodCalculated = calculateMealFoods({
food: selectedFood,
food: {
...selectedFood,
name: food.name,
},
measure: food.measure,
qty: food.qty,
});
Expand Down
Loading
Loading