From 928a2e5ee0798202f610c01c18c2d715019e0ee1 Mon Sep 17 00:00:00 2001
From: a2-imeri <Alfret2.imeri@live.uwe.ac.uk>
Date: Thu, 16 May 2024 10:25:58 +0100
Subject: [PATCH] Intigrate rules with Admin

---
 .gitignore                                    |   7 +-
 MisplaceAI/Dockerfile                         |   1 +
 .../templates/admin_app/admin_dashboard.html  |   5 +-
 .../__pycache__/apps.cpython-310.pyc          | Bin 419 -> 419 bytes
 MisplaceAI/docker-compose.yml                 |   1 +
 .../rules/__pycache__/__init__.cpython-39.pyc | Bin 198 -> 0 bytes
 .../rules/__pycache__/admin.cpython-39.pyc    | Bin 239 -> 0 bytes
 .../rules/__pycache__/apps.cpython-39.pyc     | Bin 454 -> 0 bytes
 .../rules/__pycache__/forms.cpython-310.pyc   | Bin 1154 -> 1102 bytes
 .../rules/__pycache__/models.cpython-310.pyc  | Bin 549 -> 1176 bytes
 .../rules/__pycache__/models.cpython-39.pyc   | Bin 630 -> 0 bytes
 .../rules/__pycache__/urls.cpython-310.pyc    | Bin 499 -> 915 bytes
 .../rules/__pycache__/utils.cpython-310.pyc   | Bin 2064 -> 0 bytes
 .../rules/__pycache__/views.cpython-310.pyc   | Bin 1714 -> 3741 bytes
 MisplaceAI/rules/forms.py                     |  28 ++---
 MisplaceAI/rules/migrations/0001_initial.py   |  25 +++-
 .../__pycache__/0001_initial.cpython-310.pyc  | Bin 684 -> 1095 bytes
 MisplaceAI/rules/models.py                    |  19 ++-
 .../rules/templates/rules/add_rule.html       |  26 ++--
 .../rules/templates/rules/admin_add_item.html |  58 +++++++++
 .../templates/rules/admin_add_location.html   |  57 +++++++++
 .../rules/templates/rules/confirm_delete.html |  21 ++--
 .../templates/rules/confirm_delete_item.html  |  15 +++
 .../rules/confirm_delete_location.html        |  17 +++
 .../rules/templates/rules/edit_item.html      |  16 +++
 .../rules/templates/rules/edit_location.html  |  16 +++
 .../rules/templates/rules/list_rules.html     |  66 ++++++----
 .../rules/templates/rules/rule_detail.html    |  22 +++-
 .../rules/templates/rules/update_rule.html    |  21 +++-
 MisplaceAI/rules/urls.py                      |  19 ++-
 MisplaceAI/rules/utils.py                     |  70 +++++------
 MisplaceAI/rules/views.py                     | 116 ++++++++++++++----
 README.md                                     |  78 ++++++++++++
 33 files changed, 554 insertions(+), 150 deletions(-)
 delete mode 100644 MisplaceAI/rules/__pycache__/__init__.cpython-39.pyc
 delete mode 100644 MisplaceAI/rules/__pycache__/admin.cpython-39.pyc
 delete mode 100644 MisplaceAI/rules/__pycache__/apps.cpython-39.pyc
 delete mode 100644 MisplaceAI/rules/__pycache__/models.cpython-39.pyc
 delete mode 100644 MisplaceAI/rules/__pycache__/utils.cpython-310.pyc
 create mode 100644 MisplaceAI/rules/templates/rules/admin_add_item.html
 create mode 100644 MisplaceAI/rules/templates/rules/admin_add_location.html
 create mode 100644 MisplaceAI/rules/templates/rules/confirm_delete_item.html
 create mode 100644 MisplaceAI/rules/templates/rules/confirm_delete_location.html
 create mode 100644 MisplaceAI/rules/templates/rules/edit_item.html
 create mode 100644 MisplaceAI/rules/templates/rules/edit_location.html

diff --git a/.gitignore b/.gitignore
index 29f259e..3c37699 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
+# Ignore all __pycache__ directories
 __pycache__/
-**/migrations/*
-!**/migrations/__init__.py
-registration
\ No newline at end of file
+
+# Ignore all migrations directories
+migrations/
diff --git a/MisplaceAI/Dockerfile b/MisplaceAI/Dockerfile
index 2751409..bbeaee3 100644
--- a/MisplaceAI/Dockerfile
+++ b/MisplaceAI/Dockerfile
@@ -1,3 +1,4 @@
+#Dockerfile
 # Use the full Python runtime as a parent image
 FROM python:3.10
 
diff --git a/MisplaceAI/admin_app/templates/admin_app/admin_dashboard.html b/MisplaceAI/admin_app/templates/admin_app/admin_dashboard.html
index 93e3301..7d43f1d 100644
--- a/MisplaceAI/admin_app/templates/admin_app/admin_dashboard.html
+++ b/MisplaceAI/admin_app/templates/admin_app/admin_dashboard.html
@@ -10,7 +10,10 @@
             <h1>Admin Dashboard</h1>
             <div class="list-group">
                 <a href="{% url 'admin_users' %}" class="list-group-item list-group-item-action">Users Activity</a>
-                <!-- Add other admin links here -->
+                <a href="{% url 'rules:list_rules' %}" class="list-group-item list-group-item-action">Manage Rules</a>
+                <a href="{% url 'rules:admin_add_location' %}" class="list-group-item list-group-item-action">Add
+                    Location</a>
+                <a href="{% url 'rules:admin_add_item' %}" class="list-group-item list-group-item-action">Add Item</a>
             </div>
         </div>
     </div>
diff --git a/MisplaceAI/authentication/__pycache__/apps.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/apps.cpython-310.pyc
index 3d7bbc9a78b073b047dfd0b96999c880a622acb1..aac04fde8475c476d4a28433344a6abb5dedec2d 100644
GIT binary patch
delta 65
zcmZ3?yqI~yX~tU<&jhn^F)%O`aZOfb4AFux!F&+G&A`BLi^C>2KczG$)sB&YfuWd%
Lfq{XCL4*ka2IdU$

delta 65
zcmZ3?yqI~yX~w9DXM)){85kIfI47$zhG;>UU_OZ8Vqjpn#bJ}1pHiBWYRAaHz);M>
Lz`(%6Ai@Ly=;#b<

diff --git a/MisplaceAI/docker-compose.yml b/MisplaceAI/docker-compose.yml
index 216683c..dc72d67 100644
--- a/MisplaceAI/docker-compose.yml
+++ b/MisplaceAI/docker-compose.yml
@@ -1,3 +1,4 @@
+#docker-compose.yml
 version: '3.7'
 
 services:
diff --git a/MisplaceAI/rules/__pycache__/__init__.cpython-39.pyc b/MisplaceAI/rules/__pycache__/__init__.cpython-39.pyc
deleted file mode 100644
index cf5573c4ac264229497c6125f1ed0780162d5844..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 198
zcmYe~<>g{vU|=ZR=aL4ZAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_WjkBN
zgche3700+0rKY6B_~)g%6lIpB#<=7sm*%GCl@!OgW#%R3C{(5<7R6+yq~?`mre!84
zmSpDV>E@^D=4KWb<Rm7irs!stq~;dK_(J)Po-swGIjO}l@$s2?nI-Y@dIgoYIBatB
PQ%ZAE?LdzB400?0PM$Wy

diff --git a/MisplaceAI/rules/__pycache__/admin.cpython-39.pyc b/MisplaceAI/rules/__pycache__/admin.cpython-39.pyc
deleted file mode 100644
index 1bf9591e9ac3cc1c8238693e6444b34c1696be78..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 239
zcmYe~<>g{vU|=ZR=aS~cz`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl(
zn#?ajYBd>eu_mVEX6E^6GDY#FWF_XM=j$cs=am#?CKZ7USjkYt%)kI4eq}gY#e^28
z78S?16{V)6#Q5i>x)f!WrN+4ACzs}?=9Lu3xMk)g<|tIACKknHrljVTWTs^%CzfR9
z=jrCB>E>n@7vv-+r>5v;mZatu$M{0|j-D|^r8%j^F<__Y6;$5hu*uC&Da}c>V`N}p
I_zZF>0BYVs5C8xG

diff --git a/MisplaceAI/rules/__pycache__/apps.cpython-39.pyc b/MisplaceAI/rules/__pycache__/apps.cpython-39.pyc
deleted file mode 100644
index 31706469dbe44504ed6dba139fb1d69414c59785..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 454
zcmYe~<>g{vU|<lt;gYtIfq~&Mh=Yt-7#J8F7#J9e6&M&8QW#Pga~N_NqZk<(+!<1s
zQkYv9QkYX2o0+4SQdoi+G+AGQ^lCER;&d!1aL&(5%S=xOi6CP}n290`3=F9ZQH&`J
zQA{a}QOqe!Q7kFU!3>%#x445!b5e^T21KzIfjCtHU@-;X#Jt4x)ZEm(5<gAWTO9H6
zd5O8H@$t8~;^TAkQ%Z9{Y@Yb|!qUVXs0<5;zQt3PT9lMuoC;RIlA(x`fdNANN_V!3
z2`x@7Dvoh0N=-?L@y|<jDatHMjd96OE(KXs9OIUmmzbkanVMJ>lbMp5SCW~QnVeXX
znV+YdpQf9eSzM5ln4FrTn^}^YTO8vH<vV)DfL$JwSWr-`S5R5R%)r0^!o{FK<zQrC
v1dI4-GT-7($x6&i&({N~EMfw=45SX>MhFWOQ@1#5Al|eCg<~;DEe{g_3UqXI

diff --git a/MisplaceAI/rules/__pycache__/forms.cpython-310.pyc b/MisplaceAI/rules/__pycache__/forms.cpython-310.pyc
index 7417812a7a9b27f25d270f78b952272824883522..48868c69e39a330151c6a798a8488645e623b8dc 100644
GIT binary patch
literal 1102
zcmd1j<>g{vU|@JH?V2{3k%8ech=Yt-7#J8F7#J9eqZk+%QW#Pga~N_NqZk<(QkYVh
zbC`0OqnLA9qF8cSqgWXk+!<0>QdnCUQdm<Nv)G!MquAXUQrJ@1TNqN<p&}ga3@IEb
zoGlC~oKO+Y6s}+fP41T<TQwPPv8Lr0<rcqWWME*>WWL1`RGO1|i^C^BIk6-&KkpWc
zXGv;qGDs;hW`;WQvlIgZLn=cQV+unQlRHBSV+vCXLkd$fQxtOwb1;J@%PkI&d2abd
zm}W3R%_x>YG9#5aiY1*Pg>eyM6l)4oFoPy@6)(&LJ>S%lM356pi&Kkkv1FE{=HBAW
zfjYF<Pm}EyM|^x<Vs2`D{4K8d_}u)I(i{+*CqBNgG%*JvQv?d%TdcYHDXBTP*wQjn
zb5e>|G873iFhGc3!up8?1^Pv$IjP0^;E>TPsJz7jvYHhXD{Kr53>*wBj694*!VC-y
zek)muctCo2K?EO&00|?^gRq1^5*!Q+3?SP-g9r`=A;uz*2+puAVh6<t%Pk&QTwo1F
zP_%)P%V#mPP)uP=M}(muvKioTyu|_v4?j&dbmxP7S;P-=uK<XE2Mm%&Kt2Q|;?J<a
z;DQE5kq9m=AlGq%Bt=04h)2-h9H5kk*Uv@bpb%oN;)SUM`>Y6*p0Icf<X9p+2KKrn
z$dw>(`r-BxDCvVE9PA|!&rg%<7F$YIVqSWF5h!)vVgo0$VsM%(0tYO}5w|#fL8%Yq
sHE;?j0tH7A$N)$fBZ3^1Y;JMbKvJ?DD5{G=;m*S#!YITf#45%L0PsG*!~g&Q

literal 1154
zcmd1j<>g{vU|{%l!6hw;nStRkh=Yt-7#J8F7#J9e^%xi!QW#Pga~N_NqZk<(QkYVh
zbC`0OqnH^P+!<0>QdnCUQdm<Nvsjv$qgYeef*CZ~UxG~1WW2?imS2=x{F0G@fkBh;
z7E4fRPHHkp3K=uQEHYwXU`S<%VoYI(Vsd9lVN79aVMt+WW{P4?VNPLbVTfW$VNGFc
zVTfW)VNc;`VTfW&;S6Tb<hsQHGS@A?C>O(QCYae0NM@%pN3o<cq%baGjABh;3TDt`
zuHuE6py!)flBmgiizP2HH}w{0a(-S)W=Up#-YvGoWDxDA$##n)J{}|+AAgH0K0Y@;
zr8FlsKK>R@e0*VPVh%*62o!p^Sab7JQgd#xrDdk(q!h1YDB@#afDpfg^%DyU^ovS!
zQj7J$VWd}3d5Z;PIV&j4*%%lYI2c$Mc^HcX7#J9mK>-L0GmxJ^Vdl)h!0=g)fq|ih
zA&X%FV+!L!##+W2#$w(QrUlF?ObZ#C7;6|ozVj;r8CRtel98$aa-IU%JqpQ*d3pII
z3Q4I7IjLzS3Q0MMdD(g^S#I$p=cFd)rKZHEB$g!JVopyjDFRt}i$5$eCo?4x6bi0I
zMfpXVOt)ByQ*+Y5rX##o#LvLMaEl9U2soTLLGI*WU|`^3WMSlDWMQllhKDvn6;3Y}
z34#(2vtJQA0|P^qCdd=;Si$F$A|a4IrXn#=n1l49JCPq^IovRiyNf{Sq)GzKeQ+g&
z9SQPhl^V#Akn}>d3qcyuT?mPZc!)`&Ab)_JCyM4gh`gUBdl4w8i$K}Bh#RCDlyr*3
zK`coSAq67fNf2Tg*wdgS2THKTAgvq>e2g3{9Be#nMIdodf@e#~O3X{oha>|waH1}T
oq;O7OPzncSJ+NYknFuRDrr+YQf#eZ8P$Dh{B}E<v9!4=H0I`z&aR2}S

diff --git a/MisplaceAI/rules/__pycache__/models.cpython-310.pyc b/MisplaceAI/rules/__pycache__/models.cpython-310.pyc
index 2824feb030c55b134bd72336e3f50b46a45a196a..8b2afb9c30caa32b45e9aa9b932de5cb8dc483e2 100644
GIT binary patch
literal 1176
zcmd1j<>g{vU|{&I=$cl{#K7<v#6iX^3=9ko3=9m#K@1EGDGVu$ISjdsQH+crHd78$
zE^`z!BZE6b3Udle3quM^Dq|K)GjkNHJ3|U<3R??93L8{}&7C2IJ%yu%A%z1f!k)qz
z%%I8j5@eeu<1Mz_{FKz3Vok<dETP4zMadvxWDIl2XC(#(hE#?q#uSDqrc~xEmK4Sm
zrWEF0rYP1FmK4?&hA6fawqOQL_FEi2`N@eTnfZAy|1&T!gsfz`#g&^_5ucNqmtK-_
zi>)*-v#>NZnGwkn5F3P@85kHovoSC*)G%Z*1T(B;^jpbzizP2HHx)z|r{<)sWGE6~
zU|{$qqMuk$pkGv)lUl3~@qk`I<t_I3_~MeH_;_}ZIZO-;3~Y>50x;L;K_&fGvftu}
zj|Z6=AAgH0K0Y@;r8FlsKK>R@e0*VPVh%*62&DfOr*lSPky~bJPD&9k0|P^m5QqS|
z0PGA1AqWy<Wnf?c1r^x&91MJnJWNF(F`VI91X8WZev8GkBsI4P<mr$ikh^gPOc5x-
z6mf$r;{g$TAOhhOuq!~$1G`h0fq|il2V^wd+eIR%8o*k?x}+Ew7{G>0f>eNbI9*+A
zhn5ObSyP#_*ismKnWET1sUnpF&gV>JUci;gy^t}A2b5A;7@~MnSb`ZeS#PlfmFA>s
zGT!3M&x=n<%}Fi6Ob(#X2PKDMkT*feA&YS~Lki<ureFq5Cci3H1+WoJw^%Yk!3Xv;
zNF^jj5MBcXh$tu<fz0D$tl|M_g9nKwUlB;MNDSm}aS#Dgc8kj`zbG{`J<mI}vWS_1
zf#DXrvtzKcql@b;meS(Xq9RZT70H4m_<a-eDns%?BqWi5qWl(T4m1N4<4!Nq3=9k)
zXBLA3o`XSvQGk&Plx9HUewrM&I8(9`^V0M6Qj#DEQ3}dW&d)0;%1qKrEG@~<gQR?j
u8(Dop`52t$APxkXgcKYg%ZfnJeT%~elH%<^Sq^MJ4+9UQ5R(v_7#jeJd*q1#

delta 391
zcmbQixs-)3pO=@5fq{YH35RRiJBEpTG8Re<3=Am@DU3M`xr|Yaj12A!DNHHMEet8l
zsf<}n&CF5EDJ;PZnyfED+B6w&vE}Bcq~;VSPZX4NHDX|3NM(p(Oks#(N@dPsNnr%(
z?PZE$O=VudwvZu;9ZGYgu%xiIFhp^tumv+{vfp9}D$PlK`JaJ-Aw+ZH8$G3BHU<WU
z8ip)}U<OS_KTXD4EP08!sUW&IH79K)LlNg>8%8A=4h9B>VkQO#1~$ej9*_}w@$tna
zMe*@|np~6X7)|Th85kIDafYN;l(=Q4=A_)>OwP|s$t=mt&%4Ezm<*zexEUB2ia1dT
zP>>WcGcYiKa50F-!NAAJ!N|eL!vq%h(`32DnUa;5m!7Yel2in8!Yx)`P(XmCVdg2r
dj0PETi^C>2KczG$)s7M5Y!(Iv1|9}6CIC3eRYw2-

diff --git a/MisplaceAI/rules/__pycache__/models.cpython-39.pyc b/MisplaceAI/rules/__pycache__/models.cpython-39.pyc
deleted file mode 100644
index 3f0a1653bc660437e4e5e302b81d9b463a2ebb6f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 630
zcmYe~<>g{vU|<N??~?Y8fq~&Mh=Yt-7#J8F7#J9el^7TpQW#Pga~N_NqZk<(+!<1s
zQkYv9QkYX2vzVHhqnJ}zf*CYfUxIXNGTvg#%}+_qDNY7)kulsrBL)VBRE8+V6ox3K
zROT#}6h@GNy-ZQ8smu%57BWP!Lurl_mK4?&hA7SywqOQL_FF7Lr8%iD|1&T!glIC|
z;>t~|h|fvQOE1Z|#a5b^Sy-By%!p(mhz-KdAWyI{Ffi0GWHAIYXfpa~GTvgzOUz9L
z(Z#7bX)76uI2jlieq}ma#e^2878S?16{V)6#Q5i>x)f!WrN+4ACzs}?=9Lu3xMk)g
z<|tIACKknHrljVTWTs^%CzfR9=jrCB>E>n@7vv-+r>5v;mZatu$M{0|j-D|^r8%j^
zF_4haE2zB19v@#^QWPK00dgD@$kmKhJRtAsK_&b&xo&a9$Ag?1AAgH0K0Y@;r8Fls
zKK>R@e0*VPVh%*62&DHGr*lSPky~bJPD&9w0|Ub?&XClK5-|T3XL5dCN+!sKx7ZSs
zL39x}0|UgvU|&NBP+BNrW?*0d;bM@hI2idDIT$&Zz@mPdEVnpQvJ&&s^Yv1aAeOTF
fg5nu04KV{0h7cCWv|AiD5GUJ#BB2=MP97!zpJ19U

diff --git a/MisplaceAI/rules/__pycache__/urls.cpython-310.pyc b/MisplaceAI/rules/__pycache__/urls.cpython-310.pyc
index 0afb21aa3fd21a6317c48e6bf1b3afcfbcfb2731..9b94bafd72cfdc090116bbe497c908634a18faf0 100644
GIT binary patch
literal 915
zcmd1j<>g{vU|{%h!8PqCGXuk85C<9aGcYhXFfcF_UtnNhNMT4}%wfo7jACSDNMTB0
z&SA=Bj$+PbiDJoRjbhDZi(<=Vk7Cc|h~miQjN;7YisH)Uj^fVciQ>uSjpAiwNMVWM
zOJz)9O=V7DOJVP2PGwBtNM%XkgtEC(SyQ;7Y@SrM6kaHsFO@xoAIcU;<wy~PvV~GP
zQ-q;xkyNe}Q7Bt1l{-Zo%9cpwNs)xIrBZoQq(SU-?kN5gnP3J@*_R-{YBJtpDM&2I
zc*)4Xz@W)}iz_FyxFo))G$*zA7Dr-A3Yd9|BRv%&c#FFzH8;O36(Y=CT9A@h0_6xL
zrsQVk#e?+Z<R>SVWaj7H;zNjKmZaw1;!I7+EQtp*xl>YeQcF@H9A2<ETpK@B4lck7
zaS%fh3&@p>w^;HLb5pBW5>rz2i&z;L7^?VeGV@BTK&s+1Q|$DM*g%4!5Vz{1$+3gw
zAWlb@;{eGCBU}x0fqoGuNQNIF1M-A^5hwvwNq}7s764lXVnLk24bmh9^$kcEVjqYF
zQNROIpa9knw+d_qj0aK13sR;8H3udIF$>0nDCA>cVDQrvxW%24m6(^FuUA@>Q(VNv
zz`$^ewJbBWycisS;2;ABQ4uICia?$Q`w#4$B9NntKn^PcSz81$@)k#8K|wqy&~I^<
z7UdKqmXxFx<rS}FC=z2}fDpfg^b-pT^g&TjtPiqQub}c4hfQvNN@-529Vm4b%P}x8
U@GzJ#vas?n@h~DmD39X{0G{9f+W-In

delta 228
zcmbQt{+U@jpO=@5fq{YH8Ha1yZbk-%#~=<e=44=CaA06yC@z?&t;xp7kirthF|o)-
zE}b=sGesbnK~wN0NVz8CEtZ1Bl8l#(3=9mKtdm6;ttYQ$R16icDK06pDk{xMjn7NW
zO|{c6Vq;)ns1h$q&CM@M)yI%!2g{Zgq$HMLk>y}uVDQuAntYqdXtFl56q^7814EI(
bWN&6QF(C#91|9|(MiwR>CLTrz<oFE$VR17B

diff --git a/MisplaceAI/rules/__pycache__/utils.cpython-310.pyc b/MisplaceAI/rules/__pycache__/utils.cpython-310.pyc
deleted file mode 100644
index 6ec72ae2621dab37e52edba017451b6382a1ca8f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2064
zcmd1j<>g{vU|>kv?~?YEm4V?gh=Yuo85kHG7#J9e<ro+kQW#Pga~N_NqZk<(+!<1s
zQkYv9Qka{WqL@-xf*CYfUotW<FlaK~VhJkENlivJ2E=B98Rf#jz>vxi#hAhn#gxLB
z!qmbL#hk*N!qUPJ#gf9B!q&nN#hSvN!qLJI#g@XE!qvhM#h${Q!qdVK#gW3B!q>tO
z#hJn%%%CZ7iw9&=v2S8tVtQ&(GRS(6O&|<ngKTsLIi8P!fuV+B0mDLu8ishr6oz01
zO-4UWrdwP&`H3m<MWs2Z#kW|&)Jn!%EXAogX)76uI2afhehKR*78K}%rSwZnGINUc
z3My}L#K&jmWtPOpvw#c-*}}(IC5r46J(vm%H-Q2a>?RRVfP#Hr!jQ$dfN3Fv3qvzw
zFoPy@m7-66Vv0gZMydkXVuiG#{9G_MC9xziDX}<J55-uJ1K1cC7=l5r0mV}$Lk&YL
zcP(QLV-`aVV-|>JN@1A8G?}T83FP&aOt(0b^Yc<NOEUBGZm}gMgJ@0WTP%5rxv51w
z3=9lKyr7t5y2YetaEk@x2ykdX2u=nDhFe@VDVfP7$@#ejb|8K+$PID~RoW<lfCybZ
zo1FaQ#GGO~J%m0@<|2@;TkQEsS*gh-#kZIfb8?D69)Z{c3jZRI;YFZeW(Ro=q+W!n
zN*sqR$smQG$OmDNL97f64B)`lV_;wa1#=ct4Py;c4RZ?P9HtbeUZxnPT9#T?m`Dvn
z7IO`w4MPfZFoPybl}vDAS*k)JI1&^}@=;@;h#MS2MWCd0iz6j9EwMDGq}WfB1?;IJ
zAy6O*loq5UmZZk#7sV$Rr6!i77J(e3$yNmN3|J>3u!{shI@lrVQqV%+7H4r{St>Z8
zf~+kD`BREXgt1BtB_!aAl0g9l3Iq@au|a_W4hT^40Of=l#uP?Lh8o5cCNRk?$*_=_
zkpYs8tK=P1QWO#u@>0uj_#NbFgwy>r8H>arp#k<7$S3F?;7Ck?WHgW@B(*T1Wf_<X
z6vu;n3Q7oI$47v(aTdb@#u~<jjI~TPOvPGNVkJyj%%C)$!r04L%Ur{p#ZtqZ#hSu2
zhY6&jh5?iZY#72BYM6o<SQtu}ve+s$85uw@5**XzU>Q(+2c?!2Wu_wHJgHJ4v!qx7
zlq>XBGD0E@6#jmi?BJNZ#hjj6f{1TKh}`0F$xkiz%P(=Q$Sf|=WC2I`ElyBIiU*kn
zj_fE7Fh4&j3nQ@7Q%k^+4Jspw#TXbEc$ioinHc#P`51W^S(y3$u`x3JXF(4@m@bq6
z1jRnQ%+Ub_AR{P9${317Ky(eGEkg-o785Apg92~?%R&Z5h7_h?FxF(Qk_t-A&Bq=j
zMUo5*41Sud;IKdh!!5S7%$$<cqFZb!sX3`7shUh+?-$8{$`w#tLc9yg*|)fhz@~#e
zs{qR3AbBn(4n{FXmVZ?eD5)DsDN6AND(T@q1f|Rph8hM)i3%=H8LRkxGK)(T5_59E
z$+=h$RMh2U7MFk>ev7RvF{d=O7+cA6iwmR-?7Ct#kn=#H$%jz@WfnuCtJqJI3sgCP
zqBuVO7FT?HZhlH>PHKGoEuQ%J!qUVXh)fZv&IOlh;Cxdg0SXye5CIB<B4rQ@6cCVr
z0<%D&RRr=S2p5Ag5eEYYBL_1F3kNF)3kMGm8(7v)llc}~ZhlH?PBA1xK+2Jfftz)U
S!v^9uJ5ca}3lts(AtnG&-M&Bo

diff --git a/MisplaceAI/rules/__pycache__/views.cpython-310.pyc b/MisplaceAI/rules/__pycache__/views.cpython-310.pyc
index 5175198a3ed3629c01840fa93443e5fea63fd89f..35a893392adfc093578df244f706a42561585443 100644
GIT binary patch
literal 3741
zcmd1j<>g{vU|{gM;F^{!$iVOz#6iZ)3=9ko3=9m#7Z?~AQW#Pga~N_NqZo6UqL^}-
zqnH^%VoW(KxvWvFU^a6OTP}MPJ0n91OA2caM=oa+XD(M1S1xxHH&~1<hbNaeiZ_=p
ziZ7QxiXW_pJx3r{FiH^2=ExDs6^;^SWJuvm;c8)s5=r4s;b~!r5>4Sv;cH=t5=-Gv
z5olqE5>F9K5o%$Gl1ODu5l#_lVQ6NIl1yby5ls;Tv!znRQzTj#qNGzKQ>0oLqGVE}
zQ)F5gqGVHKQ{-A0qU2KKgBdgxUV{9p$$X2gC^au7wdfW{QEEzNQEGC@Ey48ElKA|j
ztkmR^`23=H69W@X##?+j`RSQ?@kObHrI|&kDVmJ8IC4{qixbmRi(fJ_FfeE`-(m?W
z%}Kq*;gg@7Sdy8acZ<cdBsEu)`4$IA+%3N-_ZAOK4$R{K$%9y$jJG%g64NvD5=-)n
zG#PKP7p0b^78R!^gA4{a6NH%<7#LU?7#N&EQ6j~_z)-@F#khcJAww-=33ClY3S$aW
z4Pz!_GjlM5CbM6aXi;fSYO#J!W^qY8n5mahlACjj70lLTDdJ#YV7SE&@n!KX=ER(w
zB9IN5Od#6}OH+$WiUb%K7*;YAi7+rQ{1VnrEGW<iYt}EzOf4_gE2zB1g)kkIl!{px
z7#O%11sIFO7#J9EJKlwXfuV*Wiy?(Eo2f{=gt3Mpi>aBhma&F$0rNtJBC#6A1uP30
z7#T`fQ<$0=gBkLeOBkC$-ejv`NMTN4fqRqH?-omde{jez0kFfY5YDL*28-w?rlf#<
z5Ai%pT7FTkCi^Y6+|-hc{FEYY1_p*AaZo^TWERJlCFW$N++rzCEK4l{rG0346bXY=
zNrDJaNPvT*NEECIW;!1zN<g8-#mL3T0ftQf*jNM@i)29o0SZ@841zGoV0bLbfMc<Q
zv4$~)v6rcqsf4M9A%!W0xrPZEk1T#G8E-LVrc{YRyaOWRQ&LM3GjpIm0*Poc7lA?^
z9Hn4KuVe;0`W8D#Ha;_@NCBJcL8%<1Kmz1?kO4fPs8h!0;?HJiE(S$i3R5;yk#G$Y
zDDoH?N?1~uL6KI%S_3W!;C^BAE0O~_0~FpxAUmrhLADp`C+Fv-WftYer=;ejmZXCH
z1$M9|8<Mv`3H}xvL<u5xiWEU6qD2dLQEF~}St>Z*K_UDZls0*wF(bfOq=xQ8kl)#0
zIV%B|50yZ<EQ_UvDTTS0sg}8hc>(J}h9bop<^^ov#LAw+Qp1$Rk;2-`6wHvvTEYxg
z$ym!=!db(R!d3&~v(I4y=T8o#uvp1>iz73yxFj(zIkk!p93)n-sL^CBQet3WfJJ|4
zK}uo?#AD!K(qt+Er%O=uYI32479w>QNrOTO6cmt<lLv7@iBgjVoKC=YfP)-j9C~;n
zSqn-X#X<}W450Aj1E+L8My7vUEJBP$TA*-6F0nvi3c{cg>vI!0Tp=aa0_GIPg^aa~
zB`h_JDNM~wwM;b(S*#1#QkWMq)-u;HEnu$!u~=#tvN%#$vYCoZL1CE1)y!DSTEn`4
zdm%%SNe$})9&otxF5s(SNMT*b#K=&>pTY)8dwI+yoXrfitR(_93@Pk2tTikt9MF*G
z^t;89mzbOS5|k)zu@oexr-Dm>Dj8VOtdN+JlA5AWT$-GmT3nn~nv+wh_e%m2FNrC+
znR)S`Y@Y)y<f~-CGWwV@;22s7iJ@B@Ad5hCil$%@Cn)#@K?EouZ*k-orKA?cCsh`K
zijiB)?ye!XnA1~BZgGH80Z3mFDDfBZfOLQ}4<b52p?ixR>QqSNg5#A99Iv-HVXiE`
z#aRHWUv6=O%#6<~%}q)zDl!C_3Qk05u`YzgM+^)MpFwUBVB%r~B>*laNO8x*$ic|;
zmyK13vB(NvA}G=ZRg|25MLHl`bwPw4hyeMjN&-|HVhwx|a1dJ|9F$p-nhPsEP({Ik
zUSt5WMz9DJ#YOOdE;0gH1q$OLV-U*(M3{mIke7;hK`f9%ka7zsc#A+q9%j(8g4|GC
zWC7A;2_kR?Bp<2^K`p8xYmg2*P*8!Q3sf(FFsK}Y*9{Ti{DP<(;3cg*)^bP=xf}xL
z0pt>h1C&ERWe~JpVMi)|iZnouu>ln`kbu@tP01{Y2l)>YnxNF7$q6Z4z(I;Lyg-#3
zxB`L}EVtM}ro@A4RS*Mf>B0%OEf`b}fwBZBX+g>s4sh8bz*yvn9#$Z$U}06H0*Y^x
z`UUJAIdHl`t6z{j28s$;C4=yoDkwNW#zTApsY;9NL82fHkoq5-S-_0|Zb+R3HZ~5V
zNF78tp}Q9)Zewu8ts>UARY1gT2}cS`Gb2X)f@&C6yz#3KieE@628mx-(SQ`k&>93>
zK7r#HTag0}8Geu-K}i=D(cCcOK#|P><6w<&UT}oNlw@K?Iu8@mUoKVw#v)hrKm^&1
zC(^-wRKgnRFzX<`1vNln5s&aK_J{{nUPT}c=n>Bkjd+;R<)APDN4^^a1B0KY{4If$
zti-(Ze7)j~{GyWN(vo6uih`6Sp!5(W2UU=qpI1_pnWUFkT9ToclA4@f1nLMB7lHhG
ziw{*%5vWkQ#g?0&lA2QtY4U-+07}5OSV0ZkVo1#ojyzDQc1sj)LQ$$7ydHp5H{4LU
z(xRN=B5<^V+V0?XYZ0ij2e+2MReKSrXfFa4THxGR1WMxIC@KQ^7b$cQd4t0yH$SB`
zC)EzrDkuh(Ga?K;j694Yj3SIYj66&nOdKp6TpTPM>`dHTj7)-Dj2uE7+#K9Id;q@P
BCnW#?

delta 916
zcmbO$yNOpjpO=@5fq{YH1&3?eCUypf#~=<eW@2DqaA06yD9)Lvt>Vj^!ji+5%O1tf
z$dJOE!kWX8%NfPV$dJO8!rsCV#g)R5!r8(Q#ht>H!rj6U#goF5!rQ_S#hb#H!r#IW
z#g`%g<qHNgXbMeY)K}y2D$dUfN-ZwP&nr%S$;iOKpvicPC8#tfRg>`+2Z(mdFUp;q
zz$7(!FQXG9`y?hM4o(IJhLsFOypy$<RQTCIZew9!VBlgDU@YRF9Lprj7sSB8P{WYL
zkiwYFR3taKgGouCgsleTVwM`lOvYyBV1~(Sn8MjO7#J9e1SWGbE7<aYm_i_e7f$do
zFfiQWNK8qIFDlJR1qD;F0N5ffMh-9(U}9quU@Q`wypBs|auc&UD@$HtZtCPU%xWI&
zAX7kLx01OCWcDpikQwnH`65Y>9J)2>sU=`*#9;p60r^J;Y_tiBHUCOBzanvvMvxPV
z1Si+A$P0lCTFF)f@_iB5LgC5lS;S1GK+4d}=PpXk%`Zy@TLF^)4Dt>SBg7{Hj75r*
zf3e6i7EE5iDZ!{U*^pI7sD!hIA%(4mxrQl)eGU^i%;H%UxZrNkoZQJO$0$8{1*=>=
zIN(68(d0sQ4agmkFb1(iK!hlWU<MHqAOaLZnk?WDDv|~XfD9=D8;9<J(t?!45{L&B
zL16?^1o8kMBL^=d2O}S&5EB=Z5Mz<b<aJ!K#<C#8<UoWxhyZ!H2-U<QkSY2gNhJmb
z20u;y$%(v*^|!cFvJ&&s^Yt=HN(zctK`DSOH$Npcrx+Z<w^-Bii*k#Lz`o)KX$Hkt
zkqn3hGOtJl#6nmEW<k=CO>TZlX-=vgD2*3`!a{_BhY<uhm^fHCcsN)%*m?K>l~bd+

diff --git a/MisplaceAI/rules/forms.py b/MisplaceAI/rules/forms.py
index f45d524..2260014 100644
--- a/MisplaceAI/rules/forms.py
+++ b/MisplaceAI/rules/forms.py
@@ -1,25 +1,17 @@
 from django import forms
-from .models import Rule
+from .models import Rule, Location, Item
 
 class RuleForm(forms.ModelForm):
     class Meta:
         model = Rule
-        fields = ['name', 'condition', 'action']  # Include all the fields you want from the model
+        fields = ['user', 'item', 'locations']
 
-    def clean_name(self):
-        name = self.cleaned_data.get('name')
-        if not name:
-            raise forms.ValidationError("The name field cannot be left blank.")
-        return name
-
-    def clean_condition(self):
-        condition = self.cleaned_data.get('condition')
-        if not condition:
-            raise forms.ValidationError("The condition field cannot be left blank.")
-        return condition
+class LocationForm(forms.ModelForm):
+    class Meta:
+        model = Location
+        fields = ['name']
 
-    def clean_action(self):
-        action = self.cleaned_data.get('action')
-        if not action:
-            raise forms.ValidationError("The action field cannot be left blank.")
-        return action
+class ItemForm(forms.ModelForm):
+    class Meta:
+        model = Item
+        fields = ['name']
diff --git a/MisplaceAI/rules/migrations/0001_initial.py b/MisplaceAI/rules/migrations/0001_initial.py
index 30eb830..c88616d 100644
--- a/MisplaceAI/rules/migrations/0001_initial.py
+++ b/MisplaceAI/rules/migrations/0001_initial.py
@@ -1,6 +1,8 @@
-# Generated by Django 3.2 on 2024-05-15 15:06
+# Generated by Django 3.2 on 2024-05-15 20:43
 
+from django.conf import settings
 from django.db import migrations, models
+import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
@@ -8,16 +10,31 @@ class Migration(migrations.Migration):
     initial = True
 
     dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='Rule',
+            name='Item',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=255, unique=True)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Location',
             fields=[
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('name', models.CharField(max_length=255, unique=True)),
-                ('condition', models.TextField()),
-                ('action', models.TextField()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Rule',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rules.item')),
+                ('locations', models.ManyToManyField(to='rules.Location')),
+                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
             ],
         ),
     ]
diff --git a/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc b/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc
index 3cbc07602d64ef4ef2f9a6599d6144f132f80e71..41f9305df4cc8cb517a5b241eaef71e4d84b52e9 100644
GIT binary patch
literal 1095
zcmd1j<>g{vU|>j+b4^>v%E0g##6iX^3=9ko3=9m#RtyXbDGVu$ISjdsQH+crHd78$
zE^`!fE=v>(n9rQU8pY<$kiwF}+QN{+n#!ET-pm}up28f=pvm?UWU40PEso;Ul9J54
z^kPk>TU@!B=|zbpnfZCex7c#?Q&Mw^{gOfIkTDO;1&<gQ7*ZLc7*iOcm{J&{m{VC6
zu%@zQu`gsyXN=-VWy#`9VM<|6<;vntVN78Jxgv$FmnDrUg*}xkizkI6g)xP*mnn@Y
zohgN@mkF$%n?&_ISk?2Ua%J(R@@4U7ab*c)38wI+@Pq705lH3A5=s$F5$a`3V@eT5
zRRwZ6L|r-y$UW)IQNk%A!3>(Bw>W)a!4h(d#j_+e_ZCxTirXzFPZv#=TRe%SCHe8m
zMX8A;sVTR(3yLyx6N@V2vr{W?aTcc*WhUliR;AwJDN8L%$}dih&r8fry~P3|U;bxc
zU;qbtVnuvTYF>It#x1teyv)MVR86KLUIqq+TWo2WsW~adw>W(Alflt)izTQuC-oLf
zW=U#p6<1MdPHM3ph^@(Vi!(njJ|#6LwIuZxQ%U|U&K#(g;wnCfI+z)nj74G~!&yp;
zQ;YmGMQ(A#gIyILe~T+VJ~uz5G$%Da{uWPsd|_!~4#=hP@weDB^D;{^6LX4~L0UzM
z%M%L<5|eUL<5N-#Qu9($^O7rzm_Snej-eqQ@u9)4LGix+F0MYec;G5BQ;TnLJA(tt
z7nHV&Kxz3Fk5gv4V`)jg8_27-IGr;Riy%xcxBQ~i%=A3()XH0IDOrhm>G`*qQj%_Q
zfPI;npLdJh*)iDJ(Z%%^zi(n*Wk^1VgzC*NNQEZkl?+8%3=9zBm#ThZL4iIvJoFK1
zUEjdKz%U-_L%o8^B31?l1`bdrGXgVMn7Ei({<E+$F^Vt=Ff#pP`NzVJ&X!>0W0YcK
z`or>%<0DwVCdVyqh^zII^YhXmp~DFkNl5|+BqRhR;evXQJf{cqVUY^R<sjD}`~YET
agTk7_1`=C#j3Bpy9L&Qcz{tTU#tZ;D1~W4N

delta 458
zcmX@kv4)i|pO=@5fq{V``MgV7DAPnfnR+z_28I-d6viBeT*fHIT&5@{Mh16=6s8pB
z7KRk&RK_gkX67j76qaBHP1ctnt(r`?xN<YoixNvR^Ye;tvE}Bcq~;VSgQSo#Cj$e6
z0|Ns?aSQ_kLn=cQV+unQQwn1gb2>v5ODby?8_0@O_OL9D6vh<B6qXd$6t-TLG^P~x
zRQ4>+6p$!qFH;&*3Rf!o0<MJ&X-p~HFjhKC3QsRnI%5=f3U4rjCf_YiUzmeJZm|TF
z=A=$u#+aabi!(VtFC`P?&RcAW$sk&jsfdSxf#DWgT4riaO0l0N&*WkzU8P$*DX9gi
zc`2!R$(gCeMNA+i+|EU*i6yDNAnz41PkzTF%gPy&T2V6Dky(UImVtqxNOp2Gvvv^+
z0|Nsa$fFVr3=A9$EKDp+EG$fnB1{5|T#Q_dOn+GZar_6X^3!Cw#hH?on3tZfmy!gw
nrHC115Xgukh>;*Jm?Z~t1BXp+eoARhsvRT90+2ERCNX9JCFf^{

diff --git a/MisplaceAI/rules/models.py b/MisplaceAI/rules/models.py
index a11306e..cef49b1 100644
--- a/MisplaceAI/rules/models.py
+++ b/MisplaceAI/rules/models.py
@@ -1,9 +1,22 @@
 from django.db import models
+from django.contrib.auth.models import User
 
-class Rule(models.Model):
+class Location(models.Model):
+    name = models.CharField(max_length=255, unique=True)
+
+    def __str__(self):
+        return self.name
+
+class Item(models.Model):
     name = models.CharField(max_length=255, unique=True)
-    condition = models.TextField()
-    action = models.TextField()
 
     def __str__(self):
         return self.name
+
+class Rule(models.Model):
+    user = models.ForeignKey(User, on_delete=models.CASCADE)
+    item = models.ForeignKey(Item, on_delete=models.CASCADE)
+    locations = models.ManyToManyField(Location)
+
+    def __str__(self):
+        return f"{self.item.name} Rule"
diff --git a/MisplaceAI/rules/templates/rules/add_rule.html b/MisplaceAI/rules/templates/rules/add_rule.html
index 078583c..66bcc05 100644
--- a/MisplaceAI/rules/templates/rules/add_rule.html
+++ b/MisplaceAI/rules/templates/rules/add_rule.html
@@ -1,11 +1,15 @@
-<h1>Add Rule</h1>
-<form method="post">
-    {% csrf_token %}
-    <label for="name">Name:</label>
-    <input type="text" id="name" name="name"><br>
-    <label for="condition">Condition:</label>
-    <textarea id="condition" name="condition"></textarea><br>
-    <label for="action">Action:</label>
-    <textarea id="action" name="action"></textarea><br>
-    <input type="submit" value="Submit">
-</form>
\ No newline at end of file
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Add Rule{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Add Rule</h1>
+    <form method="post">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button type="submit" class="btn btn-success">Save Rule</button>
+    </form>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/admin_add_item.html b/MisplaceAI/rules/templates/rules/admin_add_item.html
new file mode 100644
index 0000000..39aca1d
--- /dev/null
+++ b/MisplaceAI/rules/templates/rules/admin_add_item.html
@@ -0,0 +1,58 @@
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Add Item{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Add Item</h1>
+    <form method="post">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button type="submit" class="btn btn-success">Add Item</button>
+    </form>
+
+    <h2>Existing Items</h2>
+    <table class="table">
+        <thead>
+            <tr>
+                <th>Item Name</th>
+                <th>Actions</th>
+            </tr>
+        </thead>
+        <tbody>
+            {% for item in page_obj %}
+            <tr>
+                <td>{{ item.name }}</td>
+                <td>
+                    <a href="{% url 'rules:edit_item' item.id %}" class="btn btn-warning btn-sm">Edit</a>
+                    <a href="{% url 'rules:delete_item' item.id %}" class="btn btn-danger btn-sm"
+                        onclick="return confirm('Are you sure you want to delete this item?');">Delete</a>
+                </td>
+            </tr>
+            {% empty %}
+            <tr>
+                <td colspan="2">No items found.</td>
+            </tr>
+            {% endfor %}
+        </tbody>
+    </table>
+
+    <!-- Pagination -->
+    <nav aria-label="Page navigation">
+        <ul class="pagination">
+            {% if page_obj.has_previous %}
+            <li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
+            </li>
+            {% endif %}
+            {% for num in page_obj.paginator.page_range %}
+            <li class="page-item {% if page_obj.number == num %}active{% endif %}"><a class="page-link"
+                    href="?page={{ num }}">{{ num }}</a></li>
+            {% endfor %}
+            {% if page_obj.has_next %}
+            <li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a></li>
+            {% endif %}
+        </ul>
+    </nav>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/admin_add_location.html b/MisplaceAI/rules/templates/rules/admin_add_location.html
new file mode 100644
index 0000000..2df1d82
--- /dev/null
+++ b/MisplaceAI/rules/templates/rules/admin_add_location.html
@@ -0,0 +1,57 @@
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Add Location{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Add Location</h1>
+    <form method="post">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button type="submit" class="btn btn-success">Add Location</button>
+    </form>
+
+    <h2>Existing Locations</h2>
+    <table class="table">
+        <thead>
+            <tr>
+                <th>Location Name</th>
+                <th>Actions</th>
+            </tr>
+        </thead>
+        <tbody>
+            {% for location in page_obj %}
+            <tr>
+                <td>{{ location.name }}</td>
+                <td>
+                    <a href="{% url 'rules:edit_location' location.id %}" class="btn btn-warning btn-sm">Edit</a>
+                    <a href="{% url 'rules:delete_location' location.id %}" class="btn btn-danger btn-sm"
+                        onclick="return confirm('Are you sure you want to delete this location?');">Delete</a>
+                </td>
+            </tr>
+            {% empty %}
+            <tr>
+                <td colspan="2">No locations found.</td>
+            </tr>
+            {% endfor %}
+        </tbody>
+    </table>
+    <!-- Pagination -->
+    <nav aria-label="Page navigation">
+        <ul class="pagination">
+            {% if page_obj.has_previous %}
+            <li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
+            </li>
+            {% endif %}
+            {% for num in page_obj.paginator.page_range %}
+            <li class="page-item {% if page_obj.number == num %}active{% endif %}"><a class="page-link"
+                    href="?page={{ num }}">{{ num }}</a></li>
+            {% endfor %}
+            {% if page_obj.has_next %}
+            <li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a></li>
+            {% endif %}
+        </ul>
+    </nav>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/confirm_delete.html b/MisplaceAI/rules/templates/rules/confirm_delete.html
index 6e2fa10..f1ea751 100644
--- a/MisplaceAI/rules/templates/rules/confirm_delete.html
+++ b/MisplaceAI/rules/templates/rules/confirm_delete.html
@@ -1,18 +1,13 @@
-<!DOCTYPE html>
-<html lang="en">
+{% extends 'core/base.html' %}
+{% block title %}Delete Rule{% endblock %}
 
-<head>
-    <meta charset="UTF-8">
-    <title>Delete Rule</title>
-</head>
-
-<body>
+{% block content %}
+<div class="container mt-5">
     <h1>Are you sure you want to delete "{{ rule.name }}"?</h1>
     <form method="post">
         {% csrf_token %}
-        <input type="submit" value="Confirm Delete">
-        <a href="{% url 'rules:list_rules' %}">Cancel</a>
+        <button type="submit" class="btn btn-danger">Confirm Delete</button>
+        <a href="{% url 'rules:list_rules' %}" class="btn btn-secondary">Cancel</a>
     </form>
-</body>
-
-</html>
\ No newline at end of file
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/confirm_delete_item.html b/MisplaceAI/rules/templates/rules/confirm_delete_item.html
new file mode 100644
index 0000000..ae87987
--- /dev/null
+++ b/MisplaceAI/rules/templates/rules/confirm_delete_item.html
@@ -0,0 +1,15 @@
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Confirm Delete{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Are you sure you want to delete "{{ item.name }}"?</h1>
+    <form method="post">
+        {% csrf_token %}
+        <button type="submit" class="btn btn-danger">Delete</button>
+        <a href="{% url 'rules:admin_add_item' %}" class="btn btn-secondary">Cancel</a>
+    </form>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/confirm_delete_location.html b/MisplaceAI/rules/templates/rules/confirm_delete_location.html
new file mode 100644
index 0000000..5a2665c
--- /dev/null
+++ b/MisplaceAI/rules/templates/rules/confirm_delete_location.html
@@ -0,0 +1,17 @@
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Confirm Delete{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Delete Location</h1>
+    <p>Are you sure you want to delete "{{ location.name }}"?</p>
+
+    <form method="post">
+        {% csrf_token %}
+        <button type="submit" class="btn btn-danger">Delete</button>
+        <a href="{% url 'rules:admin_add_location' %}" class="btn btn-secondary">Cancel</a>
+    </form>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/edit_item.html b/MisplaceAI/rules/templates/rules/edit_item.html
new file mode 100644
index 0000000..9960b94
--- /dev/null
+++ b/MisplaceAI/rules/templates/rules/edit_item.html
@@ -0,0 +1,16 @@
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Edit Item{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Edit Item</h1>
+    <form method="post">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button type="submit" class="btn btn-success">Save Changes</button>
+        <a href="{% url 'rules:admin_add_item' %}" class="btn btn-secondary">Cancel</a>
+    </form>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/edit_location.html b/MisplaceAI/rules/templates/rules/edit_location.html
new file mode 100644
index 0000000..a772b20
--- /dev/null
+++ b/MisplaceAI/rules/templates/rules/edit_location.html
@@ -0,0 +1,16 @@
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Edit Location{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Edit Location</h1>
+    <form method="post" novalidate>
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button type="submit" class="btn btn-primary">Update</button>
+        <a href="{% url 'rules:admin_add_location' %}" class="btn btn-secondary">Cancel</a>
+    </form>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/list_rules.html b/MisplaceAI/rules/templates/rules/list_rules.html
index 2be2586..9ecc344 100644
--- a/MisplaceAI/rules/templates/rules/list_rules.html
+++ b/MisplaceAI/rules/templates/rules/list_rules.html
@@ -1,28 +1,44 @@
-<!DOCTYPE html>
-<html lang="en">
+{% extends 'core/base.html' %}
+{% load static %}
 
-<head>
-    <meta charset="UTF-8">
-    <title>List of Rules</title>
-</head>
+{% block title %}List of Rules{% endblock %}
 
-<body>
+{% block content %}
+<div class="container mt-5">
     <h1>List of Rules</h1>
-    <ul>
-        {% for rule in rules %}
-        <li>
-            {{ rule.name }}
-            {% if rule.name %}
-            : <a href="{% url 'rules:get_rule' rule.name %}">View</a>
-            | <a href="{% url 'rules:update_rule' rule.name %}">Edit</a>
-            | <a href="{% url 'rules:remove_rule' rule.name %}">Delete</a>
-            {% else %}
-            : Name unavailable
-            {% endif %}
-        </li>
-        {% endfor %}
-    </ul>
-    <a href="{% url 'rules:add_rule' %}">Add New Rule</a>
-</body>
-
-</html>
\ No newline at end of file
+    <table class="table">
+        <thead>
+            <tr>
+                <th>Item</th>
+                <th>Locations</th>
+                <th>Actions</th>
+            </tr>
+        </thead>
+        <tbody>
+            {% for rule in rules %}
+            <tr>
+                <td>{{ rule.item.name }}</td>
+                <td>
+                    {% for location in rule.locations.all %}
+                    {{ location.name }}{% if not forloop.last %}, {% endif %}
+                    {% endfor %}
+                </td>
+                <td>
+                    <a href="{% url 'rules:get_rule' rule.id %}" class="btn btn-info">View</a>
+                    <a href="{% url 'rules:update_rule' rule.id %}" class="btn btn-warning">Edit</a>
+                    <form action="{% url 'rules:remove_rule' rule.id %}" method="post" style="display:inline;">
+                        {% csrf_token %}
+                        <button type="submit" class="btn btn-danger">Delete</button>
+                    </form>
+                </td>
+            </tr>
+            {% empty %}
+            <tr>
+                <td colspan="3">No rules available.</td>
+            </tr>
+            {% endfor %}
+        </tbody>
+    </table>
+    <a href="{% url 'rules:add_rule' %}" class="btn btn-primary">Add New Rule</a>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/rule_detail.html b/MisplaceAI/rules/templates/rules/rule_detail.html
index 5b35231..da291d5 100644
--- a/MisplaceAI/rules/templates/rules/rule_detail.html
+++ b/MisplaceAI/rules/templates/rules/rule_detail.html
@@ -1,4 +1,18 @@
-<h1>Rule Details</h1>
-<p><strong>Name:</strong> {{ rule.name }}</p>
-<p><strong>Condition:</strong> {{ rule.condition }}</p>
-<p><strong>Action:</strong> {{ rule.action }}</p>
\ No newline at end of file
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Rule Detail{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Rule Detail</h1>
+    <p><strong>Item:</strong> {{ rule.item.name }}</p>
+    <p><strong>Locations:</strong> {% for location in rule.locations.all %}{{ location.name }}{% if not forloop.last %},
+        {% endif %}{% endfor %}</p>
+    <a href="{% url 'rules:update_rule' rule.id %}" class="btn btn-warning">Edit</a>
+    <form action="{% url 'rules:remove_rule' rule.id %}" method="post" style="display:inline;">
+        {% csrf_token %}
+        <button type="submit" class="btn btn-danger">Delete</button>
+    </form>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/templates/rules/update_rule.html b/MisplaceAI/rules/templates/rules/update_rule.html
index 0a5843e..4d3ca50 100644
--- a/MisplaceAI/rules/templates/rules/update_rule.html
+++ b/MisplaceAI/rules/templates/rules/update_rule.html
@@ -1,6 +1,15 @@
-<h1>Update Rule</h1>
-<form method="post">
-    {% csrf_token %}
-    {{ form.as_p }}
-    <button type="submit">Save changes</button>
-</form>
\ No newline at end of file
+{% extends 'core/base.html' %}
+{% load static %}
+
+{% block title %}Update Rule{% endblock %}
+
+{% block content %}
+<div class="container mt-5">
+    <h1>Update Rule</h1>
+    <form method="post">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button type="submit" class="btn btn-success">Save Changes</button>
+    </form>
+</div>
+{% endblock %}
\ No newline at end of file
diff --git a/MisplaceAI/rules/urls.py b/MisplaceAI/rules/urls.py
index a556df6..345f00c 100644
--- a/MisplaceAI/rules/urls.py
+++ b/MisplaceAI/rules/urls.py
@@ -1,12 +1,23 @@
 from django.urls import path
-from .views import list_rules, add_rule, get_rule, remove_rule, update_rule
+from .views import (
+    list_rules, add_rule, get_rule, remove_rule, update_rule,
+    admin_add_location, admin_add_item, edit_item, delete_item,edit_location, delete_location
+)
 
 app_name = 'rules'
 urlpatterns = [
     path('', list_rules, name='list_rules'),
     path('add/', add_rule, name='add_rule'),
-    path('<str:rule_name>/', get_rule, name='get_rule'),
-    path('remove/<str:rule_name>/', remove_rule, name='remove_rule'),
-    path('update/<str:rule_name>/', update_rule, name='update_rule'),
+    path('<int:rule_id>/', get_rule, name='get_rule'),
+    path('remove/<int:rule_id>/', remove_rule, name='remove_rule'),
+    path('update/<int:rule_id>/', update_rule, name='update_rule'),
+    path('admin_add_location/', admin_add_location, name='admin_add_location'),
+    path('admin_add_item/', admin_add_item, name='admin_add_item'),
+    
+    path('edit_item/<int:item_id>/', edit_item, name='edit_item'),
+    path('delete_item/<int:item_id>/', delete_item, name='delete_item'),
+    path('edit_location/<int:location_id>/', edit_location, name='edit_location'),
+    path('delete_location/<int:location_id>/', delete_location, name='delete_location'),
+
 
 ]
diff --git a/MisplaceAI/rules/utils.py b/MisplaceAI/rules/utils.py
index fd8fbcd..3de4b76 100644
--- a/MisplaceAI/rules/utils.py
+++ b/MisplaceAI/rules/utils.py
@@ -1,40 +1,38 @@
+from django.core.exceptions import ValidationError
 from .models import Rule
 
-class RulesManager:
-    def __init__(self):
-        self.rules = self.load_rules()
+def validate_rule(rule):
+    """
+    Validates a rule to ensure there are no conflicting rules.
+    """
+    existing_rules = Rule.objects.filter(item=rule.item).exclude(id=rule.id)
+    for existing_rule in existing_rules:
+        if set(existing_rule.locations.all()) & set(rule.locations.all()):
+            raise ValidationError(f"A rule for {rule.item.name} already exists for one or more of the selected locations.")
+    
+def check_item_location(item, location):
+    """
+    Checks if the given item is allowed at the given location based on the existing rules.
+    """
+    rules = Rule.objects.filter(item=item, locations=location)
+    if not rules.exists():
+        return False
+    return True
 
-    def load_rules(self):
-        """Load the rules from the database."""
-        return {rule.name: {'condition': rule.condition, 'action': rule.action} for rule in Rule.objects.all()}
+def get_item_location_rules(item):
+    """
+    Retrieves all the locations where the given item is allowed based on the existing rules.
+    """
+    rules = Rule.objects.filter(item=item)
+    allowed_locations = set()
+    for rule in rules:
+        allowed_locations.update(rule.locations.all())
+    return allowed_locations
 
-    def save_rule(self, name, condition, action):
-        """Save a rule to the database."""
-        rule, created = Rule.objects.update_or_create(name=name, defaults={'condition': condition, 'action': action})
-        self.rules[name] = {'condition': condition, 'action': action}
-
-    def add_rule(self, rule):
-        """Add a new rule to the database."""
-        self.save_rule(rule["name"], rule["condition"], rule["action"])
-
-    def get_rule(self, rule_name):
-        """Retrieve a rule by its name."""
-        rule = self.rules.get(rule_name)
-        if not rule:
-            try:
-                rule_obj = Rule.objects.get(name=rule_name)
-                rule = {'condition': rule_obj.condition, 'action': rule_obj.action}
-                self.rules[rule_name] = rule
-            except Rule.DoesNotExist:
-                return None
-        return rule
-
-    def remove_rule(self, rule_name):
-        """Remove a rule by its name."""
-        if rule_name in self.rules:
-            del self.rules[rule_name]
-            Rule.objects.filter(name=rule_name).delete()
-
-    def list_rules(self):
-        """List all rules."""
-        return list(self.rules.values())
+def notify_user_of_misplacement(user, item, location):
+    """
+    Notifies the user that the given item is misplaced at the given location.
+    """
+    # This function can be implemented to send notifications to the user.
+    # For now, we will just print a message.
+    print(f"User {user.username}, the item '{item.name}' is misplaced at '{location.name}'.")
diff --git a/MisplaceAI/rules/views.py b/MisplaceAI/rules/views.py
index 9ef5872..a97a2e7 100644
--- a/MisplaceAI/rules/views.py
+++ b/MisplaceAI/rules/views.py
@@ -1,7 +1,11 @@
 from django.shortcuts import render, redirect, get_object_or_404
-from django.http import JsonResponse
-from .models import Rule
-from .forms import RuleForm
+from django.contrib.auth.decorators import login_required
+from django.contrib import messages
+from .models import Rule, Location, Item
+from .forms import RuleForm, LocationForm, ItemForm
+from django.core.paginator import Paginator
+
+from django.urls import reverse
 
 def list_rules(request):
     rules = Rule.objects.all()
@@ -13,40 +17,108 @@ def add_rule(request):
         if form.is_valid():
             form.save()
             return redirect('rules:list_rules')
-        else:
-            return render(request, 'rules/add_rule.html', {'form': form})
     else:
-        form = RuleForm()  # An unbound form for GET requests
-        return render(request, 'rules/add_rule.html', {'form': form})
+        form = RuleForm()
+    return render(request, 'rules/add_rule.html', {'form': form})
 
-def get_rule(request, rule_name):
-    rule = get_object_or_404(Rule, name=rule_name)
+def get_rule(request, rule_id):
+    rule = get_object_or_404(Rule, id=rule_id)
     return render(request, 'rules/rule_detail.html', {'rule': rule})
 
-def remove_rule(request, rule_name):
-    rule = get_object_or_404(Rule, name=rule_name)
+def remove_rule(request, rule_id):
+    rule = get_object_or_404(Rule, id=rule_id)
     if request.method == 'POST':
         rule.delete()
         return redirect('rules:list_rules')
     return render(request, 'rules/confirm_delete.html', {'rule': rule})
 
-def update_rule(request, rule_name):
-    rule = get_object_or_404(Rule, name=rule_name)
+def update_rule(request, rule_id):
+    rule = get_object_or_404(Rule, id=rule_id)
     if request.method == 'POST':
         form = RuleForm(request.POST, instance=rule)
         if form.is_valid():
             form.save()
-            return redirect('rules:get_rule', rule_name=rule.name)
-        else:
-            return render(request, 'rules/update_rule.html', {'form': form, 'rule': rule})
+            return redirect('rules:get_rule', rule_id=rule.id)
     else:
         form = RuleForm(instance=rule)
-        return render(request, 'rules/update_rule.html', {'form': form, 'rule': rule})
+    return render(request, 'rules/update_rule.html', {'form': form, 'rule': rule})
 
+@login_required
+def admin_add_location(request):
+    locations = Location.objects.all().order_by('name')
+    paginator = Paginator(locations, 10)  # Show 10 locations per page
+    page_number = request.GET.get('page')
+    page_obj = paginator.get_page(page_number)
 
-def remove_rule(request, rule_name):
-    rule = get_object_or_404(Rule, name=rule_name)
     if request.method == 'POST':
-        rule.delete()
-        return redirect('rules:list_rules')
-    return render(request, 'rules/confirm_delete.html', {'rule': rule})
+        form = LocationForm(request.POST)
+        if form.is_valid():
+            form.save()
+            messages.success(request, 'Location added successfully.')
+            return redirect('rules:admin_add_location')
+    else:
+        form = LocationForm()
+    return render(request, 'rules/admin_add_location.html', {'form': form, 'page_obj': page_obj})
+
+
+@login_required
+def admin_add_item(request):
+    items = Item.objects.all().order_by('name')
+    paginator = Paginator(items, 10)  # Show 10 items per page
+    page_number = request.GET.get('page')
+    page_obj = paginator.get_page(page_number)
+
+    if request.method == 'POST':
+        form = ItemForm(request.POST)
+        if form.is_valid():
+            form.save()
+            messages.success(request, 'Item added successfully.')
+            return redirect('rules:admin_add_item')
+    else:
+        form = ItemForm()
+    return render(request, 'rules/admin_add_item.html', {'form': form, 'page_obj': page_obj})
+
+
+
+def edit_item(request, item_id):
+    item = get_object_or_404(Item, id=item_id)
+    if request.method == 'POST':
+        form = ItemForm(request.POST, instance=item)
+        if form.is_valid():
+            form.save()
+            return redirect('rules:admin_add_item')
+    else:
+        form = ItemForm(instance=item)
+    return render(request, 'rules/edit_item.html', {'form': form})
+
+def delete_item(request, item_id):
+    item = get_object_or_404(Item, id=item_id)
+    if request.method == 'POST':
+        item.delete()
+        return redirect('rules:admin_add_item')
+    return render(request, 'rules/confirm_delete_item.html', {'item': item})
+
+
+
+ 
+
+def edit_location(request, location_id):
+    location = get_object_or_404(Location, id=location_id)
+    if request.method == 'POST':
+        form = LocationForm(request.POST, instance=location)
+        if form.is_valid():
+            form.save()
+            # Use the 'reverse' to correctly use named URLs with namespaces
+            return redirect(reverse('rules:admin_add_location'))
+    else:
+        form = LocationForm(instance=location)
+    return render(request, 'rules/edit_location.html', {'form': form})
+
+
+
+def delete_location(request, location_id):
+    location = get_object_or_404(Location, id=location_id)
+    if request.method == 'POST':
+        location.delete()
+        return redirect('rules:admin_add_location')
+    return render(request, 'rules/confirm_delete_location.html', {'location': location})
diff --git a/README.md b/README.md
index e57dc36..bb3e373 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,84 @@
 # Identification of Misplaced Items
 
 
+## DATABASE
+
+### Connect though terminal
+
+```bash
+docker exec -it misplaceai-db-1 mysql -u root -p
+```
+<br>
+Then enter password
+
+```bash
+Enter password: rootpassword
+```
+
+<br>
+Select Database:
+```bash
+mysql> USE misplaceai;
+```
+
+### Drop all tables 
+
+Disable foreign key checks:
+
+``bash
+SET FOREIGN_KEY_CHECKS = 0;
+```
+
+Generate and execute the drop script:
+
+```bash
+SET @tables = NULL;
+SELECT GROUP_CONCAT('`', table_name, '`') INTO @tables
+FROM information_schema.tables
+WHERE table_schema = (SELECT DATABASE());
+
+SET @tables = CONCAT('DROP TABLE IF EXISTS ', @tables);
+PREPARE stmt FROM @tables;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+```
+
+Enable foreign key checks:
+
+```bash
+SET FOREIGN_KEY_CHECKS = 1;
+
+```
+
+Verify that all tables are dropped:
+
+```sql
+SHOW TABLES;
+```
+
+exir
+
+```bash
+mysql> EXIT;
+Bye
+```
+
+
+## 
+migrations 
+```bash
+docker-compose exec web python manage.py makemigrations 
+ docker-compose exec web python manage.py migrate 
+```
+
+create superuser:
+
+``` bash
+
+ docker-compose exec web python manage.py createsuperusers
+```
+
 
 ## Getting started
 
-- 
GitLab