Artikel ini adalah bagian dari latihan saya dalam membuat aplikasi dengan cara mempelajari code milik orang lain. Cara belajar seperti ini saya gambarkan di artikel berikut : Latihan Programming Dengan Cara 'Membedah' Code Buatan Orang Lain. Code yang kali ini saya bahas adalah code buatan Mohammad Iqbal yang ditulis di website FreeCodeCamp berikut: Full Stack React: How to Build Your Own Blog Using Express, Hooks, & Postgres.
Ini adalah artikel bagian kedua. Bagian pertama bisa ditemukan di sini, bagian kedua dapat ditemukan di sini.
-------------
PROFILE.JS
Bagian ini adalah dashboard user yang menampilkan data profil dan daftar post user. Data yang ditampilkan di memakai data tambahan dari authO karena lebih lengkap.
Elemen utama profile.js adalah component Profile, function RenderPost, RenderProfile dan bagian return html. Bagian return html menampilkan component RenderProfile, Dialog yang terdiri dari DialogContent dan DialogActions, DialogTitle. Lalu ada bagian daftar post. Tampilan profile sepenuhnya ditangani komponen Render Profile. Tampilan post ditangani RenderPosts. Bagian dialog ini sepertinya adalah window yang muncul ketika ada operasi penghapusan post, yaitu window dengan tombol konfirmasi atau batal.
Komponen Profile mengambil context dari Context. Dia lalu mendeklarasikan stateLocal dengan property open, post_id, array posts. Selanjutnya di komponen ini ada function useEffect. Di useEffect ini ada deklarasi variable user_id yang mengambil data uid dari database. Kemudian ada panggilan axios.get ke database yang memakai parameter user_id tadi. Data yang diambil secara spesifik adalah property posts yang kemudian dimasukkan ke stateLocal. Selanjutnya ada function handleClickOpen yang mengambil parameter pid, yaitu post_id. Function ini mengubah property stateLocal open dengan true dan post_id dengan pid tadi.
Lalu ada function handleClickClose tanpa parameter yang mengubah property stateLocal open jadi false dan mengosongkan post_id.
Lalu ada function DeletePost. Dia pertama-tama mengambil stateLocal.post_id ke dalam variable post_d. Lalu dia melakukan panggilan API, yaitu panggilan delete untuk data dengan post_id tadi. Delete pertama adalah delete comments dengan route /delete/post/comments, dilanjutkan dengan operasi delete post ke route /delete/post. Ini dilanjutkan dengan function handleClickClose yang sepertinya menutup operasi ke stateLocal. Dan dilanjutkan dengan operasi setTimeOut yang sepertinya memberi waktu bagi browser untuk kembali ke route ‘/’ setelah 700 ms.
Selanjutnya ada component RenderProfile yang mengambil parameter props. Component ini me-return elemen html yang mengambil data dari property props tersebut, yaitu nickname, profile picture, email, name, status verifikasi. Sepertinya variable props ini diambil dari auth0.
Selanjutnya ada component RenderPosts. Component ini terdiri dari component Card, yaitu CardHeader dan CardContent. RenderPosts ini mengurus satuan post. Nanti dia dipanggil pakai function map di bagian return html. Jadi di bagian CardHeader ada bagian title yang mengambil data title dan url untuk link dari property di object post. RenderPost mengambil object post sebagai parameternya. Selanjutnya dia ambil property date_created juga. Lalu ada button edit yang mengarahkan ke route /editpost/. Lalu ada Buton Delete yang ditangani oleh function handleClickOpen. Setelah CardHeader ada CardContent yang isinya adalah post.post.body dengan style hidden. Style hidden ini mungkin maksudnya awalnya tersembunyi dan baru setelah diklik.
CSS untuk profile ditulis di bagian App.css di bagian Client/src/.
SHOWUSER.JS
Component ini berfungsi menampilkan laman profile user yang dibuka oleh user lain (bukan dashboard user). Importnya mirip dengan yang sudah-sudah. Ada useState, useEffect. Tidak ada useContext. Ada Link dari react-router-dom, axios, moment. Ada Card, CardContent, CardHeader, Button dari material-ui.
Component utama di sini adalah ShowUser yang menerima parameter props. Ada deklarasi dua useState. Pertama adalah useState profile yang isinya object kosong, kedua adalah useState userPosts yang isinya array kosong.
Selanjutnya ada useEffect tanpa parameter. Di sini dia ambil variable username dari props, yaitu property author. Selanjutnya ada panggilan ke database lewat axios.get untuk mengambil data username lewat route get/otheruserprofilefromdb. Data res yang didapat lalu dimasukkan ke object state profile. Selanjutnya ada function catch error.
Lalu adada function panggilan ke database untuk ambil data posts yang didahului parameter username. Data yang didapat dimasukkan ke dalam array state userPosts. Selanjutnya window diarahkan ke atas. Function useEffect ini memiliki parameter kedua, yaitu props author. Ini mungkin maksudnya function ini dieksekusi lagi ketika props location author itu berubah.
Selanjutnya ada component RenderProfile yang fungsinya menayangkan profile. Component ini menerima parameter props. Isi component ini adalah html yang mengambil props username. Lalu ada Button untuk mengirim pesan. Button ini diurus oleh pathname atau route sendmessage dengan mengambil state props. State props ini yang nanti mestinya diolah di route sendmessage.
Selanjutnya ada compnent RenderPosts yang mengambil parameter post. Fungsinya adalah menampilkan post-post untuk user tersebut. Function ini memakai component Card dari material-ui. Card pertama adalah CardHeader yang mengambil judul berupa post.post.title dengan link ke pathname ke route /post/ di tambah post id. Mesti ditelusuri lebih lanjut apakah koneksi ini berarti memanggil langsung ke database atau tidak. Sepertinya iya. Selanjutnya di CardHeaer ada tampilan tanggal yang diurus oleh library moment. Selanjutnya ada tampilan author melalui post.post.author. Selanjutnya setelah CardHeader ada CardContent. Ini isinya hanya post.post.body yang dibalut dengan style hidden. Kemungkinan tampilan lengkap post body ini tersembunyi dan baru terbuka kalau diklik.
Selanjutnya ada bagian return yang memanggil component RenderProfile di dalam className FLexRow. Sebelumnya ada function ternary dulu yang memeriksa apa ada state profile. Kalau ada, RenderProfile ditampilkan. Kalau tidak, hasilnya akan null. Lalu ada bagian Latest Activity yang menampilkan post dari user tersebut. Tampilan post ini juga memakai ternary yang memeriksa apa state userPosts kosong atau tidak. Kalau tidak, makan ada function map yang me-iterate object di dalam state tersebut lalu mengambil post.pid-nya lalu di render dengan RenderPosts. Jika tidak ada, maka hasilnya akan null.
ADMIN APP
App buat admin dibuat tersendiri. Yang dimaksud admin di sini adalah yang punya akses khusus soal keanggotaan. Mungkin bisa mengelola post juga. App buat admin authentication-nya terpisah dari authentication biasa, tapi dia mengelola database yang sama dengan yang biasa. Admin app tidak punya pilihan signup. Admin ditambahkan secara manual. Authentication admin memakai Auth0. Jadi dari dashboard app di Auth0 menyambung ke database.
Langkah yang dilakukan di dashboard Auth0 untuk membuat admin app adalah, pertama membuat app baru. Selanjutnya membuat DB connection baru. Membuat atau menambahkan user baru. Isi detail password dan mana user tersebut. Jadi di sini diatur user-user yang punya akses ke koneksi database kita. Privilege admin yang mau diterapkan di sini adalah mengedit atau menghapus post dan comment. Selanjutnya untuk laman admin, kita memakai component untuk user biasa hanya dengan modifikasi, yaitu penghilangan button signup di addpost.js dan showpost.js. Selanjutnya di bagian editpost.js ada modifikasi di function handleSubmit() di mana admin bisa mengakses user_id dan username. Bagian addpost tidak dimodifikasi. Di bagian posts.js ditambahkan function edit dan delete di bagian RenderPosts. Selanjutnya di bagian showpost.js kita menghilangkan perbandingan user ide dengan user id comment yang dicek untuk memastikan siapa yang boleh mengedit komentar tersebut. Selanjutnya di bagian handleUpdate kita menetapkan username dan user id ke author asli komentar tersebut.
Selanjutnya ada implementasi fungsi kalender di dashboard admin. Kita membuat table baru di PSQL. Membuat route-nya di routes. Table-nya terdiri dari kolom id, title, start_time, end_time. start_time dan end_time isinya adalah penanggalan dan jam. Routes-nya terdiri dari post dan get. Route post mengirimkan operasi INSERT INTO, route get mengirimkan operasi SELECT. Selanjutnya ada operasi edit dan delete, tapi itu tidak dibahas di artikel. Untuk menampilkan kalender di laman, kita memakai library react-big-calendar.
Selanjutnya kita akan membuat sebagian elemen yang diperlukan untuk membangun fungsi calender di dashboard admin. Ini tidak termasuk ke dalam fungsi utama blog, tapi merupakan latihan yang baik.
Sekarang kita akan tambahkan route untuk calendar di routes.js. Routes aplikasi kalender dinamakan appointments, yaitu terdapat route appointment dan all appointment, ada juga route untuk delete dan edit nantinya. Untuk route post appointment, yang berfungsi untuk membuat appointment baru, kita membuat operasi INSERT INTO ke database. Data yang dimasukkan adalah title, start_time, end_time. Data tersebut sebelumnya diambil dari laman melalui variable values yang mengambil req.body.
Selanjutnya ada route get yang berfungsi menampilkan semua appointment yang sudah ditulis. Route ini sederhana, yaitu hanya mengeksekusi operasi SELECT ke database.
Untuk operasi di client, code untuk calender ada di laman profile.js yang telah dimodifikasi untuk admin. Berikut pembahasannya.
File profile.js untuk admin ini terpisah dari file blog utama. Belum diketahui bagaimana nanti kita memasang file-file ini di server.
Setelah saya pikir-pikir, karena app admin ini sudah bagian terpisah dari app blog utama, kita skip dulu sekarang. Kita lanjut untuk praktek membuat web app sendiri berdasarkan pengetahuan tadi sambil mengambil pengetahuan-pengetahuan lain di tengah jalan. Yuk!
-------------
PROFILE.JS
Bagian ini adalah dashboard user yang menampilkan data profil dan daftar post user. Data yang ditampilkan di memakai data tambahan dari authO karena lebih lengkap.
Elemen utama profile.js adalah component Profile, function RenderPost, RenderProfile dan bagian return html. Bagian return html menampilkan component RenderProfile, Dialog yang terdiri dari DialogContent dan DialogActions, DialogTitle. Lalu ada bagian daftar post. Tampilan profile sepenuhnya ditangani komponen Render Profile. Tampilan post ditangani RenderPosts. Bagian dialog ini sepertinya adalah window yang muncul ketika ada operasi penghapusan post, yaitu window dengan tombol konfirmasi atau batal.
Komponen Profile mengambil context dari Context. Dia lalu mendeklarasikan stateLocal dengan property open, post_id, array posts. Selanjutnya di komponen ini ada function useEffect. Di useEffect ini ada deklarasi variable user_id yang mengambil data uid dari database. Kemudian ada panggilan axios.get ke database yang memakai parameter user_id tadi. Data yang diambil secara spesifik adalah property posts yang kemudian dimasukkan ke stateLocal. Selanjutnya ada function handleClickOpen yang mengambil parameter pid, yaitu post_id. Function ini mengubah property stateLocal open dengan true dan post_id dengan pid tadi.
Lalu ada function handleClickClose tanpa parameter yang mengubah property stateLocal open jadi false dan mengosongkan post_id.
Lalu ada function DeletePost. Dia pertama-tama mengambil stateLocal.post_id ke dalam variable post_d. Lalu dia melakukan panggilan API, yaitu panggilan delete untuk data dengan post_id tadi. Delete pertama adalah delete comments dengan route /delete/post/comments, dilanjutkan dengan operasi delete post ke route /delete/post. Ini dilanjutkan dengan function handleClickClose yang sepertinya menutup operasi ke stateLocal. Dan dilanjutkan dengan operasi setTimeOut yang sepertinya memberi waktu bagi browser untuk kembali ke route ‘/’ setelah 700 ms.
Selanjutnya ada component RenderProfile yang mengambil parameter props. Component ini me-return elemen html yang mengambil data dari property props tersebut, yaitu nickname, profile picture, email, name, status verifikasi. Sepertinya variable props ini diambil dari auth0.
Selanjutnya ada component RenderPosts. Component ini terdiri dari component Card, yaitu CardHeader dan CardContent. RenderPosts ini mengurus satuan post. Nanti dia dipanggil pakai function map di bagian return html. Jadi di bagian CardHeader ada bagian title yang mengambil data title dan url untuk link dari property di object post. RenderPost mengambil object post sebagai parameternya. Selanjutnya dia ambil property date_created juga. Lalu ada button edit yang mengarahkan ke route /editpost/. Lalu ada Buton Delete yang ditangani oleh function handleClickOpen. Setelah CardHeader ada CardContent yang isinya adalah post.post.body dengan style hidden. Style hidden ini mungkin maksudnya awalnya tersembunyi dan baru setelah diklik.
CSS untuk profile ditulis di bagian App.css di bagian Client/src/.
SHOWUSER.JS
Component ini berfungsi menampilkan laman profile user yang dibuka oleh user lain (bukan dashboard user). Importnya mirip dengan yang sudah-sudah. Ada useState, useEffect. Tidak ada useContext. Ada Link dari react-router-dom, axios, moment. Ada Card, CardContent, CardHeader, Button dari material-ui.
Component utama di sini adalah ShowUser yang menerima parameter props. Ada deklarasi dua useState. Pertama adalah useState profile yang isinya object kosong, kedua adalah useState userPosts yang isinya array kosong.
Selanjutnya ada useEffect tanpa parameter. Di sini dia ambil variable username dari props, yaitu property author. Selanjutnya ada panggilan ke database lewat axios.get untuk mengambil data username lewat route get/otheruserprofilefromdb. Data res yang didapat lalu dimasukkan ke object state profile. Selanjutnya ada function catch error.
Lalu adada function panggilan ke database untuk ambil data posts yang didahului parameter username. Data yang didapat dimasukkan ke dalam array state userPosts. Selanjutnya window diarahkan ke atas. Function useEffect ini memiliki parameter kedua, yaitu props author. Ini mungkin maksudnya function ini dieksekusi lagi ketika props location author itu berubah.
Selanjutnya ada component RenderProfile yang fungsinya menayangkan profile. Component ini menerima parameter props. Isi component ini adalah html yang mengambil props username. Lalu ada Button untuk mengirim pesan. Button ini diurus oleh pathname atau route sendmessage dengan mengambil state props. State props ini yang nanti mestinya diolah di route sendmessage.
Selanjutnya ada compnent RenderPosts yang mengambil parameter post. Fungsinya adalah menampilkan post-post untuk user tersebut. Function ini memakai component Card dari material-ui. Card pertama adalah CardHeader yang mengambil judul berupa post.post.title dengan link ke pathname ke route /post/ di tambah post id. Mesti ditelusuri lebih lanjut apakah koneksi ini berarti memanggil langsung ke database atau tidak. Sepertinya iya. Selanjutnya di CardHeaer ada tampilan tanggal yang diurus oleh library moment. Selanjutnya ada tampilan author melalui post.post.author. Selanjutnya setelah CardHeader ada CardContent. Ini isinya hanya post.post.body yang dibalut dengan style hidden. Kemungkinan tampilan lengkap post body ini tersembunyi dan baru terbuka kalau diklik.
Selanjutnya ada bagian return yang memanggil component RenderProfile di dalam className FLexRow. Sebelumnya ada function ternary dulu yang memeriksa apa ada state profile. Kalau ada, RenderProfile ditampilkan. Kalau tidak, hasilnya akan null. Lalu ada bagian Latest Activity yang menampilkan post dari user tersebut. Tampilan post ini juga memakai ternary yang memeriksa apa state userPosts kosong atau tidak. Kalau tidak, makan ada function map yang me-iterate object di dalam state tersebut lalu mengambil post.pid-nya lalu di render dengan RenderPosts. Jika tidak ada, maka hasilnya akan null.
ADMIN APP
App buat admin dibuat tersendiri. Yang dimaksud admin di sini adalah yang punya akses khusus soal keanggotaan. Mungkin bisa mengelola post juga. App buat admin authentication-nya terpisah dari authentication biasa, tapi dia mengelola database yang sama dengan yang biasa. Admin app tidak punya pilihan signup. Admin ditambahkan secara manual. Authentication admin memakai Auth0. Jadi dari dashboard app di Auth0 menyambung ke database.
Langkah yang dilakukan di dashboard Auth0 untuk membuat admin app adalah, pertama membuat app baru. Selanjutnya membuat DB connection baru. Membuat atau menambahkan user baru. Isi detail password dan mana user tersebut. Jadi di sini diatur user-user yang punya akses ke koneksi database kita. Privilege admin yang mau diterapkan di sini adalah mengedit atau menghapus post dan comment. Selanjutnya untuk laman admin, kita memakai component untuk user biasa hanya dengan modifikasi, yaitu penghilangan button signup di addpost.js dan showpost.js. Selanjutnya di bagian editpost.js ada modifikasi di function handleSubmit() di mana admin bisa mengakses user_id dan username. Bagian addpost tidak dimodifikasi. Di bagian posts.js ditambahkan function edit dan delete di bagian RenderPosts. Selanjutnya di bagian showpost.js kita menghilangkan perbandingan user ide dengan user id comment yang dicek untuk memastikan siapa yang boleh mengedit komentar tersebut. Selanjutnya di bagian handleUpdate kita menetapkan username dan user id ke author asli komentar tersebut.
Selanjutnya ada implementasi fungsi kalender di dashboard admin. Kita membuat table baru di PSQL. Membuat route-nya di routes. Table-nya terdiri dari kolom id, title, start_time, end_time. start_time dan end_time isinya adalah penanggalan dan jam. Routes-nya terdiri dari post dan get. Route post mengirimkan operasi INSERT INTO, route get mengirimkan operasi SELECT. Selanjutnya ada operasi edit dan delete, tapi itu tidak dibahas di artikel. Untuk menampilkan kalender di laman, kita memakai library react-big-calendar.
Selanjutnya kita akan membuat sebagian elemen yang diperlukan untuk membangun fungsi calender di dashboard admin. Ini tidak termasuk ke dalam fungsi utama blog, tapi merupakan latihan yang baik.
Sekarang kita akan tambahkan route untuk calendar di routes.js. Routes aplikasi kalender dinamakan appointments, yaitu terdapat route appointment dan all appointment, ada juga route untuk delete dan edit nantinya. Untuk route post appointment, yang berfungsi untuk membuat appointment baru, kita membuat operasi INSERT INTO ke database. Data yang dimasukkan adalah title, start_time, end_time. Data tersebut sebelumnya diambil dari laman melalui variable values yang mengambil req.body.
Selanjutnya ada route get yang berfungsi menampilkan semua appointment yang sudah ditulis. Route ini sederhana, yaitu hanya mengeksekusi operasi SELECT ke database.
Untuk operasi di client, code untuk calender ada di laman profile.js yang telah dimodifikasi untuk admin. Berikut pembahasannya.
File profile.js untuk admin ini terpisah dari file blog utama. Belum diketahui bagaimana nanti kita memasang file-file ini di server.
Setelah saya pikir-pikir, karena app admin ini sudah bagian terpisah dari app blog utama, kita skip dulu sekarang. Kita lanjut untuk praktek membuat web app sendiri berdasarkan pengetahuan tadi sambil mengambil pengetahuan-pengetahuan lain di tengah jalan. Yuk!
Comments