From e3a339980754c08d4fa7b05c418fc00a109eaa10 Mon Sep 17 00:00:00 2001 From: Jadowyne Ulve Date: Sat, 9 Aug 2025 21:25:27 -0500 Subject: [PATCH] Added the ability to delete a Recipe --- .../database_recipes.cpython-313.pyc | Bin 14910 -> 15707 bytes .../__pycache__/recipes_api.cpython-313.pyc | Bin 13633 -> 14355 bytes application/recipes/database_recipes.py | 14 ++++ application/recipes/recipes_api.py | 10 +++ .../recipes/static/js/recipesListHandler.js | 61 +++++++++++++++++- .../recipes/templates/recipes_index.html | 20 ++++++ 6 files changed, 102 insertions(+), 3 deletions(-) diff --git a/application/recipes/__pycache__/database_recipes.cpython-313.pyc b/application/recipes/__pycache__/database_recipes.cpython-313.pyc index 66f6f93a9683314d5b14b15de9e0793c4c1ca294..147a3b50d31d0c267eea89e79040bc9c260455df 100644 GIT binary patch delta 498 zcmdm2a=VJ}GcPX}0}uo;&B$1%Jdsa=(P^T(g|Bchixfi^V-b6>a4>5OM=)CqXE1vV zmkC=i2T+^^D8mhu0f{gLb3#RU5Nb_Wg1Mlgyurc~*C;azPrM*$if$GkRE;1)C)5^x zsEkms@MJkgNpp0af>3!844pzy8PRk`O_9wZjO$Gqe@$jFH)UGMIeCJh)Z{g?!XTy~ zuju4@b2sitpx^fbaq$v{$%-Z-lb@JRV*EV0+(LsXnR)U=d6CWbrbih0ib8=(subgk zQj;?aQYXusOPLpi0fmafL0UP1gaQl{@dJ6ccv4bxQcF^U!0L-)fI_E1Dj}Be-r$j# zAu@yQf}H&YE{Dk<&0D#OqJYwxj3Jt0lb2W&=z&}X)>R||VhMr>u(=#Ix%nxjIjMF< ri9j(%ATAbRoNR0PUF9nS52Nr$86Yts`2&c(z!XevQ27Spfz1E_&OLH_ delta 288 zcmcazwXcNlGcPX}0}!bG=+CH8oX97^s4-F9!dEDmMT#Mdv4}lbD3~>dBbY6QGnhSw z%Y-eM11Qb{l;H--fJB&rIiVsv2(>0G!CX*L-e94LYm^y3oa!R9;HHwGR?;UYnx F2mo`yK#l+a diff --git a/application/recipes/__pycache__/recipes_api.cpython-313.pyc b/application/recipes/__pycache__/recipes_api.cpython-313.pyc index ee5a6fae0d16e6064bbcba59caee9725e4b70aec..241808ba40d57a4736514e012f42fe964ea7690f 100644 GIT binary patch delta 1712 zcma)6Z)jUp6wiHmNne_#f3r3wZS%UMO<(^c&AJV`m02amwS%@cE9=mirO9iXE=|(= zUL5Uoae{Nmbd-xwQM>9FnG6&k_(drAQT<@L3Dr=+4}$0i8Prb`#dBT~TSdVK@AuC8 zopaAU=iGDdXNxRbyJxdi8{nDY))#*3T&s1E_ttz5iNp?*7f2J^ByGgbwn#5I#5RbV zSvY@*Wz(FW-6rkqU7aa#XUhDLv10MEv7d|RF4(rQf9(@DYvU`rB!6gaqs8be=^yEK z8jfKU@KnCkGtWsq+DrWRLZBfK%O(Q}IVG#|lpIfHn zM~ILUGX_KKarRXGV1v107%`$*ny{Vvb{3Ut4~vGUZGS2Gh$&(o;=BjBD)ySKJzr~x z2!mWnDOtwpFsz{+2rU3VeGahNS_(}p#hDP5Ts$r-%3Lm$TIrCuqFGU6YEGd+FiyTf zU`4N(RK#>f6=P{JmP%zV%L#EwRu?h}F_RY61<=arL^hMmr&YgHMS0xt2tZMom(}Q^ zl1WocjarebIanZC1(d{>R!2e?dp2-{VMma z-L+%)-m`n}+q*WeJh^QjykP-uePY|*2a@2}5jyV)otw#z+P)SZ-K}e0j~9AJx9i3V z!q~30aouy*_o4rezaR}2h7tvzyltH;@N?QTHi4@S2*lr`<^CVJ6sj?tp0-{uQl3d>uF2^t8kmfhZc4 zOS%2ciZ!{+Qgk^NORGtBg?6EfB!DDPw5IG0n>G$H?`?*nULq%r&6Hh z8roR^q_Uk}-aI2c9@DEpf1pV{Ka#vYoqFwXI`yK3AJ&w|6H^!Uimy7v%Q59&=Cz|z zK3x4AZf7~rjDyIIAne!Fj@gFF7ZkhIXCYzsX5Z=RTVVDvyvi1Pb|9#=_Rn$$qKl#v zJ;aMB;o*kqO%&$<%Hid*iI@r(!~S*hxA0P6`TxS3)*Vf;-viYxVcbOTQ&Z_+^=d^~ z`@nG%1Kk!oKkzg0vQY3CiLlk+BpGL428U+!i$hv?5dxu;1jwCil8f@sEeR>6?73K5#&vH5uNvJLkK_k9-i|)@A=OAyyyKO@n*Jk zucSnOggwi<8#5Ko_0no`VcoS)Two_lqztx*l~lkha#XAwHsK12gr;m9&NG&cJ>u+x z(3e}ciFxIY*a&~cI`}9y3b_whrMwuIOwzRAacl3TuZ5aeE(rP{D}^F7Lz(fRE+Y*N z43B8fjD-T})U-++Dehq62tCcvQv&T}HSonWQr^Xuv>V|h!WlSK<&cLMZP(PQm_$Zk z$KsJMvOvG~#}X3iIx)@0AfrnsV$qaJ&1~^hpbaR5A!2oq4!CV?B_VieZ6;y(X?5tw znK;JYEBl z#xSj>u%PZ}Dw^|#S{z{(VGiLxr@E|Dya~$BLeCiqtEZRYgv%zUSzuWkcYPAbC>wc#>hzWc=$~KIKzBqD0Y@&+bFh&q6NAJ?*bOXCZmMC$!`Mu L4t&-~t5Ns||7i08 diff --git a/application/recipes/database_recipes.py b/application/recipes/database_recipes.py index 920822d..b6fad27 100644 --- a/application/recipes/database_recipes.py +++ b/application/recipes/database_recipes.py @@ -190,6 +190,20 @@ def postDeleteRecipeItem(site:str, payload:tuple, convert:bool=True): database_config = config.config() deleted = () sql = f"DELETE FROM {site}_recipe_items WHERE id=%s RETURNING *;" + with psycopg2.connect(**database_config) as conn: + with conn.cursor() as cur: + cur.execute(sql, payload) + rows = cur.fetchone() + if rows and convert: + deleted = postsqldb.tupleDictionaryFactory(cur.description, rows) + elif rows and not convert: + deleted = rows + return deleted + +def deleteRecipe(site:str, payload:tuple, convert:bool=True): + database_config = config.config() + deleted = () + sql = f"DELETE FROM {site}_recipes WHERE id=%s RETURNING *;" with psycopg2.connect(**database_config) as conn: with conn.cursor() as cur: cur.execute(sql, payload) diff --git a/application/recipes/recipes_api.py b/application/recipes/recipes_api.py index 8157925..45a4b83 100644 --- a/application/recipes/recipes_api.py +++ b/application/recipes/recipes_api.py @@ -46,6 +46,16 @@ def getRecipes(): return jsonify({'recipes': recipes, 'end': math.ceil(count/limit), 'error': False, 'message': 'fetch was successful!'}) return jsonify({'recipes': recipes, 'end': math.ceil(count/limit), 'error': True, 'message': f'method is not allowed: {request.method}'}) +@recipes_api.route('/api/deleteRecipe', methods=["POST"]) +@access_api.login_required +def deleteRecipe(): + if request.method == "POST": + recipe_id = request.get_json()['recipe_id'] + site_name = session['selected_site'] + database_recipes.deleteRecipe(site_name, (recipe_id, )) + return jsonify(status=201, message="Recipe deleted successfully!") + return jsonify(status=405, message=f"{request.method} is not an allowed method on this endpoint.") + @recipes_api.route('/getRecipe', methods=["GET"]) @access_api.login_required def getRecipe(): diff --git a/application/recipes/static/js/recipesListHandler.js b/application/recipes/static/js/recipesListHandler.js index cda669f..9989c49 100644 --- a/application/recipes/static/js/recipesListHandler.js +++ b/application/recipes/static/js/recipesListHandler.js @@ -177,17 +177,25 @@ async function replenishRecipesCards() { footer_div.style = 'height: 40px; border: none;' let editOp = document.createElement('a') - editOp.setAttribute('class', 'uk-button uk-button-small uk-button-default') + editOp.setAttribute('class', 'uk-button uk-button-small uk-button-primary') editOp.innerHTML = ' Edit' editOp.style = "margin-right: 10px;" editOp.href = `/recipes/edit/${recipes[i].id}` let viewOp = document.createElement('a') - viewOp.setAttribute('class', 'uk-button uk-button-small uk-button-default') + viewOp.setAttribute('class', 'uk-button uk-button-small uk-button-primary') viewOp.innerHTML = ' View' viewOp.href = `/recipes/view/${recipes[i].id}` + + let deleteOp = document.createElement('button') + deleteOp.setAttribute('class', 'uk-button uk-button-small uk-button-danger') + deleteOp.innerHTML = ' Delete' + deleteOp.onclick = async function() { + await openDeleteRecipeModal(recipes[i].id) + } - footer_div.append(editOp, viewOp) + + footer_div.append(editOp, viewOp, deleteOp) main_div.append(card_header_div, body_div, footer_div) @@ -242,6 +250,53 @@ async function addRecipe() { } +var select_recipe_id_to_delete = 0 +async function openDeleteRecipeModal(recipe_id) { + select_recipe_id_to_delete = recipe_id + document.getElementById('deleteRecipeConfirm').value = "" + UIkit.modal(document.getElementById('deleteRecipeModal')).show(); +} + + +async function deleteRecipe() { + let confirm = String(document.getElementById('deleteRecipeConfirm').value) + if (confirm === "DELETE"){ + const response = await fetch(`/recipes/api/deleteRecipe`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + recipe_id: select_recipe_id_to_delete + }), + }); + data = await response.json(); + transaction_status = "success" + if (data.error){ + transaction_status = "danger" + } + + UIkit.notification({ + message: data.message, + status: transaction_status, + pos: 'top-right', + timeout: 5000 + }); + recipes = await getRecipes() + await replenishRecipes() + await updatePaginationElement() + UIkit.modal(document.getElementById('deleteRecipeModal')).hide(); + } else { + UIkit.modal(document.getElementById('deleteRecipeModal')).hide(); + UIkit.notification({ + message: "Confirmation Incorrect!", + status: "danger", + pos: 'top-right', + timeout: 5000 + }); + } +} + async function updatePaginationElement() { let paginationElement = document.getElementById("paginationElement"); paginationElement.innerHTML = ""; diff --git a/application/recipes/templates/recipes_index.html b/application/recipes/templates/recipes_index.html index ed76676..841695c 100644 --- a/application/recipes/templates/recipes_index.html +++ b/application/recipes/templates/recipes_index.html @@ -156,6 +156,26 @@ + +
+
+ +
+

Delte Recipe...

+
+
+

You are attempting to delete something that will be hard to get back, please confirm you want to + complete this action by typing the DELETE in the box below!

+

+
+ +
+
+ +
+