diff --git a/backend/prisma/migrations/20231211235124_/migration.sql b/backend/prisma/migrations/20231211235124_/migration.sql new file mode 100644 index 0000000..ce77f7d --- /dev/null +++ b/backend/prisma/migrations/20231211235124_/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Drill" ALTER COLUMN "image" SET DEFAULT 'abc'; diff --git a/backend/prisma/migrations/20231211235631_/migration.sql b/backend/prisma/migrations/20231211235631_/migration.sql new file mode 100644 index 0000000..12c0cac --- /dev/null +++ b/backend/prisma/migrations/20231211235631_/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Drill" ALTER COLUMN "image" SET DEFAULT 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAx4AAAGyCAMAAABdpeKwAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAE1UExURQAAAHFzfJKVoJmZZo+PX5iYdDJhNTBbMTRlNy5XLzZpOSxTLSVIJ/X19SVJJ/b29vf396VjUGooFPL19ytcLocyGoEwGTxtP6ReSY02HJM4Hevr6zpoPJU9JJ5bSIUtFCpYLJhZR5k6Ho87I+3v8DhkOvby8aVgSnsuGJ9hT/Hx8ShUKu/x8d7Y2NfPz+3m5HwoFG8oFNHPz3UoFM/Pz+nj4uvj4pJXRtvPz+HPz3soFNLPz/Pr6e7o5nYoFOvl5IIoFNbPz+bi4mwoFJtAJd3Pz/Dp538rFPHr6YwvFHAoFCAgIMbDvGxoX5+bkufq6+nn5Oji4ry/zvb2/7i615lfTluAXd/Y2GGEYll8W19/YF17Xld4WNPPz3x8UoWFWO/t7HkoFF2EX/P19mlpRnBwS////y5nq+wAAAABYktHRGYs1NklAAAAB3RJTUUH5wwJADUQwOvxwwAAAAFvck5UAc+id5oAADWASURBVHja7Z0NmxS3lbZr46Q/YNh0F6k21c6AGRyWGSeebo+ZeI094JhlDCROSGIvYXfj3ffN/v+/sKWj+urqqi7pSCpJpVNXrsBwOE0ZzjPSkfTojiJ6JJ5/ajw/8f95r/v56U+z/+Tst/z0p++hniLP33zb9ebVM0JxHJQHFAhaHEVh+pxvu+I8ekYpjh55vPczleIqCtTffNs1580zUnEclsfPbH/3tp1vu+o8eUYrjkPy+Jn9ub/tfNt158UzYnF0y2NnWoUpsDHk2648D55Ri6NLHns9h2yBjSPfdu05/4xcHO3yaG3IZQpsLPm2q8/xZ/TiaJNH52qVaIGNJ992/Tn9BCCOfXkcXMoVKbAx5duuQIefIMTRlEfvPkdYcds16OwTiDh25SG0CejSd3fT+bar0NEnGHHU5SG8Q+5Ob2A633YdOvkEJI5KHlLHR1xZWTKdb7sSHXyCEkchD+mzVW7sS5jOt12Lzj2BiYPLA3Xw0IVdbdP5tqvRsSc4cTB5oE/l2j8TZTrfdj069QQojp/8ROnIuu0TtabzbVekQ0+Q4lAyOxUFNt582zXpzBOuOFz+7m0733ZVOvKEK46iSLDFNe5823XpxBO2OLAFFkK+7cp04CFxYAosjHzbtWn9IXFgCiyUfNvVSeJwRBwyBRZOvu36JHE4Iw7RAgsp33aFkjgcEodIgYUVt12jJA6nxNFXQKHl265SEodj4jhUROHl265TEodz4ugqpBDzbVcqicNBcbQVU5j5tmuVxOGkOJoFFWq+7WolcTgqjnpRhZtvu15JHM6KoyiskPNtVyyJw/AzmeCLoyiwcPNt1yyJw7A4phMVgdj+7m0733bVkjiMimM2nU3mc6xA7M/9befbrlsSh0lxTOZs9JhNUCOICytHtvNtVy6Jw5g4JtPsmbEf2M9kBeLGvoPtfNu1S+IwJI7pbD6dTdngMZ3MskFkJjWCuLJrbTvfdvWSOMyII+s65ux/2c+m8+yLSTbPEhaIO2eebOfbrl8ShwFxZErIxo4JdB1s2JjN56xHn8yFplgunZi1nW+7gkkc+sUxhZnVlC9bQXs+v8EmWXPepuOLK7y47RomcWgWB+82MlmwCdXk5rSUCWtFZlPoRvDF0/d7xpZvu4pJHFrFMb0BjfiMDxpTmFqxn4A22AIWj0/kC0fk940v33Ydkzg0imMyY6XPl6vYCHKD9eSwuJv1HpMb81p8Il40ogU2xnzblUzi0CaOOW8vbvKGfDphgwhrQW5AZNqINwXi576E6XzbtUzi0CSOGdsjZ70FzKZmU1i9yuZU7FDJDPYH9+KTvuIQL7Cx5tuuZhKHHnFknfg0GxduTmA2lTUbM7ZYxUaOOWyBdMTxxVXPG2++7XomcWgQB+u7YSU3GyjYV7Cey6ZTmTBYM94dZwLx+USt6XzbFU3iUBfHBBalYGscFqr4Bvl8ClOoG9PDcfKDHIrarmkSh6o4soGBtRQ32OLtnPcVcBxxDoPErD9OfpDRyyNYcfB9wPmN2RwWqmZwCpEv37LdD8E4+UHGLI9wxcHGhukNNl+a34DlKX7+MJ9DScTJDzJWeYQqjjk/sz69MeXjwRzWbqc3mEfwJvslyTi+uDAF6ke+7domcSDFATsYvPGGHhuGANZjZDV/E9Zu5eP44pItUF/ybVc3iQMnjtkU2og5rNDyDT92hn0GAwNsbSDi5AcZlTyCFQecC4G9DDg8MrkJpll2NJd133N8nPwgo5FHqOK4ydwbc3Y4F6ZFE94/8GWobJKkGCc/yCjkEao4YOkJvtGzUr4B86Ws3S7uW5hpiJMfxHd5hCoOmBfBN3xmj2ULUfyXbvKa1xUnP4jP8ghVHBM4QcWO4fJZESw+TXlh87O4uuLkB/FWHqGKg50Iyb/rz+Eg1fQGu6Fnwn2Ac91x8oP4KI9QxcHdsNBQ34DlWPad/+Y8v39kaiSOL65mjq/5tqudxCEkDn6UkN95CD+yIs6XYll33R0/OjocP5RPfhDb9U7iEBDHlBs15rPZzWlh+KvdgDjrjh8d3bo1OcLnh+4HsV3xJI5ecUz4t3TWMrMLq/hpqfwgCP8e3xX/50wc7GECweTfgBNa+OIqCtTffNs1T+LoEccU7k/gvQE4N+D2w2lewHBxVUf8KBcHe6ZH8vlFPGQ/iO2qJ3EcFAfnc8xm+VSIb+rxhgFKujvOxfHzxTK+/XP2s18cyeXX4+H6QWzXPYnjkDhKPgdbXWK9NLtBYZpfZAWl2xEvxbFMVsuEC+T9I/H8ZjxUP4jtyidxdIqjyefgNx3y2xTynbyOeCmOO0marNfJMv0ABPLLI7H89ji+ODEF6ka+7doncXSIo43PMZ8Ut5LAalNHvCaOZJ2s01WapHeOFz8vm/Se/O44vjhlC9SVfNvVT+JoF0crn2NW7E3MuuOlOO4mSbpOk+xZp9kPd+7xKdaHR4fzD31+eH4Q2/VP4mgRRzefYwr35nbHq55jlYkjWa+y8SMbPLL/rVfLe3wEmR3hPz80P4htBZA49sVxmM8x745X4sgEsWb6WLH/ZeJIVtkX6XJVTLFwnx8eH8S2BkgcDXGI8Dna46U47p8wYaTZgJGNGymbWq3ZF5lU1ssHH4FAfnUk//kh8kFsq4DEsSMOQT5HS7w2cmTd+IotWa0SmGClK2jPVydskrW6mz7MRxC5zw+TD2JbBySOmjgk+ByNeCmOf8kmVXm3kclizYaPR0kpE9aKrE+Th/kIIv75ofJBbCuBxFGKQ47PUY9Xq1WwVHXCGvHsfzBoJDC1Yj8BbUD8NF3k+yBinx8uH8S2FkgcuTgQfI48XtshT08yWWTSSPkAwkYQ1oeksLib9R5l/DQ9+zk/i9X/+SHzQWyrgcTxExU+R23kWDI5MGVkfccj3pCzr7OWPPv1E4jU43dSvg/y8dHhzw+bD2JbDyQOJT5HtVq1hv0/1mCwQYPNpvLVq2xOxXr1/fgy+XXtNC/xQRyXR7DiQPM5KnHAFkfWiSfZuPAohdlU1mys2WIVGzlW7fHj/Lj7h0fEB3FcHsGKA83nqMTBmvFkna/kZgMFm1jBei6bTmXCaI/H8W9KP8iHR8QHcVgewYoDzecoxXG6Sk/4+hSs38I+4Ar+l/1fAlOstngcf3Je94OwHoT4IE7KI1xxYPkctYac7W5kAwNrKU7Y4u2K9x0pa8VXMIi0xDeFOGp+ENaDEB/EOXmEKg48n6O+Q77iSmBLuOsVLFSt4RQiX95tj2/jT8/b/CCTI+KDOCaPUMWB53PUTuWy6RNrs7Pugv18dQLLU/z8YT7H2o9fxJ+dd/lBsh6E+CDuyCNYcaD5HFXP8YgNEfzMenKS8PFiBWu3yUk2bCTt8Yv4k8eH/SDEB3FEHsGKA83fqIsj4TsYvPGGHpwNEawBz6ZRSXs8E8dlnx/kl0fEB3FAHqGKA8/fKMXxWzgysk6gzVjBCi7f8GNn2NcwcLTFt/Hnj0X8IO8fER/EsjxCFQeev1Htc2Td9QqaC9ADPzySPoJJEgwJ7fFtsVol4AeZHBEfxKI8QhUHnr9Ru2BhdZI+Yu6NrKc+gd4BNv2yn/Nlqvb4Nv7XSxk/yMdHxAexJI9QxYHnb9QuWEjhW/+a7/GxQeAE5lNZO857jNb4F/GTL2X9IL84Ij4IiWMwceD5G1VDnsDCVArtAnQOa/gafukR10RL/CJ+8hXGD/L+Ueh8EBLHQOLA8zdqfg44a8vKmx3D5bMmWJxK1vkqbVv8Kv7kKdYP8vFR2HwQEscg4lDhc1TiYOdB+OHbZA2dQyaAk/WKN+Rpe/xZsQmI9INMguaDkDgGEIcan4NPq1I+X4JpU9Zwn8ByLRs5HrETuKukPX4Vf/07vB+kXMUKlg9C4jAuDlU+Bz8btV7zkuZ73PAjE0HKT+G2x7ff5CMH0g+yfH5WXT0aJB+ExGFYHKp8DiYO1kgn3KiRFfGjpPgGX+14t8Xj+PNLFT8Ii9/N90FC5YOQOIyKQwOf4z4cJ+RDAmu52QYFP02VHxRpj8fxv12q+EGK+L/kU6ww+SAkDpPi0MLngI0Kto8H3+HBuQG73UkukLb4VfzJCxU/SD2+PD4Llg9C4jAmDn18Dmid1/lUim/68YYjbY9fxJ++UPGDNOPFKlZ4fBAShyFx6OVzpPnqFOvFWUed73y3xuPy+AjOD9IWP33+QZB8EBKHGXFo53Pw8yJ8Z5t3z+3xTfz5uYofpCt+N10EyAchcRgQhxk+B5z+gJaZrzK1xUsnINIPcih+eh0eH4TEoV8cxvgcTBvrYm+jJX4Rf/KVih+kL356LzQ+CIlDszjM8jlgrXXVHo/jJ9+q+EFE4qcvF0HxQUgcWsVhns8BbXhL/FXRkCP9IKLxZXoWEB+ExKFRHMPwOdriV/GTFyp+EJn4nXwfJAQ+CIlDmziG43M041VDjvODyMbvHD8MhA9C4tAkjmH5HPX4pvJzoPwgmPj9ZBEEH4TEoUccg/M5ivgm/uypih8EG1+uQuCDkDg0iMMOn4PFr+LPHqv4QVTiy5IwNV4+CIlDXRzW+Bybb6q7cjF+ENX43fyoyXj5ICQOVXFY5HN8faniB9ERv5OUd/OOkg9C4lATh30+B9IPoiu+vB4zH4TEoSQOF/gcGD+IzviY+SAkDrQ43OFzyPpBdMfHywchcSDF4RafQ8YPYiI+Vj4IiQMnDuf4HKJ+EFPxcfJBSBwYcTjJ5xDxg5iMj5EPQuKQFoe7fI4+P4jp+Pj4ICQOSXG4zec45AcZIj42PgiJQ0oc7vM5uvwgQ8XHxQchcUiIww8+h+34mPggJA5hcfjD57AdHw8fhMQhKA6/+By242Phg5A4hMThH5/DdnwcfBASh4A4bPM5bqH9IDbjY+CDkDh6xWGbz5E993B+ENtx//kgJI4ecdjmc8CzSK5wfA7bcd/5ICSOxhPtiMMBPkfM5vBPF/c2OD6H7bjffBASR0Mdr0t9uMHnKPwUL87uXeH4HLbjPvNBSBwd8nCCz3Gn7qf4cnEd4/gctuP+8kFIHK3ycILPUcvnforHi2SL43PYjvvKByFx7MkjipzgczTyuZ/i8SLd4PgctuN+8kFIHHvy+P3vM4HY5nMsu/wU56wHQfE5bMd95IOQOPbkEYFArPI5OvK5n+LF4l5sht9hOu4fH4TEsfNMMnlMJrlArPE5+vwUjxfHsRl+h+m4b3wQEkddHJNpJg92zCH6AxeIBT7HUsRP8buPnm/N8DtMx/3ig5A4auKYzGaZPNg3qOg7PoIMzucQyOd+isvb6cYMv4P4IAflEao4gD/BJlfZP0cmj3KKNSCfQzCf+ylenF1vzPA7iA/SKY9QxZHzJ5g82Co708eMC2RAPoekn+LF2cutGX4H8UFa5RGsOAr+BJtcsQ4wkwf7l8h7kEH4HBg/xYvbzzdm+B3EB9mTR6jiqPEnYGE3+z4F8pjPih7EOJ8Dkc/9FOd/vN6Y4XcQH2RHHsGKo86fKLYFmTyyfxX2Q9GDGORzIPO5n+LFWXplh+8xfj4IiWOXP1FuC34XwTcp9uM870FM8TmQ+ZWf4sUH6Rd2+B5j54OELo4mfwIWdpkc/hQBf4L3IHPegxjhcyDzd/0U54t0K+cncSXuNh8kcHHs8SfYtuC0WLPK4kweWbzoQfTzOXT5KS5zR+HwfI8x80ECFkcrfwIOlcymN6M/cIFkumDx2j6ITj4HMr/dT/Ht2cutHb7HePkgwYqjgz+RyQP4E9Hvyx5kmvfoxVksbXwOZH63n+J88Ty2w/cYKx8kClQcXfwJ6D0msO8xm/IeBOLQok/zfRAtfA5k/mE/xZvbx1s7fI9x8kGiIMXRzZ+AI4lMJt/BXkfecdzkLToMIvArynwOZH6/n+LNIr3q9pPY5H/4yAeJwhPHQb5EJg+I854jG0V4D3IDRpOjo+yHW1wgSnwOJN9DzE/x4uzexk3+h398kCg0cfTwJWDfg/fiEK/1INBzZD8u7/NfwfM5TPspvlyst27yP3zjg0RhiaOXL5HvmvPJVXG4hPcg0JBnX7N/Xt6DoPgcSL6HnJ/ize106yb/oy/uFh8kCkkcAnyJ2q45/BJMqqb5mlVW3NnX7Ftf0YNI8zmQfA95P8Xl4kHsJv9DzM/iBh8kCkccQnwJtnI146MFxPOe41begyTZ12xewwaRYoolwedA8j1wforHizR2k//hDx8k+rPtuh1IHIJ8CSaPLF6sWM3LnqPqQcDPwH7MBSLB5xjYT/E0G0Hc5H+I+Vns80GCkIcEnwMOlbAf/1D2IGXPkfBRBb5rw9dpwnsQMT6HDT/F44fHsZv8DzE/i20+SADykOJz8G1BaMmL0QKKm8kh+wflv5Y1xNnXbIZT9CCH+Rx4voe6n+LxR8nGTf6HD3yQ0ctDks8BXvM5mGmncz5awGoTa8nZP2k+qrDmg/kZ2A95D9LJ58DzPfT4Kb58yO7mdZH/4T4fZOTykOZzwJFEvj3Oeo689FdsmICjELUeBHayYFTJR5BWPgee76HPT/GU+CAkjzZxSPM5+LYgLOjynoOPFiCDNW/JVydFD5LwHiT7Hl70IC18DiTfQ6+fgvgg1Hvsi0Oez5HJ4y9/iaKjWs9RrlilXA5slpyPKkn+ddmDtPE53PBTEB9EXhwjHj2QfI7o9V//8hcmkO/KnmNdrljxXhw25Wr7IKwfZj8UAtnnc7jhpyA+iKw4RisPNJ8jk8dfmUDY2SrG14Aeo+gusjaSfc38Cjs9SPbPCNuF/Ffa+Bxu+CmIDyInjpHKQ4HPAfLIBAKTqnTNe440LUaLFSzoZt/havsgPA77IGnND4Lke5j1UxAfREYco5QH/5tC8jmy3gP08dcIplgrWMDl5V+MFmneg7ApTDGqwNd8ksX9IEi+h3k/BfFBxMUxQnlwhz6OH8HOVrGVKy6QogeBnbZyAZevWPEFXXY2sepBGJ+j8oO466cgPoioOEYnj8lEhA9xgM+RyYP5OUqB5KMF9BblaHECZxLBr1DrQYDPUfODuOunID6ImDhGJo/JRJAPcYDPEQFfoxQITKrWsN8BfoR6D7LiK7rsd7NRBRpykE32K3wfxFk/BfFBRMQxKnkAn0OUD9HL54h2ehAug6zg6j0IW4LMfnxU7oPkZ7P4XIxPsZz1UxAfpF8cI5LHRJIP0c/naPYgUFuwS85HC/imDCtbF/FntbNYLL+2D+Ksn4L4IH3iGI08Sj6HDB+il8+x24OAHwEmVWlajg3Z18DnqPUgkA8rWcXeuqt+CuKDHBbHSORR43NI8iH6+By7PUh+5orFaz0I8DlKOfwpj/MzWsVZLFf9FMQHOSSOUchjh88hyYfo53Ps9iDrfPsvbfODsAWuwj8Ih01WlR/EST/Fr2/5zQdZ3DLNB/FeHg0+hxQfQozP0exBHhX7IKvSD3If5MDy6/sgWX7lB3HRT3EM5eUvH+TeLf6Y44N4Lo89PocEH0Kcz9HsQXhvwfgceemfgBxYfv0sFssvZRRFrvkp4vg3eXn5yQep3t8cH8RrebTwOYT5EHJ8jt0ehK9YwaVutdEC8mGXnY8qkA9HFk9qnnRX/BQlXyS+7SUfpPDTfL9dGOSDeCyPVj6HIB9Cns+x24NsWv0gJ3ABFssvJ1Qw6UrKfRBX/BQVX6Twg/jFByn9NKer9Wm5iqWfD+KtPDr4HEJ8CByfo9mDQH7tLBbkczmUu+s8zs+7l026dT9FyRe5U/eD+MMHKf00pzx857q4tEE3H8RTeXTyOSb9fAg8n2O3B4F8vmJVlP4Jn2SxPcXavVgJ321PV8Xl1Xb9FCVfpOZH4X4QP/ggpZ/mtAovH5jhg3gpjwN8joP8Bxaveg6MH6HRg6xXfH8jOantg0A+HDYp/CD8ShPI5z2IRT9FyRdp+FG4H8R9Psgm/vy8unGyCt9NzgzwQTyUx0E+Rw//oS4OjB/hIt4/i3VSHLKqepBSNuXBEn519arqQez4KUq+SIsfhftB3OaDlCPf/f3w3XVx1EQfH8Q7efTwOQ7yH0pxIPkanM+xdxaLxWEhN/eDsHwuj/W6fjcvb9GLrUMLfomSL7I86Adxlg+SiZvfVXynPf37/HZ3fXwQz+TRy+c4wH+o9jlwfoOKz7HbgyT5BT8sPx8b1nyBN93ZBylMt0WnMrRfonr/Pj+Im3wQ8NPkCypd6cVRE118EK/kIcDn6IyX4kDyNXb5HM2zWAlMsrL8fLR4lC/wnoAs8pUtiGP5IKrx8v2XIn4Q9/ggr8q//8Ppy5fFPogOPohH8pDhOzTj1ZF1nN9gn8+xfxYrbfQgkM9tVOt6D4Lhg6jGy/cv/Sy9fhCn+CBX8ZN8Kbc//fTlmTY+iDfyEORztMarhhznN2jnc+yfxeLNxapxkzt8vhIfRDVevv+On6XPD+IOH6RCXYulL48/0MQH8UQewnyOlnjNz4HyG3TzOXZ7EMgv7FCF0wO86uzqajwfRDVee39JP4gbfJBN8f6n4ul3kvKoiRIfxAt5SPA59uJ1cWD8Bof5HLs9yArKno8alXsQPh/NB1H1Szyrf+eV9oPY54Ns4s+eFpuYMunLZFE26Xg+iAfykOJzNOLVtArnN+jnc+z2IHzXnPM/aid3+WiB4IOo+iXK9+/0s/TxNezyQa7izx7nPZN0+uk194Mcqo+++nFeHpJ8jp34P1erVSg/gRifo9mDQLzmHoTPR/FBVP0Q5fsf9LP08TXs8UE23xRnw3Afz/0st37A1s+NuePykOZz1OLVUi7WTyDK59jtQSCe8z9U+CDqfojPL8X8LH18DTt8EOan4QsKuI/fxP8O6niLrB+gIbksDwSfo4zXzU4qfgKx/MY+CL+qhMXRfBBdfggxP0t3nPM1hueDlH6U+7iPz6aVX4E4fsDVD/eBOCwPFJ8jj9cacjU/gXD+/lmsJB9FMHwQbX4IYT9Ld5zzNYblg1R+FNzHb+Ovz0Ecb3H1w0+EO7xyheRzQLy2Q67mJ5DK3+tB8p5Dng+izQ8h5Wfp42sMxwcp/ShL3MdfwDeHTBx/w9VPxQNxVB5oPkf2k5o41PwE0vl7d/Oi+CDa/BDSfpY+vsYwfJDqVC7u41/FX38L4niHqx+Iu7xrrsDnmNaOj6j5CVD5TT8Ijg+ixw9hgq9hng9S+lF+i/v4TfzZJRcHrn6mO6g1B+WhxOeonIBqfgI0nyPSwgdR9kMg/Sz9fA2zfJDSj/Jb3MdfxZ9ycbzF1Q+LO31iV5HPceuQn0HYT4DM53E8H4TvHuL5IOX7I/0sfXHO1zDHByn9KHdxH/+qHDl08T8ck4cyn6PHzyDkJ0DmV3EcH2SV9+jFvVj49zfN1zDDB6n8KLjX28A+Sb5ahagf6Mxddgvq4HP0+Rl6/QTI/N04hg9yUuyuo/ggr3b8KKb5Gvr5IKUf5RT3ettvPuWrVW9x9TNrhXM6JA+9fA6knwCZvx/H8EF4vLCNyPBByvdH+llk4pyvoZcPUvpRTnGvl4mL73P8B65++IVwDt9Uop/PgfATIPPb4+J8ENZ0qPBBqobcjF+kna+hjw9S+VFwrxcX+xzvcPXDL010+J4rM3wOST8BMr87LsYHgXwFPsim04+ixy/SzdfQwwcp/SinuNe7gJETVqtQ9TOfz6ZO35Jojs8h4SdA5h+Oi/BBIB/NB6ne3wZfQ50P8qwa+VCvt4GlYDZy4OqHxZ2+Y9csn0PQT4DM74/380EgH8kHKd8f6WdR42uwHkSND1L6UZa417uA/36+z4GpnylcKvree87KwzyfQ8BPgMwXi/fxQSAfxQep/BA4P4hq/C4cNcHzQUo/yl3c6z2DaRkTx0j5HsPwOXr8BAp+CLF4Ox8Ebo9T4IOU74/0s+iIc083jg9S+lGWuD/+Kv6UH1n/T1z9gIXWZTrUcHyOA34CRT+EWLyND8L5H1g+SOWHsMvfWF7j+CCVHwX3x2/L4yO4+qnvkDvJFhyWz9HlJxiKr9F6LxYcTcTwQep8DowfRGccwwep8zkwf/wFjDz58RFE/fAJViUD58i0w/M52vwEQ/I1WjzpKY4P0uRz2OZvyPJBmnwO2T9+AyMPm1bh6odf074rBKe45nb4HA0/gUY/BIYPAnEEH6SNz2GbvyHDB2njc8j88ZtvPi0aclT9zFvE0SUQK/Kwx+eo+Qk0+yHE4nr4ICp+FlNxUT5IF59D9I/fxl+/yc9WoeoH4h2rVfsCsSAPu3yO3E9gwA8hFtfDB8H7UczFRfggh/gcIn/8BfRc+VIuon74zkf3SlVTIIPLwz6fw5wfQiyO54NsY0b8xPtBTMf7+CB9fI6+Pz6OP8ltsrr4HX0CGVgebvA5zPkhxOI4Pgi8P2Ma3sf5QYaIH+KDiPA5Dn181pAXt4+g6odfYfVe71MXyKDycIfPYc4PIRbH8EHg/dF+kKHiXXwQUT5H18fHcEKAT6sw9TMTFMeuQAaUh1t8DnN+CLE4hg/COeoYP8iQ8TY+iAyfoy3+RTVyoOpnNplORcVRF8hg8nCPz2HODyEWF+eDZO+v5AcZOt7kg8jyOZrxi/JsFa5+ZMVRCWQgebjJ5zDnhxCLi/FB4P0V/CA24nU+CIbPUY9v4ydPq2mVfP3AnSSS4igEMog83OVzmPNDiMVF+CDw/mg/iGn+xmE+yNOHy1dPUHyOIh7H/1UcH0HVz2Qi3nPsC2QAebjN5zDnhxCL9/NB4P2RfhDT/I3DfJBfc4AAks/B4l+A2QtO5aLqhx8nwYljkMmV+3wOc34IsXgfHwT8KCg/iGn+Rl/8uBAHks/xDPZJwAmI5HMcNjtZl4cffA7b8XY+CHt/FT+Iaf5Gv5/mN7fU+Bx5z/EfeD5Hn5/Dqjz84XPYjrfxQeD90X4Q0/wNP/gcVZPtXO/hF5/Ddny3B7mq9RwYP4h+vwrWT2OXz1EVOkYcBkcP//gctuPNHgT2CVB+EDN+FR/5HHiBGN338JPPYTu+24OAHwXhBzHN3/CJz4EViNFdc3/5HLbjevwgJvkbfvE5cAIxeubKbz6H3fhFrMcPYs6vIuincYTPgRGI0RO7/vM57MX5++P9INCiF1uHFvws7vE55AVi1O8xDj6HnXj1/jg/SJLfn1V0KkP7WVzkc8gKxKhbcDx8juHju3wOjB+Ex2GSlfcgQ/pZ3ORzyAnEqNd8XHyOYeP7fA6MHyTJ8TlJ2YMM5Wdxlc8hIxCjN5WMj88xXLydzyHuB9m9bXHFN9eL4+4D+Fnc5XOIC8ToPVfj5HMME+/mc4j5QWAprN6DnOS9SlKe7zXqZ3GZzyEqEKO3JI6Xz2E+fpjPIeIHgVPBNU56MapAfnkWy5SfxW0+h5hAjN6xa5/Pccsgn8NsvJ/P0e8HgYPAsB9Skm8hzvKrfRAzfhXX+RwiAjF6Q7t9Pkf23LPjZ1CNi/E5+vwgsByUr2Sta6NKyjfTi4mYAb+K+3wOuSmWdnnY53PAk98O7pbfQZgv0utHafeDsHhBtE3z7cMdTnrKe5OiU9HtV/GBz2F19HCBz/H9dgGm/3ubYf0M+vwQWD8IxOsnd/Ptw9VJMaokvAdh+XkPos+v4gefQ2zkMNJ7OMHnOF2tT3NK6r2r4fwM+vwQOD9IfpI32T2LxeWwrjjpSf512YPo8qv4wucQnVZpX7lygs9xyu0Sd6751ZXX8TB+Bm1+CCk/yl4Pkvcc66oH4ZMpmHVV+yAsv3Yvlga/ij98DjFxdOcj5eEEn+O0skssH/CLx5KteT+DNj+EtB+lyQfhLTpv3/kOxwmsZJ3setJZfrmdGEWqfhWf+Byi4uj6NZQ83OBz7Nol7iZn/Ga+jVk/gzY/BMqP0vSDpOVRxMoPAvm1fZDiqCLk/6Fs0pF+Fb/4HHK/T8uZKyf4HC18iLtrdrfrOetBDPI5NPkh0H6U3R5kVZtklWex8h6E5RejCt8vWdd6EEU/jSd8Dtnfo3xi1wk+Rwcf4nu4HfzF4l5sxs+gzQ+h5Edp9iD8gFblSYd8+JqdTazdi5XvHuL5IP7xOVTjkvJwgs9xgA+xXN2GKdZxrN/PoM8PoeoX2etBQA6rcrQ4gUMmkL9zL1Yum8KTjvWjeMTnUB1dpOThBp/jsJ1i+ZI16b/76PlWr59Bmx9Cix9ltwdZw7AA8XoPsuIruvyKhj/lcSwfxE8+h7w4dn+fhDyc4HOc9tspTl+yJv3ydrrR52fQ5ofQ5kfZ3weBeL0HYfmwy17ug6zKo4qSfBBf+RwYcdR/r7A8nOBzCPIhlscfwEbh9cYmv6PND6HTL7LnSWdx2CXPb3Jn+fnK1kqJD+IvnwMnjur3C8rDCT6HBB/iTr6T/nKr7mfQ5ofQ7kfZ7UEgXlzoU4wNsC2460mX5YP4zOfAiqPIEZKHE3wOST7Ekgvk9vONTX5HnS9iwi/S9KSvuFvwUVrrQSAfzQcp/She8jnw4uB5AvJwgs+B4EOcXjOBnP/xeoP3M2jzQxjzo+x70iFeP4u1XufuQXk+SOlH8ZTP0Xcit+/plYcbfA6c3SIfQc7SK9yfr80PgfSziMX3Pen5PkixYpUWd/OuJfkglR/FVz6Hmjh65eEEnwPJh2DxHET/QfrF8PyO8v2RfhbxeLMHSfNr48qb3FF8kNKP4jGfw+jo4QafQ81ukU+xFulW0pCgzQ8xhJ+kcRZrlV/RsHODCeT38kGiUfE5VPMPyMMNPoe63WIJhxUvc0fhMPyO6v2H8pO03osFRxOl+CDR62jXj+I3n0M1v1MeTvA5kHyIZpz3IN+evdwKGhJ0+SGQfhZcvMWTnsrzQV5HY+JzqOZ3yMMJPgeSD9EWX+ZTrOexeX5H+f5IPws+3jyLheCDZPIYE59DNb9VHk7wOZB8iK74cs120t/cPt6a5XdUfggbfhJlPkgmjzHxOVTzW+ThBJ8DyYc4FL//HASySK8O+SlU+RyfleKw4zdR5INk8hgTn0M1f08eTvA5kHyIvvjd/CzWvY2K30Lg/ZF+Fj1xPB9kGzN5jInPoRpvyMMNPoc5O8ad4zO4tGG9NcnnsOMnqeI4Pgj4UTJ5jInPoZq/Iw8n+BxIPoRo/E7yEfQg6dYkn2N4P8luHMMHgffP5DEmPodqfk0eTvA5kHwImfgSBHK5eBCb5HMM6yfZj2P4IIyj/joaE59DNb+Uhxt8jmHsGMuUW27TWMVv0cfnGM5P0h4X54NcxE/KfZDXkfwf7y6fQzU/l4cTfI7T4ewYp2t+9eiD2CSfYxg/SXdcjA8CfpSyB3kdjYnPoZoP8nCCz4HkQ2Dj3/N7sR4exyb5HOb9JIfjInwQGPmKo4ls9BgRn0M1P5OHCp9jesRvSFfjc+D5ECpx7ih8/FGyMcnnMOsn6Y/380Hg/fk9WAkbPcbE51DNj/6swOco1IHla5R+AiQfQjXOj5p8+ZDdzWuOz2HwP0Ao3scHgb9/ftlopo/XkfjHu8/nUM2P/vx3OF6P5CvMfonna5R+AiQfQkf89MFD6EGU3h/pZxku3s4HYX6UfB8EDrpzytTrSPTjfeBzqOZn8vjxx8kEx1dg8R8m7K9Inq9R+gmQfAhd8fsJjg8ix+ewHW/jg4AfpXZyF9KhNRf5eD/4HKr5IA8mEARfIY+/e5/9NcnxNep8DgN2C6k4hg8iz+ewHd/tQa5qPUe5D8LS2egh8PG+8DlU83N5gEDk+Aq1+N9gBBHnazT5HJrtFtJxWT4Ijs9hO97sQeDvv7ZrDuls17z34/3hc6jml/JgAhHnKzTj7z5mf11ifI02PodGuwUqLsMHwfM5bMd3exD4+89veM9vMDlhvceY+Byq+TV5MIEI8hVa4u8+5ALp42t08Tk02S3QcVE+iBqfw3a8eTdvUh5NLE7uMjPtePgcqvk78uBTrD6+Qlf83S/YX9thvsYhPocGu4VSXIQPos7nsBu/iPf3Qfji1nflrvmhj/eNz6Gan/2l/PjjrkDw/I630IN08zX6+ByKdgvleB8fRA+fw16c+1FaGIX8ioY03zXv/Hj/+Byq8ShqEQiev/DDL/kUq42vIcLnULBbaIkf4oPo43PYiVd8joYnHYwgOaKTH2gfDZ9DNT+KWgWC4y+wr7lA9vkaonwOpN1CW7yLD6KXzzF8fJfP0XYvFqSz1nxEfA7V/CjqFIg8f4HH/3PK/hp3+RoyfA7b8TY+iH4+x7DxfT7Hvh8E0uFA+/7H+8rnUM2PogMCkeEv1ONv53yjsOBryPI5bMebfBAzfI7h4u18jmYPAun8QPto+Byq+VF0QCDi/IVmPG/Sga+B4XPYjtf5IOb4HMPEu/kcDT9Iwvc9xsTnUM2PooMCEeMvtMX/BkdNzm8vN09QfA7bcX6zYu39jfA5zMcP8zn2exA2uRoPn0M1P4r6BNLPX+iI/zC9lT94PoTNOL+8Ws3PYjvez+do3ov1OqrHfedzKN/QHvUKBM/3ePuxkh3EepyPIP7+B4jxOXZ7kNdRFfefz6HM94j6BPJ3frcEjs/wFkaQL8/SrbSdwok454Pg/Cy24+J8jnoP8joaE5/DwOjREMjfi2VeeT4Di/Mm/fzs+ELKTuFMnE+x5P0gtuNyfI6qB3nNr64eCZ9DNT+K+gTy92KKJctnKOJ8o/Dy7MEzg3gLg3HOB5Hzg9iOy/M5coHAytV4+Byq+VHUJ5DKDyLHZ6jFf4DTvC8+uL4yiLcwGOc9iLgfxHYcx+cAgcA1cOPhc6jmR1GfQGp+EAk+QyP+9kPeg9zbGsRbGIzzSxvE/CC243g+RyaQTB5j4nOo5kdRn0B2/SBCfIa2eL6Tvji+MIi3MBjnfJB+P4jt/4DSj4Lic7CVqzHxOVTzo77nx4YfpJ/P0BV/+6uiBzGItzAY53yQw34Q2/8BpR8Fy+cAvsd4+Byq+b3y2N8HwfM/uCf9xX//z6tWO0UyCP5CnQ/S6Qex/YKlHwXP5wB5jIfPoRoXkEeLHwTNb3gH+yDfLq63FvEXynyQdj+I7Res/CgqfI5oVHwO1XwhebSMICh+A4u/m+SXNlxYxF8o80H2/SC2X3CryEcZJ59DNV9QHu0jiBy/oYi/yy+OO95axF8oxHM+yI4fxPYLVn4a3MePlc+hmi8sj5YRRIrfUI/zmxUvPzreWsRfKPNBKj+I7Res/Ci4jx8vn0M1X0IeLQIR5jc04/ws1uXDZGsRf6EQ53wQ7gex/YJXinyUMfM5VPOl5LEvEDF+Q1v87fv5FCvmDWPqIh6jlw/y4vbzjd0XfFZdqof6+HHzOVTzJeXR0oP08hu64n/7Fb+04fjCIv5CmQ9y/sfrjb0XvIq//p0KH2XsfA7VfGl5tDXpWD7I/+NTrMWDrcN4jANxftTkxVl6ZecFtt9UTEbMx4+fz6Gaj5DHvh8Ez3d4C6d53yzWW4fxGL18kBcfpF8M/wIx3JKO56OEwOdQzUfJY98PosoHOV8kr9bu4jEOxDkf5HyRbod9gRhuScfzUcLgc6jmI+Wx7wdR5YN8xR2FruIxDsQ5H+QydxQO8wJXsBSL56OEwudQzUfLo8UPosgHuXyYXDiMxzgQ53yQb89ebod5gYv40xcqfJRw+Byq+Qry2PeDqPJBvlqsLhzGY/TyQc4Xz2PzLxCXx0dwHx8Sn0M1X0keLX4QRT7I00XyhcN4jF4+yJvbx1uzL7CJPz9X4aOExedQzVeUx74fRJkPsniwdRaPIcAHebNIr8y9QOUExH18aHwO1Xxleejng1yeHV84iccQ5YOc3duY+QM4nwPPRwmPz6Ea1yAP/XyQ80USO4fHkOCDfLlYb03yOXDvFyKfQzVfizz080GyHmTjFB5Dkg/y5na6NcnnkH+/MPkcqvma5KGfD/LV4nqjDW8xaDzngywexCb5HHLvFyqfQzVfmzwM8EEeXl/BsVLbeAwkH+TxIo31/AHtfA7x9wuXz6Gar1Ee+vkg2QjyzDoeAxXnp3mfZiOIST6H2PuFzOdQzdcqDwN8kMV1nLiMz+jhgzx+eByb5HP0v1/YfA7VfM3y0M8HeXz7eOMsPkOAD/L4o2Rjks9x+P1C53MYuqFd6xRLkQ9yzu7mdRGfIcgH+fIhu5vXHJ+j+88nPocRvodWgRAfhC1TI/gg4nyO9jjxOZwcPRoCIT4Iig8ix+fYjxOfw8neY08gxAdB8EHk+Ry7ceJzOLly1SIQ4oNI80FwfI4qTnwOJ/c9WgVCfBBJPgiez8HjxOdwcte8QyDEB5Hig6jxOdZsn4T4HO6dueoUCPFB8rgIH0SZz1FesEB8Dh35xuVBfBBxPogGPkd1wQLxOTTEB5AH8UHE+CB6+By3iM+hMX8QeRAfpJ8PQnwOF/MHkgfxQQ7zQYjP4Wb+YPIgPkg3H4T4HK7mDygP4oNU8TofhPgc7uYPKg/igzT5IOe3l5snxOdwNn9geRAfJKnxQf7/Lf4Qn8PV/MHlQXyQKn5ciIP4HI7mW5AH8UF4/Cr+zS3ic7idb0UexAcp+BrE53A735I8QueDXBRkJ+JzOJ1vTR4h80E2JdmJ+Bxu51uUR6h8EM7XID6HD/lW5REiH4TzNYjP4Ue+ZXmExge5KE/lEp/Dh3zb6ohC4oNwvgbxOfyJ29ZGq0DGyQfhfA3ic/iUb1sZHQIZHx8krm48JD6HN/m2dXFAIGPig3xRjBzE5/Aq37YqDgpkLHyQi+LIOvE5PMu3rYmDAhkHH4TzNYjP4WO+bUX0CMR/PgjnaxCfw89823roF4jXfJAvCngN8Tm8zLetBgGB+MsHeVZyyInP4We+bS30C8RbPsim6DmIz+Ftvm0l9AvEUz4I52sQn8PvfNs66BeIl3wQztcgPofv+bZV0C8QD/kgnK9BfA7/821roF8g3vFBOF+D+BxjyLetgH6BeMYH4XwN4nOMI992/fcLxCs+yFVxwQLxOUaRb7v6RQTS2Adxlw/yqhg5iM8xkrjt2kcJxE0+yKbgkBOfYzT5tisfKRD3+CCcr0F8jnHl2657tEDc4oNwvgbxOcaWb7vqFQTiDh8kLvY5iM8xsnzbNa8mECf4IJyvQXyOMebbrnhFgdjng2wK1DLxOUaYb7velQVilw/C+RrE5xhrvu1q1yEQa3yQZ4WHnPgcI823XevqArHGB+F8DeJzjDnfdqWrC8QSH4T4HCHk265zdYFY4YMQnyOMfNtVri4QC3wQ4nOEkm+7xtUFMjgfhPgc4eTbrnB1gQzMByE+R0j5tutbXSCD8kGIzxFWvu3q1iGQxj6IOT4I8TlCi9uubSMCMcMHIT5HePm2K9uQQPTzQYjPEWK+7bo2KBCdfBDic4SZb7uqjQpEFx+E+Byh5tuuaaMC0cMHIT5HuPm2K9qwQNT5IHe3/3VOfI5Q823Xs3mBKPJB2EN8jlDzbVfzAAJR5YPcunVPie9BfA5/823XsnmBWOODEJ/D/3zblWxeIJb4IMTn8D//H/+wXcfmBWKFD0J8Dv/z//GP//1f21VsXiAW+CDE5/A/n4lj1PKwxQchPof/+VwcI5eHDT4I8Tn8zy/EMXp5DM0HIT6H//mVOAKQx5B8EOJz+B+viyMIeQzFByE+h//5u+IIRB5D8EGIz+F/fqDiaBOIXj4I8Tn8zw9YHG0C0ccHIT6H//mBi6NVIFr4IMTn8D+fxNEqEHU+yHKbX81DfA5v80kcnQJR5YPwh/gc/uaTOA4LRJEPQnwOn/NJHHtP0w+ixgchPoe/+Zk4wtsG7H+afhAFPgjxObzNh5EjrCMkok/TD4LngxCfw8/8fFoVzvFDuWfPD4LmgxCfw7/8sucI4+g65mn6QfB8EOJz+JVfa8jHb3vCPz9q44MQn8Of/J3VqnFbZlUffXwQ4nP4kd9Yyh3vdQt6nuY+CJ4PQnwO9+O0zyH97G0U4vkbxOdwOp/EgXqaAsHzQYjP4W4+iQP97AsEywchPoeb+SQOpWdfIFg+CPE53MsncSg/TYHg+SDE53Arn8Sh5WmZYiH5IMTncCefxKHt2RMImg9CfA438kkcWp+9KRaaD0J8Dvv5JA7tT9MPQnwOX/PJz2HkafpBiM/hYz75OYw9TT8I8Tl8yyc/h9Fnzw9CfA6P8snPYfxp+kGIz+FLPvk5Bnl+RPFByM9hN5/8HIM98nwQ8nPYzSc/x6BPcx+k4nMwecBgMWGiID6HC3Ha5xj82fODwA4568Ln2f/lhxGJz+FAPonDyrM3gsxAE6w1hztI5nyWRX4Oq/kkDmtP2wjCunI4VQInS8jPYTefxGH12TuLBZMrINfMJ9IHD23vC4wtn8Rh/Wk5rAgP7iJp27vKY8oncTjx7ApkDitWrA+R/8et/wP7eqbJlXwShzPPXg9CfI4R+zn+D45bUlG1HBKRAAAAJnRFWHRDcmVhdGlvbiBUaW1lAHNleCAwOCBkZXogMjAyMyAwNzoyMDoyNJM64DQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMTItMDlUMDA6NTI6NTErMDA6MDBieYF0AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTEyLTA5VDAwOjUyOjUxKzAwOjAwEyQ5yAAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyMy0xMi0wOVQwMDo1MzoxNiswMDowMOoeQ10AAAAZdEVYdFNvZnR3YXJlAGdub21lLXNjcmVlbnNob3TvA78+AAAAAElFTkSuQmCC'; diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 6417eda..11c0658 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -31,7 +31,7 @@ model Drill { title String description String observations String - image String @default("data:image/png;base64,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") + image String @default("data:image/png;base64,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") classPlanId String classPlan ClassPlan @relation(fields: [classPlanId], references: [id]) drillElements DrillElement[] diff --git a/backend/src/controllers/classPlanController.ts b/backend/src/controllers/classPlanController.ts index 86505d9..83a072c 100644 --- a/backend/src/controllers/classPlanController.ts +++ b/backend/src/controllers/classPlanController.ts @@ -40,14 +40,9 @@ export default class classPlanController { where: { userId: userId, }, - include: { - user: { - select: { - id: true, - email: true, - name: true, - }, - }, + select: { + id: true, + title: true, }, }) res.status(200).json(classPlan) @@ -62,14 +57,12 @@ export default class classPlanController { where: { id: id, }, - include: { - user: { - select: { - id: true, - email: true, - name: true, - }, - }, + select: { + id: true, + title: true, + goals: true, + observations: true, + userId: true, }, }) res.status(200).json(classPlan) @@ -78,20 +71,113 @@ export default class classPlanController { } } + searchByCreatedAtOrTitle = async (req: Request, res: Response) => { + try { + const { userId, title, startDate, finalDate } = req.params + if (startDate == "_") { + const classPlan = await prisma.classPlan.findMany({ + where: { + userId: userId, + title: { contains: title }, + }, + select: { + id: true, + title: true, + }, + }) + res.status(200).json(classPlan) + } else if (title == "_") { + const start = new Date(startDate) + const final = new Date(finalDate) + const classPlan = await prisma.classPlan.findMany({ + where: { + userId: userId, + createdAt: { + lte: final, + gte: start, + }, + }, + select: { + id: true, + title: true, + }, + }) + res.status(200).json(classPlan) + } else { + const start = new Date(startDate) + const final = new Date(finalDate) + const classPlan = await prisma.classPlan.findMany({ + where: { + userId: userId, + createdAt: { + lte: final, + gte: start, + }, + title: { contains: title }, + }, + select: { + id: true, + title: true, + }, + }) + res.status(200).json(classPlan) + } + } catch (err) { + res.status(500).json({ error: "Internal Server Error" }) + } + } + delete = async (req: Request, res: Response) => { try { const { id } = req.params + const data = await prisma.classPlan.findMany({ + where: { + id, + }, + select: { + id: true, + drills: { + select: { + id: true, + drillElements: { + select: { + id: true, + }, + }, + }, + }, + }, + }) - const classPlan = await prisma.classPlan.deleteMany({ - where: { id }, + data.map(async (item) => { + item.drills.map(async (drill) => { + drill.drillElements.map(async (drillElement) => { + await prisma.drillElement.delete({ + where: { + id: drillElement.id, + }, + }) + }) + await prisma.drill.delete({ + where: { + id: drill.id, + }, + }) + }) }) - res.status(200).json(classPlan) + const plan = await prisma.classPlan.delete({ + where: { + id, + }, + }) + res.status(200).json(plan) } catch (err) { err as Prisma.PrismaClientKnownRequestError res.status(500).json({ errors: { server: "Server error" } }) } } + updateById = async (req: Request, res: Response) => { try { const id = req.params.id diff --git a/backend/src/controllers/drillController.ts b/backend/src/controllers/drillController.ts index 821c203..51292c7 100644 --- a/backend/src/controllers/drillController.ts +++ b/backend/src/controllers/drillController.ts @@ -84,6 +84,7 @@ export default class drillController { image, }, }) + console.log("Foi") res.status(204).json(updatedDrill) } catch (err) { res.status(500).json({ error: "Internal Server Error" }) @@ -93,12 +94,36 @@ export default class drillController { deleteById = async (req: Request, res: Response) => { try { const id = req.params.id - const deletedDrill = await prisma.drill.deleteMany({ + + const drills = await prisma.drill.findMany({ where: { id, }, + select: { + drillElements: { + select: { + id: true, + }, + }, + }, + }) + + drills.map(async (drill) => { + drill.drillElements.map(async (drillElement) => { + await prisma.drillElement.delete({ + where: { + id: drillElement.id, + }, + }) + }) + await prisma.drill.delete({ + where: { + id, + }, + }) }) - res.status(204).json(deletedDrill) + + res.status(204).json({ message: "Drill deleted" }) } catch (err) { console.log(err) res.status(500).json({ error: "Internal Server Error" }) diff --git a/backend/src/middleware/authUser.ts b/backend/src/middleware/authUser.ts index dd8d6aa..cc3adc2 100644 --- a/backend/src/middleware/authUser.ts +++ b/backend/src/middleware/authUser.ts @@ -1,4 +1,5 @@ -import { sign } from "jsonwebtoken" +import { sign, verify } from "jsonwebtoken" +import { Request, Response, NextFunction } from "express" interface Idata { id: string @@ -11,4 +12,22 @@ export default class AuthUser { expiresIn: "30d", }) } + + async auth( + request: Request, + response: Response, + next: NextFunction, + ): Promise { + let token + try { + token = request.headers.authorization?.split(" ")[1] + verify(token as string, process.env.AUTH_CONFIG_SECRET as string) + } catch (err) { + return response.status(401).json({ + message: "Token inválido!", + }) + } + next() + return null + } } diff --git a/backend/src/routes/classPlanRouters.ts b/backend/src/routes/classPlanRouters.ts index 042fce4..0f9bf74 100644 --- a/backend/src/routes/classPlanRouters.ts +++ b/backend/src/routes/classPlanRouters.ts @@ -1,13 +1,20 @@ import { Router } from "express" import classPlanController from "../controllers/classPlanController" +import AuthUser from "../middleware/authUser" const classPlanRouters = Router() +const authenticateUser = new AuthUser() const classPlan = new classPlanController() -classPlanRouters.post("/", classPlan.create) -classPlanRouters.get("/:id", classPlan.show) +classPlanRouters.post("/", authenticateUser.auth, classPlan.create) +classPlanRouters.get("/:id", authenticateUser.auth, classPlan.show) +classPlanRouters.get( + "/pesquisa-data-titulo/:userId/:title/:startDate/:finalDate", + authenticateUser.auth, + classPlan.searchByCreatedAtOrTitle, +) classPlanRouters.get("/planos-usuario/:userId", classPlan.list) -classPlanRouters.put("/:id", classPlan.updateById) -classPlanRouters.delete("/:id", classPlan.delete) +classPlanRouters.put("/:id", authenticateUser.auth, classPlan.updateById) +classPlanRouters.delete("/:id", authenticateUser.auth, classPlan.delete) export default classPlanRouters diff --git a/backend/src/routes/drillElementRouters.ts b/backend/src/routes/drillElementRouters.ts index c2e2835..b7bac00 100644 --- a/backend/src/routes/drillElementRouters.ts +++ b/backend/src/routes/drillElementRouters.ts @@ -1,12 +1,22 @@ import { Router } from "express" import drillElementController from "@/controllers/drillElementController" +import AuthUser from "../middleware/authUser" const drillElementRouters = Router() +const authenticateUser = new AuthUser() const drillElement = new drillElementController() -drillElementRouters.post("/", drillElement.create) -drillElementRouters.get("/:drillId", drillElement.getManyByDrillId) -drillElementRouters.put("/:id", drillElement.updateById) -drillElementRouters.delete("/:id", drillElement.deleteById) +drillElementRouters.post("/", authenticateUser.auth, drillElement.create) +drillElementRouters.get( + "/:drillId", + authenticateUser.auth, + drillElement.getManyByDrillId, +) +drillElementRouters.put("/:id", authenticateUser.auth, drillElement.updateById) +drillElementRouters.delete( + "/:id", + authenticateUser.auth, + drillElement.deleteById, +) export default drillElementRouters diff --git a/backend/src/routes/drillRouters.ts b/backend/src/routes/drillRouters.ts index 169cf22..360a3d5 100644 --- a/backend/src/routes/drillRouters.ts +++ b/backend/src/routes/drillRouters.ts @@ -1,14 +1,20 @@ import { Router } from "express" import drillController from "../controllers/drillController" +import AuthUser from "../middleware/authUser" +const authenticateUser = new AuthUser() const drillRouters = Router() const drill = new drillController() -drillRouters.post("/", drill.create) -drillRouters.get("/:classPlanId", drill.getManyByClassPlanId) -drillRouters.get("/drill/:id", drill.show) -drillRouters.put("/:id", drill.updateById) -drillRouters.put("/image/:id", drill.updateImage) -drillRouters.delete("/:id", drill.deleteById) +drillRouters.post("/", authenticateUser.auth, drill.create) +drillRouters.get( + "/:classPlanId", + authenticateUser.auth, + drill.getManyByClassPlanId, +) +drillRouters.get("/drill/:id", authenticateUser.auth, drill.show) +drillRouters.put("/:id", authenticateUser.auth, drill.updateById) +drillRouters.put("/image/:id", authenticateUser.auth, drill.updateImage) +drillRouters.delete("/:id", authenticateUser.auth, drill.deleteById) export default drillRouters diff --git a/backend/src/zodSchemas/drill.zod.ts b/backend/src/zodSchemas/drill.zod.ts index bad0550..d947046 100644 --- a/backend/src/zodSchemas/drill.zod.ts +++ b/backend/src/zodSchemas/drill.zod.ts @@ -9,7 +9,6 @@ const drillSchema = z.object({ .string() .max(500, "Observações deve ter no máximo 500 caracteres"), classPlanId: z.string().uuid("Id do plano de aula inválido"), - image: z.string(), }) export { drillSchema } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3d5d101..c326979 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,6 +12,7 @@ "apexcharts": "^3.41.0", "axios": "^1.6.2", "headlessui": "^0.0.0", + "html2canvas": "^1.4.1", "jsvectormap": "^1.5.3", "match-sorter": "^6.3.1", "react": "^18.2.0", @@ -24,6 +25,7 @@ "sort-by": "^0.0.2" }, "devDependencies": { + "@iconify/react": "^4.1.1", "@types/react": "^18.2.17", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", @@ -758,6 +760,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/@iconify/react/-/react-4.1.1.tgz", "integrity": "sha512-jed14EjvKjee8mc0eoscGxlg7mSQRkwQG3iX3cPBCO7UlOjz0DtlvTqxqEcHUJGh+z1VJ31Yhu5B9PxfO0zbdg==", + "dev": true, "dependencies": { "@iconify/types": "^2.0.0" }, @@ -771,7 +774,8 @@ "node_modules/@iconify/types": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", @@ -1276,6 +1280,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -1500,6 +1512,14 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -1943,6 +1963,18 @@ "resolved": "https://registry.npmjs.org/headlessui/-/headlessui-0.0.0.tgz", "integrity": "sha512-CHvacVPbl8AqIg2sBNKySUmumu7o15jSrCaTrIh9GW2Eq4y/krCN/vZFOsKCwlrhWQbO4267a8xvvP8bs+qREQ==" }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3188,6 +3220,14 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -3281,6 +3321,14 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/vite": { "version": "4.4.7", "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.7.tgz", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6ec304b..bfde9dd 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -8,6 +8,7 @@ import Loader from './common/Loader'; import routes from './routes'; import ViewPlan from './pages/ViewPlan'; import Drill from './pages/Drill'; +import FilteredClassPlans from './pages/FilteredClassPlans'; const DefaultLayout = lazy(() => import('./layout/DefaultLayout')); @@ -39,6 +40,7 @@ function App() { } /> + } /> } /> }> {/* } /> */} diff --git a/frontend/src/components/DrillElement.tsx b/frontend/src/components/DrillElement.tsx index 6dd3dff..330c7aa 100644 --- a/frontend/src/components/DrillElement.tsx +++ b/frontend/src/components/DrillElement.tsx @@ -1,12 +1,30 @@ -import React from "react"; -import useDragger from "./useDragger"; +import React from 'react'; +import useDragger from './useDragger'; +const DrillElement: React.FC<{ + id: string; + deleteItem: (idDeleted: string) => void; + image: any; + elementWidth: number; + top: number; + left: number; +}> = ({ id, deleteItem, image, elementWidth, top, left }) => { + useDragger(id, deleteItem); + return ( + Drill Element + ); +}; -const DrillElement: React.FC<{id : string, deleteItem : (idDeleted: string) => void, image: any, elementWidth: number, top: number, left: number}> = ({id, deleteItem, image, elementWidth, top, left}) => { - useDragger(id, deleteItem); - return( - Drill Element - ); -} - -export default DrillElement; \ No newline at end of file +export default DrillElement; diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index 406b651..2f52090 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -1,13 +1,24 @@ -import { Link } from 'react-router-dom'; import { Icon } from '@iconify/react/dist/iconify.js'; +import { useEffect, useState } from 'react'; -const Header = (props: { path: string; hasReturnArrow: boolean }) => { +const Header = (props: { + hasReturnArrow: boolean; + changeScreenFunction: () => void; +}) => { const logout = () => { localStorage.removeItem('token'); localStorage.removeItem('user'); window.location.href = '/login'; }; + useEffect(() => { + console.log("Aqui"); + const user = localStorage.getItem('user'); + if(!user){ + logout(); + } + }, []); + return (
{ >
{props.hasReturnArrow ? ( - + ) : (
)} diff --git a/frontend/src/components/useDragger.tsx b/frontend/src/components/useDragger.tsx index e300b98..9ee688b 100644 --- a/frontend/src/components/useDragger.tsx +++ b/frontend/src/components/useDragger.tsx @@ -1,64 +1,72 @@ -import { useEffect, useRef } from "react"; +import { useEffect, useRef } from 'react'; -function useDragger(id: string, deleteItem : (idDeleted: string) => void) : void{ +function useDragger(id: string, deleteItem: (idDeleted: string) => void): void { const isClicked = useRef(0); const coords = useRef<{ - startX: number, - startY: number + startX: number; + startY: number; }>({ startX: 0, - startY: 0 - }) + startY: 0, + }); useEffect(() => { const target = document.getElementById(id); - if(!target) throw new Error("Target with given id doesn't exist"); + if (!target) throw new Error("Target with given id doesn't exist"); const container = target.parentElement; - if(!container) throw new Error("Element must have a parent"); - const trash = document.getElementById("apagar"); - if(!trash) throw new Error("Element with given id doesn't exist"); + if (!container) throw new Error('Element must have a parent'); + const trash = document.getElementById('apagar'); + if (!trash) throw new Error("Element with given id doesn't exist"); const mouseDown = (e: MouseEvent) => { - if(!isClicked.current) { + if (!isClicked.current) { target.style.border = '2px solid rgb(59, 152, 245)'; - isClicked.current = 1; - trash.style.visibility = "visible"; + isClicked.current = 1; + trash.style.visibility = 'visible'; return; - } - trash.style.visibility = "hidden"; + } + trash.style.visibility = 'hidden'; if (isClicked.current === 2) { const bodyRect = container.getBoundingClientRect(); coords.current.startX = bodyRect.left; coords.current.startY = bodyRect.top; - target.style.top = `${e.clientY - coords.current.startY - (target.offsetHeight-4)/2}px`; - target.style.left = `${e.clientX - coords.current.startX - (target.offsetWidth-4)/2}px`; + target.style.top = `${ + e.clientY - coords.current.startY - (target.offsetHeight - 4) / 2 + }px`; + target.style.left = `${ + e.clientX - coords.current.startX - (target.offsetWidth - 4) / 2 + }px`; target.style.border = 'none'; } isClicked.current = 0; - } + }; const mouseDownContainer = (e: MouseEvent) => { - if(!isClicked.current) return; - if(isClicked.current === 1){ + if (!isClicked.current) return; + if (isClicked.current === 1) { isClicked.current = 2; } else { const bodyRect = container.getBoundingClientRect(); coords.current.startX = bodyRect.left; coords.current.startY = bodyRect.top; - target.style.top = `${e.clientY - coords.current.startY - (target.offsetHeight-4)/2}px`; - target.style.left = `${e.clientX - coords.current.startX - (target.offsetWidth-4)/2}px`; + target.style.top = `${ + e.clientY - coords.current.startY - (target.offsetHeight - 4) / 2 + }px`; + target.style.left = `${ + e.clientX - coords.current.startX - (target.offsetWidth - 4) / 2 + }px`; isClicked.current = 0; target.style.border = 'none'; - trash.style.visibility = "hidden"; + trash.style.visibility = 'hidden'; } - } + }; const clickTrash = () => { - if(!isClicked.current) return; + if (!isClicked.current) return; deleteItem(id); trash.style.backgroundColor = 'inherit'; - trash.style.visibility = "hidden"; - } + trash.style.visibility = 'hidden'; + }; target.addEventListener('mousedown', mouseDown); container.addEventListener('mousedown', mouseDownContainer); @@ -68,10 +76,10 @@ function useDragger(id: string, deleteItem : (idDeleted: string) => void) : void target.removeEventListener('mousedown', mouseDown); container.removeEventListener('mousedown', mouseDownContainer); trash.removeEventListener('mousedown', clickTrash); - } + }; return cleanup; - }, [id, deleteItem]) + }, [id, deleteItem]); } -export default useDragger; \ No newline at end of file +export default useDragger; diff --git a/frontend/src/index.css b/frontend/src/index.css index 043ac03..5e289f4 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -288,12 +288,33 @@ } .buttonsPanel { - width: 100vw; + width: 100%; display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 330px)); grid-gap: 20px; } +.searchClassPlanPanel { + width: 100%; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 250px)); + grid-gap: 20px; + margin: 15px 0px; +} + +input[type='date']::-webkit-calendar-picker-indicator { + opacity: 1; + color-scheme: dark; + width: 25px; + height: 20px; + border-width: thin; + box-sizing: content-box; + margin: 0px; +} + +.datepickerbg { + color-scheme: dark; +} .itemButton { height: 115px; background-color: #5899eb; @@ -342,13 +363,39 @@ padding-right: 10px; } -.contentDrill { +.titleLayoutClassPLan { + display: flex; + flex-direction: row; + margin: auto; + width: 90%; +} + +.titleLayoutClassPLan { + display: flex; + flex-direction: row; + margin: auto; + width: 90%; +} + +.contentDrill{ display: flex; justify-content: space-between; padding: 0px 15px; } -#drillGraphicContainer { +.contentClassPlan{ + display: flex; + flex-direction: column; + align-items: center; +} + +.contentClassPlan { + display: flex; + flex-direction: column; + align-items: center; +} + +#drillGraphicContainer{ margin-top: 5px; height: 406px; width: 800px; @@ -377,15 +424,19 @@ background-color: #494949; padding: 15px; border-radius: 20px; - height: 300px; + min-height: 300px; width: 350px; + box-sizing: content-box; + height: fit-content; } .pClassPlan { - color: white; + margin: 10px auto; background-color: #494949; padding: 15px; border-radius: 20px; + min-height: 300px; + box-sizing: content-box; height: fit-content; width: 90%; } @@ -410,14 +461,22 @@ border: '1px solid black'; } -.textAreaDrill { - background-color: #494949; - border-radius: 20px; - height: 300px; - width: 250px; - height: 300px; - width: 350px; - padding: 15px; +.drillButtonsPanel { + width: 100%; + margin-top: 5px; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(40px, 40px)); + grid-gap: 2px; + justify-content: center; +} + +.buttonAddElementDrill { + background-color: gray; + border-radius: 5px; + display: flex; + justify-content: center; + align-items: center; + min-height: 45px; } @media (max-width: 910px) { @@ -431,11 +490,23 @@ .drillPage { color: white; - width: 100vw; - height: 100vh; + width: 100%; + height: 100%; display: flex; flex-direction: column; background-color: #272727; padding-bottom: 10px; } -} \ No newline at end of file + + .contentDrill { + flex-direction: column; + } + + #img_drill { + display: none; + } + + .pageDrill { + padding: 0px; + } +} diff --git a/frontend/src/lib.d.ts b/frontend/src/lib.d.ts index 77fa6c8..091d25e 100644 --- a/frontend/src/lib.d.ts +++ b/frontend/src/lib.d.ts @@ -1,4 +1,4 @@ declare module '*.svg' { const content: any; export default content; -} \ No newline at end of file +} diff --git a/frontend/src/pages/Authentication/SignIn.tsx b/frontend/src/pages/Authentication/SignIn.tsx index 6836977..4d38efd 100644 --- a/frontend/src/pages/Authentication/SignIn.tsx +++ b/frontend/src/pages/Authentication/SignIn.tsx @@ -7,10 +7,12 @@ import { Icon } from '@iconify/react/dist/iconify.js'; import '../../index.css'; import Logo from '../../images/logoBeachTennisCoordimate.png'; import { Link } from 'react-router-dom'; +import ClassPlanService from '../../service/classPlanService'; const SignIn = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); + const classPlan = new ClassPlanService(); const handleSignIn = async () => { try { @@ -25,11 +27,20 @@ const SignIn = () => { if (data.status === 200) { localStorage.setItem('token', data.data.token); console.log(data.data); - localStorage.setItem('user', JSON.stringify(data.data)); - toast.success('Login realizado com sucesso!'); - setTimeout(() => { - window.location.href = '/'; - }, 3000); + const data_user = JSON.stringify(data.data); + localStorage.setItem('user', data_user); + try { + const user_id = String(JSON.parse(data_user).id); + let userClassPlans = await classPlan.getManyById(user_id as string); + localStorage.setItem( + 'userClassPlans', + JSON.stringify(userClassPlans.data), + ); + toast.success('Login realizado com sucesso!'); + setTimeout(() => { + window.location.href = '/'; + }, 3000); + } catch (error) {} } return; } diff --git a/frontend/src/pages/ClassPlans.tsx b/frontend/src/pages/ClassPlans.tsx index 74ed2ef..f8c9e1d 100644 --- a/frontend/src/pages/ClassPlans.tsx +++ b/frontend/src/pages/ClassPlans.tsx @@ -1,17 +1,23 @@ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import '../index.css'; import { Icon } from '@iconify/react'; import { toast, ToastContainer } from 'react-toastify'; import ClassPlanService from '../service/classPlanService'; -import { Link } from 'react-router-dom'; import Header from '../components/Header'; +import DrillService from '../service/drillService'; const ClassPlans = () => { - const [classPlans, setClassPlans] = useState([]); + const userClassPlans = localStorage.getItem('userClassPlans'); + const [classPlans, setClassPlans] = useState( + JSON.parse(userClassPlans ? userClassPlans : ''), + ); const userString = localStorage.getItem('user'); const [deletedItem, setDeletedItem] = useState(''); const [deletedItemTitle, setDeletedItemTitle] = useState(''); const [visibleDel, setVisibleDel] = useState(false); + const [searchedTitle, setSearchedTitle] = useState(''); + const [initialDate, setInitialDate] = useState(''); + const [finalDate, setFinalDate] = useState(''); let id: String; if (userString !== null) { const user = JSON.parse(userString); @@ -20,13 +26,11 @@ const ClassPlans = () => { id = ''; } - useEffect(() => { - loadPlans(); - }, []); - const [title, setTitle] = useState(''); const [visible, setVisible] = useState(false); const classPlan = new ClassPlanService(); + const drill = new DrillService(); + let data = { id: '', title: title, @@ -34,12 +38,6 @@ const ClassPlans = () => { observations: '', userId: id, }; - const [plans, setPlans] = useState([data]); - - async function loadPlans() { - const response = await classPlan.get('/'); - setPlans(response.data); - } const addClassPlan = () => { setVisible(true); @@ -58,7 +56,8 @@ const ClassPlans = () => { else if (title.length < 5) toast.warning('O título deve ter no mínimo 5 caracteres'); else { - await classPlan.save(data); + let newClassPlanData = await classPlan.save(data); + setClassPlans((prevArray) => [...prevArray, newClassPlanData.data]); toast.success('Plano de aula cadastrado com sucesso'); closeNewItemPanel(); setTitle(''); @@ -82,6 +81,9 @@ const ClassPlans = () => { const handleDeleteClassPlan = async () => { try { await classPlan.remove(deletedItem); + setClassPlans((prevItems) => + prevItems.filter((item) => item.id != deletedItem), + ); toast.success('Plano de aula excluído com sucesso'); closeDeleteItemPanel(); setDeletedItem(''); @@ -91,31 +93,155 @@ const ClassPlans = () => { return; }; - useEffect(() => { - if (id != '') { - classPlan - .getManyById(id as string) - .then((response) => { - setClassPlans(response.data); - }) - .catch(() => { - setClassPlans([]); - }); + const redirectToViewPlan = async (selectedId: string) => { + try { + const response = await classPlan.getById(selectedId); + localStorage.setItem('selectedClassPlan', JSON.stringify(response.data)); + const drillsClassPlan = await drill.getManyByClassPlanId(selectedId); + const drillData = drillsClassPlan.data; + localStorage.setItem( + 'drillsSelectedClassPlan', + JSON.stringify(drillData), + ); + setTimeout(() => { + window.location.href = `/plano-aula/${selectedId}`; + }, 3000); + } catch (error) { + toast.error('Erro ao buscar informações do plano'); + } + }; + + const searchClassPlans = async () => { + try { + let tit_proc, data_ini_proc, data_final_proc; + if (searchedTitle) { + tit_proc = searchedTitle; + if ((initialDate && !finalDate) || (!initialDate && finalDate)) { + toast.warning( + 'Preencha os dois campos de data ou limpe os dois caso deseje pesquisar apenas por título', + ); + return; + } + if (initialDate) { + data_ini_proc = initialDate; + data_final_proc = finalDate; + } else { + data_ini_proc = '_'; + data_final_proc = '_'; + } + } else if (initialDate || finalDate) { + if (!finalDate || !initialDate) { + toast.warning( + 'Preencha os dois campos de data caso deseje pesquisar pela data de criação', + ); + return; + } + tit_proc = '_'; + data_ini_proc = initialDate; + data_final_proc = finalDate; + } else { + toast.warning( + 'Preencha os campos para pesquisar por título, data de criação ou pelos dois filtros', + ); + return; + } + let userClassPlans = await classPlan.getManyByTitleOrDate( + id as string, + tit_proc, + data_ini_proc, + data_final_proc, + ); + console.log(userClassPlans.data); + localStorage.setItem( + 'userClassPlans', + JSON.stringify(userClassPlans.data), + ); + toast.success('Pesquisa realizada com sucesso!'); + setTimeout(() => { + window.location.href = '/pesquisa'; + }, 3000); + } catch (error) { + toast.error('Erro ao procurar planos'); } - }, [classPlan, id]); - console.log(classPlans); + }; + return ( <> } /> -
+
{}} hasReturnArrow={false}>

Meus Planos de Aula

+
+
+

Título

+ setSearchedTitle(e.target.value)} + > +
+
+

Data Início

+ setInitialDate(e.target.value)} + > +
+
+

Data Fim

+ setFinalDate(e.target.value)} + > +
+
+ +
+
{ ); }; -export default ClassPlans; \ No newline at end of file +export default ClassPlans; diff --git a/frontend/src/pages/Drill.tsx b/frontend/src/pages/Drill.tsx index fd105b7..bbeee85 100644 --- a/frontend/src/pages/Drill.tsx +++ b/frontend/src/pages/Drill.tsx @@ -1,26 +1,26 @@ -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import '../index.css'; import { Icon } from '@iconify/react'; import { toast, ToastContainer } from 'react-toastify'; import DrillService from '../service/drillService'; -import { useParams } from 'react-router-dom'; import html2canvas from 'html2canvas'; import Header from '../components/Header'; import DrillElement from '../components/DrillElement'; -import arco from "../images/drillElements/arco.png"; -import avatar_x_neg from "../images/drillElements/avatar_x-.png"; -import avatar_x_pos from "../images/drillElements/avatar_x+.png"; -import avatar_y_neg from "../images/drillElements/avatar_y-.png"; -import avatar_y_pos from "../images/drillElements/avatar_y+.png"; -import bola_tenis from "../images/drillElements/bola_tenis.png"; -import cano_alt_x from "../images/drillElements/cano_alt_x.png"; -import cano_alt_y from "../images/drillElements/cano_alt_y.png"; -import cone from "../images/drillElements/cone.png"; -import seta_x_neg from "../images/drillElements/seta_x-.png"; -import seta_x_pos from "../images/drillElements/seta_x+.png"; -import seta_y_neg from "../images/drillElements/seta_y-.png"; -import seta_y_pos from "../images/drillElements/seta_y+.png"; +import arco from '../images/drillElements/arco.png'; +import avatar_x_neg from '../images/drillElements/avatar_x-.png'; +import avatar_x_pos from '../images/drillElements/avatar_x+.png'; +import avatar_y_neg from '../images/drillElements/avatar_y-.png'; +import avatar_y_pos from '../images/drillElements/avatar_y+.png'; +import bola_tenis from '../images/drillElements/bola_tenis.png'; +import cano_alt_x from '../images/drillElements/cano_alt_x.png'; +import cano_alt_y from '../images/drillElements/cano_alt_y.png'; +import cone from '../images/drillElements/cone.png'; +import seta_x_neg from '../images/drillElements/seta_x-.png'; +import seta_x_pos from '../images/drillElements/seta_x+.png'; +import seta_y_neg from '../images/drillElements/seta_y-.png'; +import seta_y_pos from '../images/drillElements/seta_y+.png'; import DrillElementService from '../service/drillElementService'; +import ClassPlanService from '../service/classPlanService'; const Drill = () => { const listImages = [ @@ -36,7 +36,7 @@ const Drill = () => { seta_x_neg, seta_x_pos, seta_y_neg, - seta_y_pos + seta_y_pos, ]; const listButtons = [ [0, 50, arco, 35], @@ -51,167 +51,128 @@ const Drill = () => { [9, 30, seta_x_neg, 25], [10, 30, seta_x_pos, 25], [11, 30, seta_y_neg, 25], - [12, 30, seta_y_pos, 25] - ] - const { id } = useParams(); - const [title, setTitle] = useState(''); + [12, 30, seta_y_pos, 25], + ]; + const stringSelectedDrill = localStorage.getItem('selectedDrill'); + const selectedDrill = JSON.parse( + stringSelectedDrill ? stringSelectedDrill : '', + ); + const stringDrillSelectedElements = localStorage.getItem( + 'drillSelectedElements', + ); + const drillSelectedElements = JSON.parse( + stringDrillSelectedElements ? stringDrillSelectedElements : '', + ); + const [title, setTitle] = useState(selectedDrill.title); const [imagemBase64, setimagemBase64] = useState(''); const [titleAux, setTitleAux] = useState(''); - const [description, setDescription] = useState(''); + const [description, setDescription] = useState(selectedDrill.description); const [descriptionAux, setDescriptionAux] = useState(''); - const [observations, setObservations] = useState(''); + const [observations, setObservations] = useState(selectedDrill.observations); const [observationsAux, setObservationsAux] = useState(''); const [titleNotEdited, setTitleNotEdited] = useState(true); const [descriptionNotEdited, setDescriptionNotEdited] = useState(true); const [observationsNotEdited, setObservationsNotEdited] = useState(true); const drill = new DrillService(); const drillElement = new DrillElementService(); - const [drillUpdated, setDrillUpdated] = useState({ - id: '', - title: '', - description: '', - observations: '', - image: '', - classPlanId: '', - }); const [newItems, setNewItems] = useState(Array<[string, number, number]>); - const [savedItems, setSavedItems] = useState([{ - id: 'id0', - index: 0, - left: 0, - top: 0 - }] - ); + const [savedItems, setSavedItems] = useState(drillSelectedElements); const [deletedSavedIds, setDeletedSavedIds] = useState([]); const [count, setCount] = useState(0); - const updateImagen = () => { - const captureElement = document.querySelector('#drillGraphicContainer') - if(captureElement != null){ - html2canvas(captureElement as HTMLElement).then(canvas => { - const imgData = canvas.toDataURL('image/png'); - setimagemBase64(imgData) - }); - } - } - + const captureElement = document.querySelector('#drillGraphicContainer'); + if (captureElement != null) { + html2canvas(captureElement as HTMLElement).then((canvas) => { + const imgData = canvas.toDataURL('image/png'); + setimagemBase64(imgData); + }); + } + }; - const addDrillElement = (typeImage : number, width: number) => { + const addDrillElement = (typeImage: number, width: number) => { setNewItems([...newItems, [String(count), typeImage, width]]); setCount(count + 1); - } + }; - const deleteNewItem = (idDeleted : string) => { - setNewItems((prevItems) => prevItems.filter((id) => id[0] !== idDeleted)); - } + const deleteNewItem = (idDeleted: string) => { + setNewItems((prevItems) => prevItems.filter((id) => id[0] !== idDeleted)); + }; const deleteSavedItem = (idDeleted: string) => { - const node = document.getElementById(idDeleted); - if(node){ - node.style.display = 'none'; - setDeletedSavedIds((prevArray) => [...prevArray, idDeleted]); - } - } - - async function saveDrillState(){ - updateImagen() - let data = { - id: drillUpdated.id, - title: titleAux, - image: imagemBase64, - description: drillUpdated.description, - observations: drillUpdated.observations, - classPlanId: drillUpdated.classPlanId, - }; - console.log(data) - await drill.updateById(id as string, data); - for(const [idNewItem, indexNewItem] of newItems){ - try{ + setSavedItems((prevItems) => + prevItems.filter((item) => item.id !== idDeleted), + ); + setDeletedSavedIds((prevArray) => [...prevArray, idDeleted]); + }; + + async function saveDrillState() { + updateImagen(); + let data = { + image: imagemBase64 + }; + console.log(data.image) + await drill.updateImage(selectedDrill.id, data); + for (const [idNewItem, indexNewItem] of newItems) { + try { const element = document.getElementById(idNewItem); - if(element != null){ + if (element != null) { let data = { index: indexNewItem, top: parseInt(element.style.top.slice(0, -2)), left: parseInt(element.style.left.slice(0, -2)), - drillId: id + drillId: selectedDrill.id, }; await drillElement.save(data); } } catch (error) { toast.error('Erro ao salvar elementos'); return; - } + } } - for(const savedItem of savedItems){ - try{ + for (const savedItem of savedItems) { + try { const element = document.getElementById(savedItem.id); - if(element != null){ + if (element != null) { let data = { id: savedItem.id, index: savedItem.index, top: parseInt(element.style.top.slice(0, -2)), left: parseInt(element.style.left.slice(0, -2)), - drillId: id + drillId: selectedDrill.id, }; await drillElement.updateById(savedItem.id, data); } } catch (error) { toast.error('Erro ao salvar elementos'); return; - } + } } - for(const deletedSavedId of deletedSavedIds){ - try{ + for (const deletedSavedId of deletedSavedIds) { + try { await drillElement.deleteById(deletedSavedId); } catch (error) { toast.error('Erro ao salvar elementos'); return; - } + } } toast.success('Atualizações no desenho do drill salvas com sucesso'); - setNewItems([]); const trash = document.getElementById('apagar'); if (trash) trash.style.visibility = 'hidden'; } - async function loadData() { - if (id != null) { - const response = await drill.getById(id); - setDrillUpdated(response.data); - } - } - console.log("id: " + id) - useEffect(() => { - loadData(); - setTitle(drillUpdated.title); - setDescription(drillUpdated.description); - setObservations(drillUpdated.observations); - - if (id != null) { - drillElement - .getManyByDrillId(id) - .then((response) => { - setSavedItems(response.data); - }) - .catch(() => { - setSavedItems([]); - }); - } - }, [drillUpdated]); - const startEditingTitle = () => { - setTitleAux(drillUpdated.title); + setTitleAux(title); setTitleNotEdited(false); }; const startEditingDescription = () => { - setDescriptionAux(drillUpdated.description); + setDescriptionAux(description); setDescriptionNotEdited(false); }; const startEditingObservations = () => { - setObservationsAux(drillUpdated.observations); + setObservationsAux(observations); setObservationsNotEdited(false); }; @@ -221,36 +182,40 @@ const Drill = () => { else if (titleAux.length < 5) toast.warning('O título deve ter no mínimo 5 caracteres'); else { - updateImagen() + updateImagen(); let data = { - id: drillUpdated.id, + id: selectedDrill.id, title: titleAux, image: imagemBase64, - description: drillUpdated.description, - observations: drillUpdated.observations, - classPlanId: drillUpdated.classPlanId, + description: description, + observations: observations, + classPlanId: selectedDrill.classPlanId, }; - await drill.updateById(id as string, data); + await drill.updateById(selectedDrill.id, data); + setTitle(titleAux); toast.success('Título atualizado com sucesso'); } } catch (error) { toast.error('Erro ao atualizar drill'); + } finally { + setTitleAux(''); + setTitleNotEdited(true); } - return; }; const finishEditingDescription = async () => { try { - updateImagen() + updateImagen(); let data = { - id: drillUpdated.id, - title: drillUpdated.title, + id: selectedDrill.id, + title: title, description: descriptionAux, - observations: drillUpdated.observations, + observations: observations, image: imagemBase64, - classPlanId: drillUpdated.classPlanId, + classPlanId: selectedDrill.classPlanId, }; - await drill.updateById(id as string, data); + await drill.updateById(selectedDrill.id, data); + setDescription(descriptionAux); toast.success('Descrição atualizada com sucesso'); } catch (error) { toast.error('Erro ao atualizar drill'); @@ -258,22 +223,22 @@ const Drill = () => { setDescriptionAux(''); setDescriptionNotEdited(true); } - return; }; const finishEditingObservations = async () => { try { setObservationsAux(''); - updateImagen() + updateImagen(); let data = { - id: drillUpdated.id, - title: drillUpdated.title, - description: drillUpdated.description, + id: selectedDrill.id, + title: title, + description: description, observations: observationsAux, image: imagemBase64, - classPlanId: drillUpdated.classPlanId, + classPlanId: selectedDrill.classPlanId, }; - await drill.updateById(id as string, data); + await drill.updateById(selectedDrill.id, data); + setObservations(observationsAux); toast.success('Observações atualizadas com sucesso'); } catch (error) { toast.error('Erro ao atualizar drill'); @@ -281,7 +246,28 @@ const Drill = () => { setObservationsAux(''); setObservationsNotEdited(true); } - return; + }; + + const redirectToViewPlan = async () => { + try { + console.log('Aqui 1'); + const classPlan = new ClassPlanService(); + const response = await classPlan.getById(selectedDrill.classPlanId); + localStorage.setItem('selectedClassPlan', JSON.stringify(response.data)); + const drillsClassPlan = await drill.getManyByClassPlanId( + selectedDrill.classPlanId, + ); + const drillData = drillsClassPlan.data; + localStorage.setItem( + 'drillsSelectedClassPlan', + JSON.stringify(drillData), + ); + setTimeout(() => { + window.location.href = `/plano-aula/${selectedDrill.classPlanId}`; + }, 3000); + } catch (error) { + toast.error('Erro ao buscar informações do plano'); + } }; return ( @@ -297,10 +283,7 @@ const Drill = () => { /> } /> -
+
{titleNotEdited ? (
@@ -317,7 +300,6 @@ const Drill = () => {
) : (
- { />
)} -
+
-

Descrição

+

Descrição

{descriptionNotEdited ? ( {

) : (