Skip to content

Commit

Permalink
feat: extend frontend with home and pastry page
Browse files Browse the repository at this point in the history
* docs: update README.md to get started quickly for real

* fix: be consistent with pastry naming

* pastery -> pastry

* feat: add pastry page and adding new pastries

* add pastry page and home page
* add save pastry functionality
  • Loading branch information
smallTrogdor authored Jun 7, 2024
1 parent 7458f22 commit f33fa0a
Show file tree
Hide file tree
Showing 19 changed files with 238 additions and 31 deletions.
42 changes: 33 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,24 @@

#### Table Of Contents

- [Introduction](#Introduction)
- [Getting Started](#Getting-Started)
- [Contributing](#Contributing)
- [Documentation](#Documentation)
- [Code of Conduct](#code-of-conduct)
- [Coding Standards](#coding-standards)
- [License](#License)
- [The BakerTime App](#the-bakertime-app)
- [Table Of Contents](#table-of-contents)
- [Introduction](#introduction)
- [Models](#models)
- [AppBaker](#appbaker)
- [Pastry](#pastry)
- [Screens](#screens)
- [Dashboard](#dashboard)
- [AppBaker Profile](#appbaker-profile)
- [Pastry Overview](#pastry-overview)
- [API](#api)
- [Getting-Started](#getting-started)
- [API](#api-1)
- [Documentation](#documentation)
- [License](#license)
- [Contributing](#contributing)
- [Coding Standards](#coding-standards)
- [Code of Conduct](#code-of-conduct)

<a id="Introduction"></a>

Expand Down Expand Up @@ -38,13 +49,26 @@ This is the detailed view per pastry.
## API
For the backend the [Express framework](https://expressjs.com/) is used.

## Frontend
For the frontend the [Vue.js framework](https://vuejs.org/) with typescript transpilation is used.

## Getting-Started

### API
To start the backend run the following two commands:
To start the backend run the following commands from the root dir:
```
cd api
npm install
node app.js
```

### Frontend
To get started locally, add a .env file at the root of the `frontend` dir with the `VITE_BACKEND_URL` var pointing to the webserver hosted locally above.

Then run the following commands (from `./frontend`):
```
npm install
npm start
npm run dev
```


Expand Down
4 changes: 2 additions & 2 deletions api/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const cookieParser = require('cookie-parser');
const logger = require('morgan');

const appbakersRouter = require('./routes/appbakers');
const pasteriesRouter = require('./routes/pasteries');
const pasteriesRouter = require('./routes/pastries');

const app = express();
const port = 8080
Expand All @@ -16,7 +16,7 @@ app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/appbakers', appbakersRouter);
app.use('/pasteries', pasteriesRouter);
app.use('/pastries', pasteriesRouter);

app.listen(port, () => {
console.log(`BakeTime listening on port ${port}`)
Expand Down
File renamed without changes.
11 changes: 0 additions & 11 deletions api/routes/pasteries.js

This file was deleted.

11 changes: 11 additions & 0 deletions api/routes/pastries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const express = require('express');
const pastriesController = require('../controllers/pastries-controller');
const router = express.Router();

router.get('/', pastriesController.getPastries);
router.get('/:id', pastriesController.getPastry);
router.post('/', pastriesController.addPastry);
router.put('/:id', pastriesController.updatePastry);
router.delete('/:id', pastriesController.deletePastry);

module.exports = router;
6 changes: 3 additions & 3 deletions frontend/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"recommendations": [
"Vue.volar",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
"esbenp.prettier-vscode",
"bradlc.vscode-tailwindcss"
]
}
}
Binary file added frontend/src/assets/bakingApps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 11 additions & 1 deletion frontend/src/core/container/app-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import type { ContainerDefinition } from '@/core/plugins/container'
import RemoteUseCaseProxy from '@/core/use-cases/remote-use-case-proxy'
import type { InjectionKey } from 'vue'
import GetAppBakersUseCase from '../use-cases/app-bakers/get-app-bakers.use-case'
import GetPastriesUseCase from '../use-cases/pastries/get-pastries.use-case'
import AddPastryUseCase from '../use-cases/pastries/add-pastry.use-case'

export const AppContainerKey = {
httpClient: Symbol('httpClient') as InjectionKey<HttpClient>,
remoteUseCaseProxy: Symbol('remoteUseCaseProxy') as InjectionKey<RemoteUseCaseProxy>,
getAppBakersUseCase: Symbol('getAppBakersUseCase') as InjectionKey<GetAppBakersUseCase>
getAppBakersUseCase: Symbol('getAppBakersUseCase') as InjectionKey<GetAppBakersUseCase>,
getPastriesUseCase: Symbol('getPastriesUseCase') as InjectionKey<GetPastriesUseCase>,
addPastryUseCase: Symbol('addPastryUseCase') as InjectionKey<AddPastryUseCase>
}

const appContainerDefinition: ContainerDefinition<typeof AppContainerKey> = {
Expand All @@ -20,6 +24,12 @@ const appContainerDefinition: ContainerDefinition<typeof AppContainerKey> = {
},
getAppBakersUseCase({ remoteUseCaseProxy }) {
return new GetAppBakersUseCase(remoteUseCaseProxy)
},
getPastriesUseCase({ remoteUseCaseProxy }) {
return new GetPastriesUseCase(remoteUseCaseProxy)
},
addPastryUseCase({ remoteUseCaseProxy }) {
return new AddPastryUseCase(remoteUseCaseProxy)
}
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/core/models/appbaker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Pastry } from './pastery'
import type { Pastry } from './pastry'

export interface AppBaker {
readonly id: string
Expand Down
File renamed without changes.
18 changes: 18 additions & 0 deletions frontend/src/core/use-cases/pastries/add-pastry.use-case.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type RemoteUseCaseProxy from '../remote-use-case-proxy'
import type { ApiResponse } from '../remote-use-case-proxy'

export default class AddPastryUseCase {
constructor(private remoteUseCaseProxy: RemoteUseCaseProxy) {}

public async execute(pastryName: string): Promise<ApiResponse<any, any>> {
const resp = await this.remoteUseCaseProxy.execute<
{ name: string },
Record<string, never>,
string
>('pastries', 'post', {
name: pastryName
})

return resp
}
}
17 changes: 17 additions & 0 deletions frontend/src/core/use-cases/pastries/get-pastries.use-case.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Pastry } from '@/core/models/pastry'
import type RemoteUseCaseProxy from '../remote-use-case-proxy'
import type { ApiResponse } from '../remote-use-case-proxy'

export default class GetPastriesUseCase {
constructor(private remoteUseCaseProxy: RemoteUseCaseProxy) {}

public async execute(): Promise<ApiResponse<Pastry[], any>> {
const dto = await this.remoteUseCaseProxy.execute<Record<string, never>, Pastry[], string>(
'pastries',
'get',
{}
)

return dto
}
}
9 changes: 7 additions & 2 deletions frontend/src/pages/app-bakers/AppBakersListView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<template>
<div class="flex flex-col">
<p v-for="appBaker of appBakers" :key="appBaker.id">{{ appBaker.name }}</p>
<div class="flex flex-col gap-2 grow">
<div v-for="appBaker of appBakers" :key="appBaker.id" class="flex flex-row gap-2">
<div>{{ appBaker.name }}</div>
<div>{{ appBaker.quota }}</div>
<div>{{ appBaker.flavours.join(" | ") }}</div>
<div>{{ appBaker.pastries.map((e) => e.name).join(" | ") }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
Expand Down
25 changes: 25 additions & 0 deletions frontend/src/pages/home/homePage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>

<div class="flex flex-col">
<h3 class="text-xl font-bold mb-6">AppBakery - BakeTime</h3>

<p class="text-m mb-8">What's bakin'?</p>

<div class="flex flex-row items-center gap-9">
<img src="@/assets/bakingApps.png">

<div class="flex flex-col gap-5">
<div><RouterLink class="text-blue-500 hover:text-red-500 transition-colors" to="/appbakers">AppBakers</RouterLink></div>
<div><RouterLink class="text-blue-500 hover:text-red-500 transition-colors" to="/pastries">Pastries</RouterLink></div>

</div>

</div>


</div>
</template>

<script setup lang="ts">
</script>

28 changes: 28 additions & 0 deletions frontend/src/pages/pastries/PastriesListPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<template>
<LoadingWrapper :state="state" :reload="doReload">
<PastriesListView :pastries="data" @added="doReload"></PastriesListView>
</LoadingWrapper>
</template>

<script setup lang="ts">
import { AppContainerKey } from '@/core/container/app-container'
import { injectStrict } from '@/core/container/inject'
import LoadingWrapper from '@/shared/components/LoadingWrapper.vue'
import PastriesListView from './PastriesListView.vue'
import { useLoading } from '../../shared/functions/use-loading'
import type { Pastry } from '../../core/models/pastry'
const getPastriesListUseCase = injectStrict(AppContainerKey.getPastriesUseCase)
const { state, data, load } = useLoading<Pastry[]>()
load(() => {
return getPastriesListUseCase.execute()
})
const doReload = () => {
load(() => {
return getPastriesListUseCase.execute()
})
}
</script>
47 changes: 47 additions & 0 deletions frontend/src/pages/pastries/PastriesListView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<div class="flex flex-col gap-2 grow">
<div v-for="pastry of pastries" :key="pastry.id" class="flex flex-row gap-2">
<div>{{ pastry.name }}</div>
</div>
<div class="flex flex-row gap-5 mt-5">
<input v-model="newName" placeholder="New Pastry Name" />
<PrimaryButton :disabled="newName.length <= 0" @click="savePastry">Save</PrimaryButton>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { AppContainerKey } from '@/core/container/app-container'
import { injectStrict } from '@/core/container/inject'
import { SavingState, useSaving } from '../../shared/functions/use-saving'
import type { Pastry } from '@/core/models/pastry';
import PrimaryButton from '@/shared/components/PrimaryButton.vue';
const addPastryUseCase = injectStrict(AppContainerKey.addPastryUseCase)
const { savingState, savedData, save } = useSaving<void>()
const newName = ref('')
const savePastry = async () => {
await save(() => {
return addPastryUseCase.execute(newName.value)
})
switch (savingState.value) {
case SavingState.Success:
emit('added')
break;
default:
break;
}
}
interface Props {
pastries: Pastry[]
}
const emit = defineEmits(['added'])
defineProps<Props>()
</script>
12 changes: 12 additions & 0 deletions frontend/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { createRouter, createWebHistory } from 'vue-router'
import AppBakersListPage from '../pages/app-bakers/AppBakersListPage.vue'
import HomePage from '@/pages/home/homePage.vue'
import PastriesListPage from '@/pages/pastries/PastriesListPage.vue'

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomePage
},
{
path: '/appbakers',
name: 'appbakers',
component: AppBakersListPage
},
{
path: '/pastries',
name: 'pastries',
component: PastriesListPage
}
]
})
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/shared/components/PrimaryButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template>
<button class="bg-sbb-red border border-transparent text-white px-4 py-3 rounded-full hover:bg-sbb-red-125 disabled:bg-sbb-milk disabled:text-sbb-granite disabled:border disabled:border-dashed disabled:border-sbb-smoke">
<slot />
</button>
</template>

<script lang="ts" setup>
</script>

15 changes: 13 additions & 2 deletions frontend/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,19 @@ module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
extend: {

}
colors: {
sbb: {
red: {
125: '#C60018',
DEFAULT: '#EB0000'
},
milk: '#F6F6F6',
granite: '#686868',
smoke: '#8D8D8D'
},
}
},

},
plugins: [
]
Expand Down

0 comments on commit f33fa0a

Please sign in to comment.