From 5e22c7f597b61cee55c404279768d5ee048f15c4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Mar 2024 20:54:46 -0500 Subject: [PATCH 01/22] Added column selection and number of rows to display for family reports resizing, syncronized the footer's copyright year to real time, and componetised family and page donation managment information --- components/CVFooter.vue | 2 +- components/DonationManagementInformation.vue | 39 ++++ pages/EditPage/{[EditPageId].vue => [id].vue} | 16 +- pages/FamilyReports.vue | 169 ++++++++++++++---- pages/FamilyTransactionList.vue | 26 +-- pages/Page/[id].vue | 2 +- pages/Search.vue | 6 +- server/api/familiesReports.get.ts | 20 +-- server/api/pages.get.ts | 6 +- 9 files changed, 196 insertions(+), 90 deletions(-) create mode 100644 components/DonationManagementInformation.vue rename pages/EditPage/{[EditPageId].vue => [id].vue} (97%) diff --git a/components/CVFooter.vue b/components/CVFooter.vue index a08e39bd..2deb4adc 100644 --- a/components/CVFooter.vue +++ b/components/CVFooter.vue @@ -7,7 +7,7 @@ div div.absolute(style="margin-left: auto;margin-right: auto; left: 0;right: 0; text-align: center;") LinkButton.absolute.bottom-4.mx-auto.text-md(class="left-1/2" to='https://carsonsvillage.org/contact-us/') Contact Us div.bg-black.flex(style="color:gray; font-weight: 700; justify-content:center; align-items: center; height: 100px;") - label COPYRIGHT 2023 CARSON'S VILLAGE |  + label COPYRIGHT {{ (new Date()).toLocaleDateString('en', {year:'numeric'}) }} CARSON'S VILLAGE |  .col NuxtLink(to='https://carsonsvillage.org/privacy-policy/') PRIVACY POLICY |  .col diff --git a/components/DonationManagementInformation.vue b/components/DonationManagementInformation.vue new file mode 100644 index 00000000..7cee8949 --- /dev/null +++ b/components/DonationManagementInformation.vue @@ -0,0 +1,39 @@ + + + \ No newline at end of file diff --git a/pages/EditPage/[EditPageId].vue b/pages/EditPage/[id].vue similarity index 97% rename from pages/EditPage/[EditPageId].vue rename to pages/EditPage/[id].vue index 932bea76..07bb0cfe 100644 --- a/pages/EditPage/[EditPageId].vue +++ b/pages/EditPage/[id].vue @@ -123,17 +123,17 @@ const imageData = ref([]) const profile_image = ref("") const familyCuid = ref("") -const cuid_data = computed(() => router.params.EditPageId); +const cuid_data = computed(() => router.params.id); const cuid = cuid_data.value as string const user_cuid_data = computed(() => cvuser.value?.cuid) const user_cuid = user_cuid_data.value as string -const pageCuid = computed(() => router.params.EditPageId) +const pageCuid = computed(() => router.params.id) data.value.cuid = cuid; data.value.userCuid = user_cuid; console.log(data.value) const errorInPage = ref(false) -// Method that saves form data to the database for a page that has cuid: router.params.EditPageId +// Method that saves form data to the database for a page that has cuid: router.params.id const save = async () => { if(isAdvocate.value) { data.value.familyCuid = familyCuid.value @@ -141,14 +141,14 @@ const save = async () => { data.value.familyCuid = cvuser.value.familyCuid as string } - if(router.params.EditPageId === "0") { + if(router.params.id === "0") { data.value.start_date = new Date().toString() } // todo: change to $fetch const { data: saveSuccess } = await useFetch('/api/page', { // Checks if there is a pre-existing page to edit or if to create a new page - method: router.params.EditPageId !== "0" ? 'PUT' : 'POST', + method: router.params.id !== "0" ? 'PUT' : 'POST', body: ({ ...data.value }) } ) @@ -169,8 +169,8 @@ const currentFamily = computed(() => data_all_users.value?.find(({ cuid }: Famil // Method to populate the form when editing a pre-existing page const getData = async (cuid: string) => { - const pageFoundFromUser = cvuser.value.Pages.find((i: Page) => i.cuid == router.params.EditPageId) != undefined - const pageFoundFromFamily = cvuser2.value.Family?.Pages.find((i: Page) => i.cuid == router.params.EditPageId) != undefined + const pageFoundFromUser = cvuser.value.Pages.find((i: Page) => i.cuid == router.params.id) != undefined + const pageFoundFromFamily = cvuser2.value.Family?.Pages.find((i: Page) => i.cuid == router.params.id) != undefined console.log(data_all_users) // Allowing access to the user's EditPage only if user is an advocate or it is one of the family's family pages. if (pageFoundFromUser || pageFoundFromFamily || cvuser.value.user_role == "advocate" || cvuser.value.user_role == "admin") { @@ -246,7 +246,7 @@ if( isAdvocate.value ) { data_all_users.value = Families.value as unknown as Family[] } -await getData(useRoute().params.EditPageId as string) +await getData(useRoute().params.id as string) const profileImage = computed(() => data.value?.Images.find((i: Image) => i.cuid == data.value?.profileImageCuid)) diff --git a/pages/FamilyReports.vue b/pages/FamilyReports.vue index 0b7e1c98..895de1ae 100644 --- a/pages/FamilyReports.vue +++ b/pages/FamilyReports.vue @@ -4,17 +4,39 @@ //todo: add selection for families instead of all at once and toggle between all at once and all families by having the first option as displaying every page //todo: 3 column by however many needed rows (flex-wrap) of checkboxes to enable and disable columns. Future idea: put a nicer version as a sidebar div - h2(style="margin-top: 2.5rem;") Family Reports + h2.mt-4.ml-4 Family Reports br - .flex.flex-col.gap-5.px-4.mx-auto.mt-8(class="w-3/4 sm:px-16") - //img.mx-auto(v-if="profileImage?.url" class="w-[122px] h-[122px] rounded-[8px]" :src="`${profileImage?.url}`") + h2.mt-4.m1-4 Table Dimensions + .div.flex.flex-box.flex-wrap.gap-10(style="width: 450px") + CVLable() Number Of Table Rows + CVInput(v-model="dimensions") + h2.mt-4.m1-4 Fields to Show + .div.flex.flex-box.flex-wrap.gap-10(style="width: 450px") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Duration + input(type='checkbox' v-model="display.duration") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") goal met + input(type='checkbox' v-model="display.goal_met") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Goal Met date + input(type='checkbox' v-model="display.goal_met_date") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Start Date + input(type='checkbox' v-model="display.start_date") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Amount Owed + input(type='checkbox' v-model="display.owed") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Amount Paid Out + input(type='checkbox' v-model="display.paid") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Goal Date + input(type='checkbox' v-model="display.goal_date") + label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Donation Goal + input(type='checkbox' v-model="display.donation_goal") + //.flex.flex-col.gap-5.px-4.mx-auto.mt-8(class="w-3/4 sm:px-16") + img.mx-auto(v-if="profileImage?.url" class="w-[122px] h-[122px] rounded-[8px]" :src="`${profileImage?.url}`") .text-gray-dark.mx-auto.w-max.font-poppins.text-md {{ dateFormat(start_date, true) + ' - ' + dateFormat(end_date, true) }} - //.flex.flex-col-reverse.gap-5(class="sm:grid sm:grid-cols-2") + .flex.flex-col-reverse.gap-5(class="sm:grid sm:grid-cols-2") .relative.w-96.p-1(v-if="imageData.length != 0" ) button.absolute.left-4.top-64.bg-black.text-white(@click="prevImage" style="opacity:0.7; --tw-text-opacity: 1; width: 46px; height: 46px; border-radius:50%; align-items: center; justify-content: center; line-height: 2; text-align: center;color: white;") < button.absolute.right-8.top-64.bg-black.text-white(@click="nextImage" style="opacity:0.7; --tw-text-opacity: 1; width: 46px; height: 46px; border-radius:50%; align-items: center; justify-content: center; line-height: 2; text-align: center;color: white;") > img.w-96(style="object-fit:cover" :src="imageData[currentImage].url") - .py-4.grid(class="sm:grid-cols-5") + //.py-4.grid(class="sm:grid-cols-5") CVLabel Date Range .col-md-8.mx-9(class="sm:col-span-1 sm:mr-11") CVDatepicker(v-model='start_date' @update:model-value="currentPage=0; loadReports();") @@ -28,31 +50,31 @@ div tr th(style="padding: 1rem; background-color: #6eabbf; border-radius: 60px 0 0 0; width: 12%;") Page Name th(style="padding: 1rem; background-color: #6eabbf; width: 12%;") Advocate - th(style="padding: 1rem; background-color: #6eabbf; width: 12%;") Duration - th(style="padding: 1rem; background-color: #6eabbf; width: 7%;") Goal Met - th(style="padding: 1rem; background-color: #6eabbf; width: 10%;") Goal Met Date - th(style="padding: 1rem; background-color: #6eabbf; width: 12%;") Start Date - th(style="padding: 1rem; background-color: #6eabbf; width: 5%") Owed + th(style="padding: 1rem; background-color: #6eabbf; width: 12%;" v-if="display.duration") Duration + th(style="padding: 1rem; background-color: #6eabbf; width: 7%;" v-if="display.goal_met") Goal Met + th(style="padding: 1rem; background-color: #6eabbf; width: 10%;" v-if="display.goal_met_date") Goal Met Date + th(style="padding: 1rem; background-color: #6eabbf; width: 12%;" v-if="display.start_date") Start Date + th(style="padding: 1rem; background-color: #6eabbf; width: 5%" v-if="display.owed") Owed //th(style="padding: 1rem; background-color: #6eabbf; width: 5%") Owed % - th(style="padding: 1rem; background-color: #6eabbf; width: 5%") Paid - th(style="padding: 1rem; background-color: #6eabbf; width: 5%") Goal - th(style="padding: 1rem; background-color: #6eabbf; width: 7%") Goal Date + th(style="padding: 1rem; background-color: #6eabbf; width: 5%" v-if="display.paid") Paid + th(style="padding: 1rem; background-color: #6eabbf; width: 5%" v-if="display.donation_goal") Goal + th(style="padding: 1rem; background-color: #6eabbf; width: 7%" v-if="display.goal_date") Goal Date th(style="padding: 1rem; background-color: #6eabbf; width: 7%") Status th(style="padding: 1rem; background-color: #6eabbf; border-radius: 0 60px 0 0; width: 7%;") Toggle Status tbody tr(v-for="(page, i) in families" - :class="{'bg-gray-200': (i+1) % 2}") + :class="{'bg-gray-200': (i+1) % 2}" :key="listOfTagsLen") td(style="text-align: center;") {{ page.page_name }} td(style="text-align: center;") {{ page.Family.AdvocateResponsible.first_name + " " + page.Family.AdvocateResponsible?.last_name }} - td(style="text-align: center;") {{ page.duration }} - td(style="text-align: center;") {{ page.donation_status }} - td(style="text-align: center;") {{ (page.goal_met_date) ? dateFormat(page.goal_met_date, true) : "Goal Not Reached" }} - td(style="text-align: center;") {{ dateFormat(page.start_date, true) }} - td(style="text-align: center;") {{ donationFormat((page.amount_raised - page.amount_distributed)) }} + td(style="text-align: center;" v-if="display.duration") {{ page.duration }} + td(style="text-align: center;" v-if="display.goal_met") {{ page.donation_status }} + td(style="text-align: center;" v-if="display.goal_met_date") {{ (page.goal_met_date) ? dateFormat(page.goal_met_date, true) : "Goal Not Reached" }} + td(style="text-align: center;" v-if="display.start_date") {{ dateFormat(page.start_date, true) }} + td(style="text-align: center;" v-if="display.owed") {{ donationFormat((page.amount_raised - page.amount_distributed)) }} //td(style="text-align: center;") {{ (page.donation_goal) ? ((page.amount_raised - page.amount_distributed)/(page.donation_goal) * 100).toFixed(2) + "%" : "No donation goal"}} - td(style="text-align: center;") {{ donationFormat(page.amount_distributed) }} - td(style="text-align: center;") {{ donationFormat(page.donation_goal) }} - td(style="text-align: center;") {{ dateFormat(page.deadline)}} + td(style="text-align: center;" v-if="display.paid") {{ donationFormat(page.amount_distributed) }} + td(style="text-align: center;" v-if="display.donation_goal" ) {{ donationFormat(page.donation_goal) }} + td(style="text-align: center;" v-if="display.goal_date") {{ dateFormat(page.deadline)}} td(style="text-align: center;") {{ page.status }} td(style="text-align: center;") ActionButton(style="color: white; background-color: red;" @click="togglePageStatus(page)") {{ "X" }} @@ -67,7 +89,6 @@ div \ No newline at end of file diff --git a/pages/EditPage/[id].vue b/pages/EditPage/[id].vue index 07bb0cfe..8f12482c 100644 --- a/pages/EditPage/[id].vue +++ b/pages/EditPage/[id].vue @@ -121,7 +121,7 @@ const data_all_users = ref([]) const imageData = ref([]) const profile_image = ref("") - +const left = ref(true) const familyCuid = ref("") const cuid_data = computed(() => router.params.id); const cuid = cuid_data.value as string @@ -286,9 +286,12 @@ CVContainer CVLabel Profile Image .col-md-8.mx-9(class="sm:col-span-2 sm:mr-11") Listbox.rounded-md.outline-0.border-box.w-full.p-2.bg-white(style="width:350px; border: 1px solid #c4c4c4;" v-model="data.profileImageCuid" as="div") - ListboxButton(class='bg-white relative rounded-md pl-2 py-2 sm:text-sm') - img.rounded-lg(style="padding: 10px;" :src="profileImage?.url") - ListboxOptions(as='div' style="width:350px;" class='w-full absolute z-10 mt-10 bg-white shadow-lg max-h-60 rounded-md px-2 py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm' ) + ListboxButton(@click="left=!left" class='bg-white relative rounded-md pl-2 py-2 sm:text-sm') + div.flex + img.rounded-lg(class="w-50" style="padding: 10px;" :src="profileImage?.url") + p.p-2(v-if="left" style="font-size: 20px") < + p.p-2(v-else style="font-size: 20px") v + ListboxOptions(as='div' style="width:350px;" class='absolute z-10 mt-10 bg-white shadow-lg max-h-60 rounded-md px-2 py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm' ) ListboxOption(v-for="(image,k) in imageData" :key="image.cuid" :value="image.cuid") img.rounded-lg(style="padding: 10px;" :src="image.url") diff --git a/pages/FamilyTransactionList.vue b/pages/FamilyTransactionList.vue index 95269307..409c0b2b 100644 --- a/pages/FamilyTransactionList.vue +++ b/pages/FamilyTransactionList.vue @@ -110,7 +110,7 @@ const { data: Families } = await useFetch('/api/families', { ListboxButton(class='text-left bg-white relative rounded-md pl-2 pr-10 py-2 sm:text-sm w-96') {{ currentPageCuid ? currentPage.page_name : 'Select Page' }} .flex.gap-5.justify-around - DonationManagementInformation(:totalPageDonations="totalPageDonations" :totalDistributed="totalDistributed" :totalRemaining="totalRemaining" :amount_raised="currentPage?.amount_raised" :amount_distributed="currentPage?.amount_distributed") + DonationManagementInformation(:donationStatus="currentPage?.donation_status" :startDate="currentPage?.start_date" :totalPageDonations="totalPageDonations" :totalDistributed="totalDistributed" :totalRemaining="totalRemaining" :amount_raised="currentPage?.amount_raised" :amount_distributed="currentPage?.amount_distributed") div(class="basis-1/3") PayoutRecord(:currentPage="currentPage" :currentFamily="currentFamily") From 6a17ceaf9d2d7a31a5b3b6b4618d673114a3b319 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 23 Mar 2024 23:04:47 -0500 Subject: [PATCH 04/22] Added creating user and assigned advocate to page list --- pages/Page/[id].vue | 2 +- pages/PageList/[id].vue | 49 +++++++++++++++++++++++++++++----- prisma/schema.prisma | 4 +-- server/api/family_pages.get.ts | 6 +++++ server/api/page_list.get.ts | 7 ++++- server/api/pages.get.ts | 12 +++++++-- 6 files changed, 68 insertions(+), 12 deletions(-) diff --git a/pages/Page/[id].vue b/pages/Page/[id].vue index ed8400d8..cf4e7c61 100644 --- a/pages/Page/[id].vue +++ b/pages/Page/[id].vue @@ -10,7 +10,7 @@ */ import type { Page, PageDonation, Image, Reply, Family} from '@/types.d.ts' -import { dateFormat, donationFormat } from '@/utils' +import { dateFormat, donationFormat } from '@/utils' import CVReplySystem from '@/components/CVReplySystem.vue' const pageData = ref({ diff --git a/pages/PageList/[id].vue b/pages/PageList/[id].vue index 0f334c03..79974b7c 100644 --- a/pages/PageList/[id].vue +++ b/pages/PageList/[id].vue @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/components/StandardTable.vue b/components/StandardTable.vue index 6a04110e..96ddf77b 100644 --- a/components/StandardTable.vue +++ b/components/StandardTable.vue @@ -43,7 +43,7 @@ const headers = [ }, { name: "current date", - property: new Date().toString(), + property: new Date().toISOString(), kind: "date" } ] diff --git a/pages/EditPage/[id].vue b/pages/EditPage/[id].vue index 8f12482c..d50fb05a 100644 --- a/pages/EditPage/[id].vue +++ b/pages/EditPage/[id].vue @@ -142,7 +142,7 @@ const save = async () => { } if(router.params.id === "0") { - data.value.start_date = new Date().toString() + data.value.start_date = new Date().toISOString() } // todo: change to $fetch diff --git a/pages/FamilyReports.vue b/pages/FamilyReports.vue index f1b29b0b..1a75772d 100644 --- a/pages/FamilyReports.vue +++ b/pages/FamilyReports.vue @@ -268,6 +268,14 @@ div console.log(families.value) // gathering the family data into an array of family pages and their advocate responsible familiesRaw.value = familiesData.value?.all_families as unknown as Family[] +/* + { + ...page, + page_last_name: page.last_name, + ...advocateResponsible + } +*/ + familiesRaw.value.forEach((element: Family) => { element.Pages.forEach((element2) => {familyPages.value.push( { ...element2 as unknown as Page[], ...element.AdvocateResponsible as any }) })}) const familyPagesArr = [...familyPages.value] const csv = convertToCSV(familyPagesArr, listOfTags.value) @@ -289,7 +297,7 @@ div // method activated by Advocate or Admin to manual remove the ability to donate to a family page after about a week of the donation deadline. // an advocate or admin can also re-enable a page to set its status from 'inactive' to 'active' - const togglePageStatus = (page: Page) => { + const togglePageStatus = async(page: Page) => { if(isAdminAdvocate.value) { let booleanChanged = false if(page.status == "active") { @@ -311,7 +319,7 @@ div } booleanChanged = false // todo: change to $fetch - const toggledStatus = useFetch('api/page', { + const toggledStatus = await useFetch('api/page', { method: "PUT", body: { ...page } }) diff --git a/pages/FamilyTransactionList.vue b/pages/FamilyTransactionList.vue index 409c0b2b..b556ef3d 100644 --- a/pages/FamilyTransactionList.vue +++ b/pages/FamilyTransactionList.vue @@ -17,7 +17,7 @@ import { ListboxOption, } from '@headlessui/vue' import type { User, Page, PageDonation, donation_payout, Family } from "@/types.d.ts" -import { donationFormat } from "@/utils" +import { donationFormat, dateFormat } from "@/utils" //import { Family } from "@prisma/client" const currentFamilyPageNumber = ref(0) //const familyPagesLength = ref(0) @@ -50,8 +50,33 @@ const { data: Families } = await useFetch('/api/families', { const familyPagesLength = computed(() => familyData.value.Pagination.total) const currentPageCuid = ref(""); const currentPage = computed(() => familyData.value?.raw_data.find(({ cuid }: Page) => cuid == currentPageCuid.value) || {}); - watchEffect(() => currentPageCuid.value = familyData.value.raw_data![0]?.cuid || ""); + watchEffect(() => currentPageCuid.value = familyData.value.raw_data![0]?.cuid || ""); + /* const { data: lastDonationDate } = await useFetch('/api/find_last_donation', { + method: 'GET', + query: { page_cuid: currentPageCuid}, + watch: [currentPageCuid, currentFamilyPageNumber], + default() { + ""; + }, + }); + + const find_last_donation = async(cuid: string) => { + const { data: lastDonationDate2 } = await useFetch('/api/find_last_donation', { + method: 'GET', + query: { page_cuid: cuid }, + default() { + ""; + }, + }); + + return lastDonationDate2.value._max.donationDate || "" +}*/ + + /*watch(familyData, async() => { + familyData.value.data.map(async(page: (Page & { last_donation: string | undefined} )) => { page.last_donation = await find_last_donation(page.cuid) || "" }) + })*/ + const { data: donations } = await useFetch('/api/family_donation', { method: 'GET', query: { family_cuid: currentFamilyCuid }, @@ -79,7 +104,7 @@ const { data: Families } = await useFetch('/api/families', { From 30327a269d836ca4808e0c45fa6fabb105cc8b6c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Apr 2024 20:01:59 -0500 Subject: [PATCH 08/22] Reverting edit page EditPageId to Id change for merging --- pages/EditPage/{[id].vue => [EditPageId].vue} | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) rename pages/EditPage/{[id].vue => [EditPageId].vue} (97%) diff --git a/pages/EditPage/[id].vue b/pages/EditPage/[EditPageId].vue similarity index 97% rename from pages/EditPage/[id].vue rename to pages/EditPage/[EditPageId].vue index e1cbcb37..9dfb5726 100644 --- a/pages/EditPage/[id].vue +++ b/pages/EditPage/[EditPageId].vue @@ -123,17 +123,17 @@ const imageData = ref([]) const profile_image = ref("") const left = ref(true) const familyCuid = ref("") -const cuid_data = computed(() => router.params.id); +const cuid_data = computed(() => router.parmams.EditPageId); const cuid = cuid_data.value as string const user_cuid_data = computed(() => cvuser.value?.cuid) const user_cuid = user_cuid_data.value as string -const pageCuid = computed(() => router.params.id) +const pageCuid = computed(() => router.parmams.EditPageId) data.value.cuid = cuid; data.value.userCuid = user_cuid; console.log(data.value) const errorInPage = ref(false) -// Method that saves form data to the database for a page that has cuid: router.params.id +// Method that saves form data to the database for a page that has cuid: router.parmams.EditPageId const save = async () => { if(isAdvocate.value) { data.value.familyCuid = familyCuid.value @@ -141,14 +141,14 @@ const save = async () => { data.value.familyCuid = cvuser.value.familyCuid as string } - if(router.params.id === "0") { + if(router.parmams.EditPageId === "0") { data.value.start_date = new Date().toISOString() } // todo: change to $fetch const { data: saveSuccess } = await useFetch('/api/page', { // Checks if there is a pre-existing page to edit or if to create a new page - method: router.params.id !== "0" ? 'PUT' : 'POST', + method: router.parmams.EditPageId !== "0" ? 'PUT' : 'POST', body: ({ ...data.value }) } ) @@ -169,8 +169,8 @@ const currentFamily = computed(() => data_all_users.value?.find(({ cuid }: Famil // Method to populate the form when editing a pre-existing page const getData = async (cuid: string) => { - const pageFoundFromUser = cvuser.value.Pages.find((i: Page) => i.cuid == router.params.id) != undefined - const pageFoundFromFamily = cvuser2.value.Family?.Pages.find((i: Page) => i.cuid == router.params.id) != undefined + const pageFoundFromUser = cvuser.value.Pages.find((i: Page) => i.cuid == router.parmams.EditPageId) != undefined + const pageFoundFromFamily = cvuser2.value.Family?.Pages.find((i: Page) => i.cuid == router.parmams.EditPageId) != undefined console.log(data_all_users) // Allowing access to the user's EditPage only if user is an advocate or it is one of the family's family pages. if (pageFoundFromUser || pageFoundFromFamily || cvuser.value.user_role == "advocate" || cvuser.value.user_role == "admin") { @@ -246,7 +246,7 @@ if( isAdvocate.value ) { data_all_users.value = Families.value as unknown as Family[] } -await getData(useRoute().params.id as string) +await getData(useRoute().parmams.EditPageId as string) const profileImage = computed(() => data.value?.Images.find((i: Image) => i.cuid == data.value?.profileImageCuid)) From 394fa5f99da40566fff69144318cbba89494011f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Apr 2024 20:06:53 -0500 Subject: [PATCH 09/22] fixed router params mispell --- pages/EditPage/[EditPageId].vue | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pages/EditPage/[EditPageId].vue b/pages/EditPage/[EditPageId].vue index 9dfb5726..3d1826d6 100644 --- a/pages/EditPage/[EditPageId].vue +++ b/pages/EditPage/[EditPageId].vue @@ -123,17 +123,17 @@ const imageData = ref([]) const profile_image = ref("") const left = ref(true) const familyCuid = ref("") -const cuid_data = computed(() => router.parmams.EditPageId); +const cuid_data = computed(() => router.params.EditPageId); const cuid = cuid_data.value as string const user_cuid_data = computed(() => cvuser.value?.cuid) const user_cuid = user_cuid_data.value as string -const pageCuid = computed(() => router.parmams.EditPageId) +const pageCuid = computed(() => router.params.EditPageId) data.value.cuid = cuid; data.value.userCuid = user_cuid; console.log(data.value) const errorInPage = ref(false) -// Method that saves form data to the database for a page that has cuid: router.parmams.EditPageId +// Method that saves form data to the database for a page that has cuid: router.params.EditPageId const save = async () => { if(isAdvocate.value) { data.value.familyCuid = familyCuid.value @@ -141,14 +141,14 @@ const save = async () => { data.value.familyCuid = cvuser.value.familyCuid as string } - if(router.parmams.EditPageId === "0") { + if(router.params.EditPageId === "0") { data.value.start_date = new Date().toISOString() } // todo: change to $fetch const { data: saveSuccess } = await useFetch('/api/page', { // Checks if there is a pre-existing page to edit or if to create a new page - method: router.parmams.EditPageId !== "0" ? 'PUT' : 'POST', + method: router.params.EditPageId !== "0" ? 'PUT' : 'POST', body: ({ ...data.value }) } ) @@ -169,8 +169,8 @@ const currentFamily = computed(() => data_all_users.value?.find(({ cuid }: Famil // Method to populate the form when editing a pre-existing page const getData = async (cuid: string) => { - const pageFoundFromUser = cvuser.value.Pages.find((i: Page) => i.cuid == router.parmams.EditPageId) != undefined - const pageFoundFromFamily = cvuser2.value.Family?.Pages.find((i: Page) => i.cuid == router.parmams.EditPageId) != undefined + const pageFoundFromUser = cvuser.value.Pages.find((i: Page) => i.cuid == router.params.EditPageId) != undefined + const pageFoundFromFamily = cvuser2.value.Family?.Pages.find((i: Page) => i.cuid == router.params.EditPageId) != undefined console.log(data_all_users) // Allowing access to the user's EditPage only if user is an advocate or it is one of the family's family pages. if (pageFoundFromUser || pageFoundFromFamily || cvuser.value.user_role == "advocate" || cvuser.value.user_role == "admin") { @@ -246,7 +246,7 @@ if( isAdvocate.value ) { data_all_users.value = Families.value as unknown as Family[] } -await getData(useRoute().parmams.EditPageId as string) +await getData(useRoute().params.EditPageId as string) const profileImage = computed(() => data.value?.Images.find((i: Image) => i.cuid == data.value?.profileImageCuid)) From bc212ca75c8ee2bddf8348898c935e0066b2d35e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Apr 2024 15:41:26 -0500 Subject: [PATCH 10/22] changed dates to be DateTime in Prisma, deactivated pages that are created before Stripe onboarding, prefiled Stripe Connect information, and enabled user editing. --- components/CVDatepicker.vue | 9 ++- components/DonationEntry.vue | 2 +- components/DonationManagementInformation.vue | 4 +- pages/EditFamily.vue | 4 +- pages/EditPage/[EditPageId].vue | 60 +++++++++------ pages/EditUser/[id].vue | 34 ++++++--- pages/FamilyReports.vue | 25 ++++--- pages/FamilyTransactionList.vue | 29 +------- pages/Page/[id].vue | 18 +++-- pages/PageList/[id].vue | 35 +++++---- pages/Users.vue | 10 ++- .../20240411211448_date_time/migration.sql | 44 +++++++++++ .../migration.sql | 7 ++ prisma/schema.prisma | 21 +++--- server/api/family.post.ts | 6 +- server/api/page.post.ts | 5 ++ server/api/user.put.ts | 33 ++++++++- server/middleware/auth.ts | 73 +++++++++++++++---- types.d.ts | 25 ++++--- utils.ts | 6 +- 20 files changed, 300 insertions(+), 150 deletions(-) create mode 100644 prisma/migrations/20240411211448_date_time/migration.sql create mode 100644 prisma/migrations/20240411214228_date_time_nullables/migration.sql diff --git a/components/CVDatepicker.vue b/components/CVDatepicker.vue index 83de7373..278a0123 100644 --- a/components/CVDatepicker.vue +++ b/components/CVDatepicker.vue @@ -1,5 +1,5 @@ @@ -7,14 +7,17 @@ Datepicker.rounded-md.p-2(type="String" v-model="value") import Datepicker from '@vuepic/vue-datepicker'; import '@vuepic/vue-datepicker/dist/main.css'; -const props = defineProps<{modelValue: string }>(); +const props = defineProps<{modelValue: Date | string | null}>(); const emit = defineEmits(["update:modelValue"]) const value = computed({ get(){ + /*if(props.modelValue == "null") { + return null + }*/ return props.modelValue }, - set(v: string){ + set(v: Date | string | null) { emit("update:modelValue", v) }, }) diff --git a/components/DonationEntry.vue b/components/DonationEntry.vue index 73e0d86d..da0b393f 100644 --- a/components/DonationEntry.vue +++ b/components/DonationEntry.vue @@ -33,7 +33,7 @@ const donationData = ref({ donorFirstName: "", donorLastName: "", comments: "", - donationDate: "", + donationDate: null, Page: ref([]).value[0], userCuid: '', isAnonymous: false diff --git a/components/DonationManagementInformation.vue b/components/DonationManagementInformation.vue index 51d222ca..61613386 100644 --- a/components/DonationManagementInformation.vue +++ b/components/DonationManagementInformation.vue @@ -47,8 +47,8 @@ const props = defineProps<{ amount_raised: number, amount_distributed: number, donationStatus: string, - startDate: string, - lastDonationDate: string + startDate: Date | string | null, + lastDonationDate: Date | string | null }>() \ No newline at end of file diff --git a/pages/EditFamily.vue b/pages/EditFamily.vue index 0310209c..db691da4 100644 --- a/pages/EditFamily.vue +++ b/pages/EditFamily.vue @@ -24,8 +24,8 @@ const cvuser2 = useCookie('cvuser') const data_family = ref({ cuid: "", stripe_account_id: "", - created_at: Date.toString(), - updated_at: "", + created_at: new Date(), + updated_at: null, family_name: "", advocateCuid: cvuser2.value.cuid }) diff --git a/pages/EditPage/[EditPageId].vue b/pages/EditPage/[EditPageId].vue index 3d1826d6..3149a4e9 100644 --- a/pages/EditPage/[EditPageId].vue +++ b/pages/EditPage/[EditPageId].vue @@ -33,17 +33,18 @@ const cvuser2 = useCookie('cvuser') const data = ref({ cuid: "", userCuid: "", - page_name: "", - day_of_birth: "", - day_of_passing:"", - visitation_date: "", + page_first_name: "", + page_last_name: "", + day_of_birth: null, + day_of_passing: null, + visitation_date: null, visitation_location: "", visitation_description: "", - funeral_date: "", + funeral_date: null, funeral_description: "", funeral_location: "", obituary: "", - deadline: "", + deadline: null, donation_goal: 0, amount_raised: 0, amount_distributed: 0, @@ -53,16 +54,17 @@ const data = ref({ status: "active", donation_status: "in progress", duration: "0 days", - start_date: "", - goal_met_date: "", + start_date: null, + goal_met_date: null , + last_donation_date: null, PageDonations: [], Reply: [], Family: { cuid: "", family_name: "", stripe_account_id: "", - created_at: "", - updated_at: "", + created_at: null, + updated_at: null, FamilyMembers: [], FamilyDonationPayouts: [], Pages: [], @@ -110,8 +112,8 @@ type User2 = { const data_family = ref({ cuid: "", stripe_account_id: "", - created_at: "", - updated_at: Date.toString(), + created_at: null, + updated_at: new Date(), family_name: "", advocateCuid: cvuser2.value.cuid }) @@ -142,21 +144,21 @@ const save = async () => { } if(router.params.EditPageId === "0") { - data.value.start_date = new Date().toISOString() + data.value.start_date = new Date() } // todo: change to $fetch - const { data: saveSuccess } = await useFetch('/api/page', { + const saveSuccess = await $fetch('/api/page', { // Checks if there is a pre-existing page to edit or if to create a new page method: router.params.EditPageId !== "0" ? 'PUT' : 'POST', body: ({ ...data.value }) } ) try { - if (saveSuccess.value == true && isAdvocate.value) { + if (saveSuccess && isAdvocate.value) { errorInPage.value = false; await navigateTo('/PageList/' + data.value.userCuid + '?fromUsers=1') - } else if(saveSuccess.value == true && !isAdvocate.value){ + } else if(saveSuccess && !isAdvocate.value){ await navigateTo('/PageList/' + data.value.familyCuid + '?fromUsers=0') } else { errorInPage.value = true; @@ -259,13 +261,20 @@ CVContainer br .bar.mx-9(style="border-top: 0.5px solid #646464;") br - .div - .information.rounded-md.mx-9.my-2.text-center(class="sm:text-start text-white bg-blue-999") + div + .information.rounded-md.my-2.text-center(class="sm:text-start text-white bg-blue-999") CVLegend Personal Information .py-4.grid(class="sm:grid-cols-3") - CVLabel Page Name + .flex + CVLabel First Name + CVHelpButton(class="inline-block" + description="The first and last name of the recently deceased person this page should be dedicated to should be entered here") + .col-md-8.mx-9(class="sm:col-span-2 sm:mr-11") + CVInput(v-model='data.page_first_name' placeholder="required" required) + .py-4.grid(class="sm:grid-cols-3") + CVLabel Last Name .col-md-8.mx-9(class="sm:col-span-2 sm:mr-11") - CVInput(v-model='data.page_name' placeholder="required" required) + CVInput(v-model='data.page_last_name' placeholder="required" required) .py-4.grid(class="sm:grid-cols-3" v-if="isAdvocate") CVLabel Family .col-md-8.mx-9(class="sm:col-span-2 sm:mr-11") @@ -282,8 +291,11 @@ CVContainer ImagePreview(v-model:images="imageData" :images="data.Images" :profileImage="profileImage" :pageCuid="cuid_data" @profileImage="setProfileImage" @images="setImagesPreview") .information.rounded-md.mx-9.my-2.text-center(class="sm:text-start text-white bg-blue-999") legend.ml-2(class="sm:py-1" style="font-weight: 700; text-shadow: 3px 3px 4px rgba(0, 0, 0, 0.25);") Profile Image Selection - .py-4.grid(class="sm:grid-cols-3") - CVLabel Profile Image + .py-4.flex.gap-72 + .flex + CVLabel Profile Image + CVHelpButton(class="inline-block" +description="Here, you select from photos you uploaded to show up first on the Family Page") .col-md-8.mx-9(class="sm:col-span-2 sm:mr-11") Listbox.rounded-md.outline-0.border-box.w-full.p-2.bg-white(style="width:350px; border: 1px solid #c4c4c4;" v-model="data.profileImageCuid" as="div") ListboxButton(@click="left=!left" class='bg-white relative rounded-md pl-2 py-2 sm:text-sm') @@ -339,7 +351,9 @@ CVContainer .information.rounded-md.mx-9.my-2.text-center(class="sm:text-start text-white bg-blue-999") CVLegend Fundraising Information .py-4.grid(class="sm:grid-cols-3") - CVLabel Goal + .flex + CVLabel Goal + CVHelpButton(class="inline-block" description="If the Donation Goal is 0, it is assumed that there are no donations required") .col-md-8.flex.mx-9(class="sm:col-span-2 sm:mr-11") span.rounded-l-md.bg-gray-200.text-lg.p-2(style="text-shadow: 3px 3px 4px rgba(0, 0, 0, 0.25); border: 1px solid #c4c4c4;") $ input.outline-0.rounded-r-md.border-box.w-full.p-2(style="border: 1px solid #c4c4c4;" v-model='data.donation_goal' placeholder="required" required) diff --git a/pages/EditUser/[id].vue b/pages/EditUser/[id].vue index c811b890..5075fe66 100644 --- a/pages/EditUser/[id].vue +++ b/pages/EditUser/[id].vue @@ -9,8 +9,8 @@ * Located under "/EditUser/" */ -import type { User } from '@/types.d.ts' -import { Family } from '@prisma/client'; +import type { User, Family } from '@/types.d.ts' +//import { Family } from '@prisma/client'; import { Listbox, ListboxButton, @@ -35,12 +35,28 @@ const data_user = ref({ const familyCuid = ref("") const data_family = ref({ - cuid: "", - stripe_account_id: "", - created_at: "", - updated_at: Date.toString(), - family_name: "", - advocateCuid: cvuser.value.cuid +cuid: "", +stripe_account_id: "", +created_at: "null", +updated_at: new Date(), +family_name: "", +advocateCuid: cvuser.value.cuid, +Pages: [], +FamilyMembers: [], +AdvocateResponsible: { +cuid: '', +first_name: '', +last_name: '', +user_role: '', +email: '', +middle_name: '', +phone: '', +Pages: [], +familyCuid: '', +AdvocateFamily: [] +}, +FamilyDonations: [], +FamilyDonationPayouts: [] }) const data_all_families = ref([]) @@ -52,7 +68,6 @@ const errorInPage = ref(false); // Method that creates a new user on the database on the backend const save = async () => { - if(isAuthorized){ const data = await $fetch('/api/user', { method: (cuid.value as string) !== "0" ? 'PUT' : 'POST', @@ -78,6 +93,7 @@ const getData = async (cuid: string) => { query: { cuid: cuid } }) data_user.value = userData.value as unknown as User; + familyCuid.value = data_user.value.familyCuid as unknown as string } // boolean indicating that we need the family selection listbox diff --git a/pages/FamilyReports.vue b/pages/FamilyReports.vue index 53308627..c1ca5274 100644 --- a/pages/FamilyReports.vue +++ b/pages/FamilyReports.vue @@ -29,9 +29,9 @@ div label.mt-4.ml-4.text-md(class="sm:mt-0" style="letter-spacing: 0.35px;") Donation Goal input(type='checkbox' v-model="display.donation_goal") .flex.flex-col.gap-5.px-4.mx-auto.mt-8(class="w-3/4 sm:px-16") - img.mx-auto(v-if="profileImage?.url" class="w-[122px] h-[122px] rounded-[8px]" :src="`${profileImage?.url}`") + //img.mx-auto(v-if="profileImage?.url" class="w-[122px] h-[122px] rounded-[8px]" :src="`${profileImage?.url}`") .text-gray-dark.mx-auto.w-max.font-poppins.text-md {{ dateFormat(start_date, true) + ' - ' + dateFormat(end_date, true) }} - .flex.flex-col-reverse.gap-5(class="sm:grid sm:grid-cols-2") + //.flex.flex-col-reverse.gap-5(class="sm:grid sm:grid-cols-2") .relative.w-96.p-1(v-if="imageData.length != 0" ) button.absolute.left-4.top-64.bg-black.text-white(@click="prevImage" style="opacity:0.7; --tw-text-opacity: 1; width: 46px; height: 46px; border-radius:50%; align-items: center; justify-content: center; line-height: 2; text-align: center;color: white;") < button.absolute.right-8.top-64.bg-black.text-white(@click="nextImage" style="opacity:0.7; --tw-text-opacity: 1; width: 46px; height: 46px; border-radius:50%; align-items: center; justify-content: center; line-height: 2; text-align: center;color: white;") > @@ -47,8 +47,9 @@ div .col-md-8.mx-9(class="sm:col-span-2 sm:mr-11") CVDatepicker(v-model='end_date' @update:modelValue="currentPage=0; loadReports()" ) .col-md-8.mx-9(class="sm:col-span-1 sm:mr-11") - a.mr-9.mt-1.p-6.px-6.pr-6.pt-3.pb-3.bg-orange-999(class="transition duration-300 bg-orange-999 hover:bg-green-600" style="border-radius: 100px; height: 50px; color: white; font-weight: 700;" :href="filedownloadlink" :download="downloadName" :dataset.downloadurl="dataset") Download + .flex.gap-2.justify-center.cols-2.pl-6.pr-6 + a.mr-9.mt-1.p-6.px-6.pr-6.pt-3.pb-3.bg-orange-999(class="transition duration-300 bg-orange-999 hover:bg-green-600" style="border-radius: 100px; height: 50px; color: white; font-weight: 700;" :href="filedownloadlink" :download="downloadName" :dataset.downloadurl="dataset") Download table(style="margin-top: 1.25rem; width: 100%; border-spacing: 0; border-collapse: collapse;" v-if="isAdminAdvocate") thead(style="color: white;") tr @@ -68,8 +69,8 @@ div tbody tr(v-for="(page, i) in families" :class="{'bg-gray-200': (i+1) % 2}" :key="listOfTagsLen") - td(style="text-align: center;") {{ page.page_name }} - td(style="text-align: center;") {{ page.Family.AdvocateResponsible.first_name + " " + page.Family.AdvocateResponsible?.last_name }} + td(style="text-align: center;") {{ page.page_first_name + " " + page.page_last_name }} + td(style="text-align: center;") {{ page.Family.AdvocateResponsible?.first_name + " " + page.Family.AdvocateResponsible?.last_name }} td(style="text-align: center;" v-if="display.duration") {{ page.duration }} td(style="text-align: center;" v-if="display.goal_met") {{ page.donation_status }} td(style="text-align: center;" v-if="display.goal_met_date") {{ (page.goal_met_date) ? dateFormat(page.goal_met_date, true) : "Goal Not Reached" }} @@ -112,11 +113,11 @@ div const dataset = ref("") const downloadName = ref("") const totalLength = ref(0) - const start_date = ref("1/01/2015") - const end_date = ref(new Date().toLocaleDateString()) - const listOfTags = ref(["page_name", "donation_goal", "amount_raised", "deadline", "amount_distributed", "donation_status", "duration", "start_date", "goal_met_date", "first_name", "middle_name", "last_name", "owed"]) + const start_date = ref(new Date("1/01/2015")) + const end_date = ref(new Date()) + const listOfTags = ref(["donation_goal", "amount_raised", "deadline", "amount_distributed", "donation_status", "duration", "start_date", "goal_met_date", "page_first_name", "page_last_name", "first_name", "middle_name", "last_name", "owed"]) // computed variable used as a key for each element of the table so that the striping of the table re-renders when the table is resized. - const listOfTagsLen = computed(() => listOfTags.value.length) + const listOfTagsLen = computed(() => listOfTags.value?.length) // number of family pages in the family reports table per page with @default=12 pages const dimensions = ref(12) type DisplayReport = { @@ -146,7 +147,7 @@ div watch(display, async() => { //const listOfTags1 = ["page_name", "donation_goal", "amount_raised", "deadline", "amount_distributed", "donation_status", "duration", "start_date", "goal_met_date", "first_name", "middle_name", "last_name", "Amount Owed / Goal Percentage" ] //, "first_name", "middle_name", "last_name" ] - listOfTags.value = ["page_name"] + listOfTags.value = [] if(display.value.donation_goal) { listOfTags.value.push("donation_goal") } @@ -169,6 +170,8 @@ div if(display.value.goal_met_date) { listOfTags.value.push("goal_met_date") } + listOfTags.value.push("page_first_name") + listOfTags.value.push("page_last_name") listOfTags.value.push("first_name") listOfTags.value.push("middle_name") listOfTags.value.push("last_name") @@ -334,7 +337,7 @@ div } booleanChanged = false - const toggledStatus = $fetch('api/page', { + const toggledStatus = await $fetch('api/page', { method: "PUT", body: { ...page } }) diff --git a/pages/FamilyTransactionList.vue b/pages/FamilyTransactionList.vue index d77cc272..f16ae431 100644 --- a/pages/FamilyTransactionList.vue +++ b/pages/FamilyTransactionList.vue @@ -51,31 +51,6 @@ const { data: Families } = await useFetch('/api/families', { const currentPageCuid = ref(""); const currentPage = computed(() => familyData.value?.raw_data.find(({ cuid }: Page) => cuid == currentPageCuid.value) || {}); watchEffect(() => currentPageCuid.value = familyData.value.raw_data![0]?.cuid || ""); - - /* const { data: lastDonationDate } = await useFetch('/api/find_last_donation', { - method: 'GET', - query: { page_cuid: currentPageCuid}, - watch: [currentPageCuid, currentFamilyPageNumber], - default() { - ""; - }, - }); - - const find_last_donation = async(cuid: string) => { - const { data: lastDonationDate2 } = await useFetch('/api/find_last_donation', { - method: 'GET', - query: { page_cuid: cuid }, - default() { - ""; - }, - }); - - return lastDonationDate2.value._max.donationDate || "" -}*/ - - /*watch(familyData, async() => { - familyData.value.data.map(async(page: (Page & { last_donation: string | undefined} )) => { page.last_donation = await find_last_donation(page.cuid) || "" }) - })*/ const { data: donations } = await useFetch('/api/family_donation', { method: 'GET', @@ -158,7 +133,7 @@ const { data: Families } = await useFetch('/api/families', { td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ item.last_donation_date ? dateFormat(item?.last_donation_date) : "No Donations" }} td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ item?.donation_status}} td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ donationFormat(item.amount_raised) }} - td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ donationFormat(item.amount_raised-item.amount_distributed) }} + td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ donationFormat(item.amount_raised - item.amount_distributed) }} .mb-9.py-7.flex.flex-wrap.gap-2.place-content-center .col-md-10.px-2.mt-2 button(@click="prevPage") < @@ -178,7 +153,7 @@ const { data: Families } = await useFetch('/api/families', { :class="{'bg-gray-200': (i+1) % 2}" ) td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ item.transaction_id }} - td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ item.cuid }} + //td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ item.cuid }} td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ item.Page.page_first_name + " " + item.Page.page_last_name }} td.font-poppins.text-gray-dark.font-bold(style="text-align: center") {{ donationFormat(item.amount) }} diff --git a/pages/Page/[id].vue b/pages/Page/[id].vue index 4c574a03..8c53e2d2 100644 --- a/pages/Page/[id].vue +++ b/pages/Page/[id].vue @@ -17,10 +17,11 @@ const pageData = ref({ cuid: "", userCuid: "", familyCuid: "", - page_name: "", - day_of_birth: "", - day_of_passing: "", - visitation_date: "", + page_first_name: "", + page_last_name: "", + day_of_birth: null, + day_of_passing: null, + visitation_date: null, visitation_location: "", visitation_description: "", funeral_date: "", @@ -36,16 +37,17 @@ const pageData = ref({ status: "active", donation_status: "in progress", duration: "", - start_date: "", - goal_met_date: "", + start_date: null, + goal_met_date: null, + last_donation_date: null, PageDonations: [], Reply: [], Family: { cuid: "", family_name: "", stripe_account_id: "", - created_at: "", - updated_at: "", + created_at: null, + updated_at: null, FamilyMembers: [], FamilyDonationPayouts: [], Pages: [], diff --git a/pages/PageList/[id].vue b/pages/PageList/[id].vue index 1c1f167c..297c1ec8 100644 --- a/pages/PageList/[id].vue +++ b/pages/PageList/[id].vue @@ -26,12 +26,12 @@ export type Page2 = { cuid: string, userCuid: string, familyCuid: string, - day_of_birth: Date | string, - day_of_passing: Date | string, - visitation_date: Date | string, + day_of_birth: Date | string | null, + day_of_passing: Date | string | null, + visitation_date: Date | string | null, visitation_location: string, visitation_description: string, - funeral_date: Date | string, + funeral_date: Date | string | null, funeral_description: string, funeral_location: string, obituary: string, @@ -45,11 +45,12 @@ export type Page2 = { status: string, donation_status: string, duration: string, - start_date: string - goal_met_date: string + start_date: Date | string | null, + goal_met_date: Date | string | null, PageDonations: PageDonation[] Reply: Reply[] - User: User + User: User, + last_donation_date: Date | string | null } const family_cuid = ref("") @@ -77,8 +78,6 @@ const data = ref({ phone: "", Pages: [], familyCuid: "" - //PageDonations: [], - //DonationPayouts: [] }) const isFamily = ref(false) @@ -198,7 +197,7 @@ await getDataPageList() diff --git a/pages/FamilyReports.vue b/pages/FamilyReports.vue index c1ca5274..c91971dc 100644 --- a/pages/FamilyReports.vue +++ b/pages/FamilyReports.vue @@ -1,14 +1,12 @@ diff --git a/pages/EditPage/[EditPageId].vue b/pages/EditPage/[EditPageId].vue index 3149a4e9..63359cb2 100644 --- a/pages/EditPage/[EditPageId].vue +++ b/pages/EditPage/[EditPageId].vue @@ -363,11 +363,11 @@ description="Here, you select from photos you uploaded to show up first on the F CVDatepicker(v-model='data.deadline') .ml-9.mb-9.py-7.flex.flex-wrap.gap-2 .col-md-10.px-2.mt-2 - ActionButton(@click="save") Save + ActionButton(class="sm:my-2 transition duration-300 bg-orange-999 hover:bg-green-600" @click="save") Save .col-md-10.py-2.mt-2 - LinkButton(v-if="pageCuid!=0" :to="`/Page/${cuid}`") View Page + LinkButton(class="sm:my-2 transition duration-300 bg-orange-999 hover:bg-green-600" v-if="pageCuid!=0" :to="`/Page/${cuid}`") View Page .col-md-10.p-2.pt-6.mt-2(class="sm:pt-2 sm:ml-auto sm:mr-6") - LinkButton(v-if="pageCuid!=0" to='#') Delete Page + LinkButton(class="sm:my-2 transition duration-300 bg-orange-999 hover:bg-green-600" v-if="pageCuid!=0" to='#') Delete Page .py-4.grid(class="sm:grid-cols-3" Style="color:red" v-if="errorInPage") CVLabel Error in Creating/Editing page in the system. diff --git a/pages/PageList/[id].vue b/pages/PageList/[id].vue index 297c1ec8..16331c5f 100644 --- a/pages/PageList/[id].vue +++ b/pages/PageList/[id].vue @@ -158,8 +158,10 @@ const { data: family_pages } = await useFetch('/api/page_list', { } }) const totalLength2 = computed(() => family_pages.value?.Pagination.total as unknown as number) -pages.value = (family_pages.value.data) as unknown as Page2[] +watch(family_pages, () => { + pages.value = (family_pages.value.data) as unknown as Page2[] +}) // Todo: Talk to Taz about this /* // For winter clean up @@ -210,7 +212,7 @@ await getDataPageList() ListboxOption(as='div' v-for="family in data_families" :key="family.cuid" :value="family.cuid" class="px-2 border border-grey-500 py-1 my-1") {{ family.family_name }} ListboxButton(class='text-left bg-white relative rounded-md pl-2 pr-10 py-2 sm:text-sm w-96') {{ familyCuid ? currentFamily.family_name : 'Select family to view pages from' }} //todo: reduce this to one table -.mx-auto.mt-1(class="w-11/12 sm:w-[1200px]" v-if="!isAdvocate || isAdmin || fromUser") +.mx-auto.mt-1(class="w-11/12 sm:w-[1200px]") table(style="table-layout: auto;") thead tr @@ -218,8 +220,8 @@ await getDataPageList() th.font-poppins.font-bold(style="color:white; width: 10%; --tw-bg-opacity: 1; background-color: rgb(110 171 191 / var(--tw-bg-opacity));") Creating User th.font-poppins.font-bold(style="color:white; width: 10%; --tw-bg-opacity: 1; background-color: rgb(110 171 191 / var(--tw-bg-opacity));") Advocate th.font-poppins.font-bold(style="color:white; width: 10%;--tw-bg-opacity: 1; background-color: rgb(110 171 191 / var(--tw-bg-opacity));") Total Donated - th.font-poppins.font-bold(style="color:white; width:20%; --tw-bg-opacity: 1; background-color: rgb(110 171 191 / var(--tw-bg-opacity));") Creation Date - th.font-poppins.font-bold(style="color:white; width:20%; --tw-bg-opacity: 1; background-color: #5aadc2;") Donation Deadline + th.font-poppins.font-bold(style="color:white; width: 20%; --tw-bg-opacity: 1; background-color: rgb(110 171 191 / var(--tw-bg-opacity));") Creation Date + th.font-poppins.font-bold(style="color:white; width: 20%; --tw-bg-opacity: 1; background-color: #5aadc2;") Donation Deadline th.font-poppins.font-bold(style="color:white; --tw-bg-opacity: 1; background-color: rgb(110 171 191 / var(--tw-bg-opacity));") Donation Goal th.font-poppins.font-bold(style="width:15%; --tw-bg-opacity: 1; background-color: #5aadc2; color: white;") {{ "Page Editor" }} th.font-poppins.font-bold(style="border-radius: 0px 60px 0px 0px; width:25%; --tw-bg-opacity: 1; background-color: #5aadc2;color: white;") {{ "Family Page" }} @@ -242,27 +244,6 @@ await getDataPageList() td LinkButton(class="sm:my-2 transition duration-300 bg-orange-999 hover:bg-green-600" style="--tw-bg-opacity: 1; white-space: nowrap; display: flex; flex-direction: row; padding: 14px 24px; gap: 10px;" :to="`/Page/${item.cuid}`") View .container.bg-blue-300.mx-auto(class="w-auto sm:w-[1200px]" style="--tw-bg-opacity: 1; background-color: #5aadc2; height: 50px; border-radius: 0px 0px 60px 60px;") - -.mx-auto.mt-1(class="w-11/12 sm:w-[1200px]" v-if="!fromUser && isAdvocate") - table(style="table-layout: auto;") - thead - tr - th.font-poppins.font-bold.p-2(style="color:white;--tw-bg-opacity: 1; background-color: #5aadc2; overflow: hidden; border-radius: 60px 0px 0px 0px; width:30%; ") Page Name - th.font-poppins.font-bold(style="color:white; width:35%; --tw-bg-opacity: 1; background-color: #5aadc2;") Donation Deadline - th.font-poppins.font-bold(style="width:15%; --tw-bg-opacity: 1; background-color: #5aadc2; color: white;") {{ "Page Editor" }} - th.font-poppins.font-bold(style="border-radius: 0px 60px 0px 0px; width:15%; --tw-bg-opacity: 1; background-color: #5aadc2;color: white;") {{ "Family Page" }} - tr(v-for="(item, i) in family_pages.data" - :key="i" - :class="{'bg-gray-200': (i+1) % 2}" - ) - td.font-poppins.text-gray-dark.font-bold(style="text-align: center;") {{ item.page_first_name + " " + item.page_last_name }} - td.font-poppins.text-gray-dark.font-bold(style="text-align: center;" v-if="isAdmin") {{ item.userCuid }} - td.font-poppins.text-gray-dark.font-bold(style="text-align: center;") {{ dateFormat(item.deadline) }} - td - LinkButton(class="sm:my-2 transition duration-300 bg-orange-999 hover:bg-green-600" style="--tw-bg-opacity: 1; white-space: nowrap; display: flex; flex-direction: row; padding: 14px 24px; gap: 10px;" :to="`/EditPage/${item.cuid}`") Edit - td - LinkButton(class="sm:my-2 transition duration-300 bg-orange-999 hover:bg-green-600" style="--tw-bg-opacity: 1; white-space: nowrap; display: flex; flex-direction: row; padding: 14px 24px; gap: 10px;" :to="`/Page/${item.cuid}`") View - .container.bg-blue-300.mx-auto(class="w-auto sm:w-[1200px]" style="--tw-bg-opacity: 1; background-color: #5aadc2; height: 50px; border-radius: 0px 0px 60px 60px;") .mb-9.py-7.flex.flex-wrap.gap-2.place-content-center .col-md-10.px-2.mt-2 button(@click="prevPage") < diff --git a/server/api/family_pages.get.ts b/server/api/family_pages.get.ts index bc37bd33..2662a4ac 100644 --- a/server/api/family_pages.get.ts +++ b/server/api/family_pages.get.ts @@ -26,7 +26,12 @@ export default defineEventHandler(async event => { skip: page_number as number * 12, take: 12, include: { - User: true + User: true, + Family: { + include: { + AdvocateResponsible: true + } + } } }), prisma.page.findMany({ @@ -34,7 +39,12 @@ export default defineEventHandler(async event => { familyCuid : family_cuid as string }, include: { - User: true + User: true, + Family: { + include: { + AdvocateResponsible: true + } + } } }) ]) diff --git a/server/api/page_list.get.ts b/server/api/page_list.get.ts index 63c30496..2533fd9b 100644 --- a/server/api/page_list.get.ts +++ b/server/api/page_list.get.ts @@ -36,7 +36,12 @@ export default defineEventHandler(async event => { skip: page_number as number * 12, take: 12, include: { - User: true + User: true, + Family: { + include: { + AdvocateResponsible: true + } + } } }), prisma.page.findMany({ @@ -47,7 +52,12 @@ export default defineEventHandler(async event => { familyCuid: cuid as string } ] }, include: { - User: true + User: true, + Family: { + include: { + AdvocateResponsible: true + } + } } }) ])