From 5bb1329f690a64c0766b1ef3dffaab31833c30d0 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Fri, 21 Jun 2024 00:17:41 +0200 Subject: [PATCH] proof add: basic dedicated page --- src/components/ProofInputRow.vue | 6 +- src/i18n/locales/en.json | 10 ++ src/router.js | 3 +- src/services/api.js | 13 ++- src/views/AddPriceMultiple.vue | 4 +- src/views/Home.vue | 16 ++- src/views/ProofAddSingle.vue | 170 +++++++++++++++++++++++++++++++ 7 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 src/views/ProofAddSingle.vue diff --git a/src/components/ProofInputRow.vue b/src/components/ProofInputRow.vue index 6ee6711e4d..87a193cf5b 100644 --- a/src/components/ProofInputRow.vue +++ b/src/components/ProofInputRow.vue @@ -15,7 +15,7 @@ {{ $t('AddPriceSingle.PriceDetails.Gallery') }} {{ $t('AddPriceSingle.PriceDetails.SelectFromGallery') }} - + {{ $t('AddPriceSingle.PriceDetails.RecentProof') }} {{ $t('AddPriceSingle.PriceDetails.SelectRecentProof') }} @@ -104,6 +104,10 @@ export default { type: Object, default: () => ({ proof_id: null, date: utils.currentDate() }) }, + hideRecentProofOption: { + type: Boolean, + default: false + }, }, data() { return { diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index b61856047e..70dae58253 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -113,12 +113,14 @@ "Language": "Languages", "Locations": "Locations", "Date": "Date", + "Details": "Details", "Delete": "Delete", "Discount": "Discount", "Edit": "Edit", "Filter": "Filter", "FilterProductWithPriceCountHide": "Hide products with prices", "FilterPriceMoreThan30DaysHide": "Hide prices older than 30 days", + "Image": "Image", "Order": "Order", "OrderProductUniqueScansDESC": "Number of scans", "OrderProductPriceCountDESC": "Number of prices", @@ -127,6 +129,7 @@ "OrderPriceDateDESC": "Price date", "SignInOFFAccount": "Sign in with your {url} account", "Source": "Source", + "Type": "Type", "Yes": "Yes", "No": "No", "Food": "Food", @@ -158,6 +161,7 @@ "Home": { "AddPrice": "Add a price", "LatestPrices": "Latest prices", + "ProofAdd": "Add a proof", "SearchProduct": "Search for a product", "SettingsUpdated": "Settings updated!", "TodayPriceStat": "No prices added today | {todayPriceNumber} new prices added today | {todayPriceNumber} new prices added today!", @@ -278,6 +282,9 @@ "RECEIPT": "Receipt", "GDPR_REQUEST": "GDPR request" }, + "ProofCreate": { + "Success": "Proof created!" + }, "ProofDelete": { "Confirmation": "Are you sure you want to delete this proof?", "Delete": "Delete", @@ -307,6 +314,9 @@ "LatestPrices": { "Title": "Latest prices" }, + "ProofAddSingle": { + "Title": "Add a proof" + }, "Search": { "Title": "Search" }, diff --git a/src/router.js b/src/router.js index 0742d877e8..e7b04e4cbb 100644 --- a/src/router.js +++ b/src/router.js @@ -12,7 +12,7 @@ const routes = [ { path: '/settings', name: 'settings', component: () => import('./views/UserSettings.vue'), meta: { title: 'Settings', requiresAuth: true } }, { path: '/search', name: 'search', component: () => import('./views/Search.vue'), meta: { title: 'Search', icon: 'mdi-magnify', drawerMenu: true }}, { path: '/prices', name: 'prices', component: () => import('./views/PriceList.vue'), meta: { title: 'LatestPrices', icon: 'mdi-tag-multiple-outline', drawerMenu: true }}, - { path: '/prices/add', name: 'add-price', component: () => import('./views/AddPriceHome.vue'), meta: { title: 'AddPrice', icon: 'mdi-plus', drawerMenu: true, color: 'primary', requiresAuth: true }}, + { path: '/prices/add', name: 'price-add', component: () => import('./views/AddPriceHome.vue'), meta: { title: 'AddPrice', icon: 'mdi-plus', drawerMenu: true, color: 'primary', requiresAuth: true }}, { path: '/prices/add/single', name: 'add-price-single', component: () => import('./views/AddPriceSingle.vue'), meta: { title: 'Add a single price (price tag)', requiresAuth: true }}, { path: '/prices/add/multiple/price-tag', name: 'add-price-multiple-price-tag', component: () => import('./views/AddPriceMultiple.vue'), meta: { title: 'Add multiple prices (price tags)', requiresAuth: true }}, { path: '/prices/add/multiple/receipt', name: 'add-price-multiple-receipt', component: () => import('./views/AddPriceMultiple.vue'), meta: { title: 'Add multiple prices (receipt)', requiresAuth: true }}, @@ -22,6 +22,7 @@ const routes = [ { path: '/locations/:id', name: 'location-detail', component: () => import('./views/LocationDetail.vue'), meta: { title: 'Location detail' }}, { path: '/brands/:id', name: 'brand-detail', component: () => import('./views/BrandDetail.vue'), meta: { title: 'Brand detail' }}, { path: '/categories/:id', name: 'category-detail', component: () => import('./views/CategoryDetail.vue'), meta: { title: 'Category detail' }}, + { path: '/proofs/add/single', name: 'proof-add', component: () => import('./views/ProofAddSingle.vue'), meta: { title: 'ProofAddSingle', icon: 'mdi-plus', color: 'primary', requiresAuth: true }}, { path: '/proofs/:id', name: 'proof-detail', component: () => import('./views/ProofDetail.vue'), meta: { title: 'Proof detail', requiresAuth: true }}, { path: '/users', name: 'users', component: () => import('./views/UserList.vue'), meta: { title: 'TopContributors', icon: 'mdi-account-star-outline', drawerMenu: true }}, { path: '/users/:username', name: 'user-detail', component: () => import('./views/UserDetail.vue'), meta: { title: 'User detail' }}, diff --git a/src/services/api.js b/src/services/api.js index 2ab992eb23..e6d0fcbeee 100644 --- a/src/services/api.js +++ b/src/services/api.js @@ -14,6 +14,16 @@ function buildURLParams(params = {}) { return new URLSearchParams({...DEFAULT_PARAMS, ...params}) } +function filterParamsWithAllowedKeys(params, allowedKeys) { + const filteredParams = {} + for (const key in params) { + if (allowedKeys.includes(key)) { + filteredParams[key] = params[key] + } + } + return filteredParams +} + export default { signIn(username, password) { @@ -84,6 +94,7 @@ export default { }, updateProof(proofId, params = {}) { + const PROOF_UPDATABLE_FIELDS = ['type', 'date', 'currency'] const store = useAppStore() const url = `${import.meta.env.VITE_OPEN_PRICES_API_URL}/proofs/${proofId}?${buildURLParams()}` return fetch(url, { @@ -91,7 +102,7 @@ export default { headers: Object.assign({}, DEFAULT_HEADERS, { 'Authorization': `Bearer ${store.user.token}`, }), - body: JSON.stringify(params), + body: JSON.stringify(filterParamsWithAllowedKeys(params, PROOF_UPDATABLE_FIELDS)), }) .then((response) => response.json()) }, diff --git a/src/views/AddPriceMultiple.vue b/src/views/AddPriceMultiple.vue index 97dc35e5bf..e2d40f147a 100644 --- a/src/views/AddPriceMultiple.vue +++ b/src/views/AddPriceMultiple.vue @@ -238,10 +238,10 @@ export default { origins_tags: '', labels_tags: [], price: null, - price_per: null, // see initPriceSingleForm + price_per: null, // see PriceInputRow price_is_discounted: false, price_without_discount: null, - currency: null, // see initPriceMultipleForm + currency: null, // see PriceInputRow }, categoryPricePerList: [ {key: 'KILOGRAM', value: this.$t('AddPriceSingle.CategoryPricePer.PerKg'), icon: 'mdi-weight-kilogram'}, diff --git a/src/views/Home.vue b/src/views/Home.vue index f1e4f014f6..3583bd89b4 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -57,6 +57,13 @@ + + {{ $t('ProofCreate.Success') }} + +

+ {{ $t('Home.ProofAdd') }} +

+ + + + + + + + + + + + + + {{ pt.value }} + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ {{ $t('AddPriceSingle.WhereWhen.Date') }} +

+ + + + + +
+ +
+
+
+ + + + + {{ $t('AddPriceSingle.Create') }} + + + +
+ + +