diff --git a/src/components/BaseComponents/CommunityHeader.vue b/src/components/BaseComponents/CommunityHeader.vue index 4c1ca2e5bf326f0df9f75ed1ba0fce7bf82fcab5..1b0152682deee61f73a15b515deb7005a2b0a751 100644 --- a/src/components/BaseComponents/CommunityHeader.vue +++ b/src/components/BaseComponents/CommunityHeader.vue @@ -2,7 +2,7 @@ <div class="flex items-center justify-between mx-4"> <div class="flex-1 min-w-0"> <h2 - class="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate" + class="text-xl md:text-2xl text-gray-600 font-medium w-full sm:truncate" > {{ community.name }} </h2> diff --git a/src/components/BaseComponents/NavBar.vue b/src/components/BaseComponents/NavBar.vue index 251c1fec23ac86ed9a7c627be290df0efdcfc253..3281cf2e521896053954387941ba03dc04c88281 100644 --- a/src/components/BaseComponents/NavBar.vue +++ b/src/components/BaseComponents/NavBar.vue @@ -15,7 +15,7 @@ <PlusIcon class="m-6 cursor-pointer h-7" alt="Legg til" - @click="$router.push('/addNewItem')" + @click="$router.push('/newItem')" /> </li> <li> diff --git a/src/components/CommunityComponents/CommunityHamburger.vue b/src/components/CommunityComponents/CommunityHamburger.vue index f933ac305b5f0a958e099c491e746409e24dbea3..9a0bcc8dd2b612d5cc68204d1ef2b14112308f72 100644 --- a/src/components/CommunityComponents/CommunityHamburger.vue +++ b/src/components/CommunityComponents/CommunityHamburger.vue @@ -6,28 +6,29 @@ <ul class="py-1"> <li id="newItem"> <router-link - to="/addNewItem" + to="/newItem" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" >Opprett Utleie</router-link > </li> <li id="getMembers"> <router-link - :to="'/group/' + communityID + '/memberlist'" + :to="'/community/' + communityID + '/memberlist'" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" >Se Medlemmer </router-link> </li> <li id="adminGroup" v-if="admin"> <router-link - :to="'/group/' + communityID + '/admin'" + :to="'/community/' + communityID + '/admin'" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" >Administrer Gruppe</router-link > </li> <li id="leaveGroup"> <div - class="cursor-pointer block py-2 px-4 text-sm text-error-medium hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" + class="cursor-pointer block py-2 px-4 text-sm text-error hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" + @click="leaveCommunity" > Forlat Gruppe </div> @@ -37,11 +38,27 @@ </template> <script> + +import { LeaveCommunity } from "@/utils/apiutil"; + export default { name: "CommunityHamburger", props: { communityID: Number, admin: Boolean, }, + data(){ + return{ + id: -1, + } + }, + + methods:{ + leaveCommunity: async function(){ + this.id = await this.$router.currentRoute.value.params.communityID; + await LeaveCommunity(this.id); + this.$router.push('/'); + } + } }; </script> diff --git a/src/components/CommunityComponents/CommunityHome.vue b/src/components/CommunityComponents/CommunityHome.vue index 1f7dcca6aa9c88192fac1263c49fa25da1c4697e..0e8d546252fada67613a3fa49601f5124bce13ae 100644 --- a/src/components/CommunityComponents/CommunityHome.vue +++ b/src/components/CommunityComponents/CommunityHome.vue @@ -37,7 +37,7 @@ </template> <script> -import ItemCard from "@/components/CommunityComponents/ItemCard"; +import ItemCard from "@/components/ItemComponents/ItemCard"; import CommunityHeader from "@/components/BaseComponents/CommunityHeader"; import { GetCommunity, GetListingsInCommunity } from "@/utils/apiutil"; export default { diff --git a/src/components/CommunityComponents/NewCommunityForm.vue b/src/components/CommunityComponents/NewCommunityForm.vue index 8edbda1072907b4fa6b5c976f95e7a550ce6b0f4..3a59f6d796348597c257dd07b73d0c25a566c00c 100644 --- a/src/components/CommunityComponents/NewCommunityForm.vue +++ b/src/components/CommunityComponents/NewCommunityForm.vue @@ -3,50 +3,50 @@ class="md:ring-1 ring-gray-300 rounded-xl overflow-hidden mx-auto mb-auto max-w-md w-full p-4" > <!-- Component heading --> - <h3 - class="text-xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" + <div + class="text-xl md:text-2xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-10" > Opprett ny gruppe - </h3> + </div> <!-- Radio boxes --> <div class="mt-6"> <label - class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" - id="radioBoxLabel" - >Synlighet</label + class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" + id="radioBoxLabel" + >Synlighet</label > <div class="form-check"> <input - class="form-check-input appearance-none rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-primary-medium checked:border-primary-medium focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer" - type="radio" - name="flexRadioDefault" - id="flexRadioOpen" - value="Åpen" - @change="checkRadioButton($event)" - checked + class="form-check-input appearance-none rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-primary-medium checked:border-primary-medium focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer" + type="radio" + name="flexRadioDefault" + id="flexRadioOpen" + value="Åpen" + @change="checkRadioButton($event)" + checked /> <label - class="form-check-label inline-block text-gray-800" - for="flexRadioOpen" - id="radioBoxOpenLabel" + class="form-check-label inline-block text-gray-800" + for="flexRadioOpen" + id="radioBoxOpenLabel" > Åpen </label> </div> <div class="form-check"> <input - class="form-check-input appearance-none rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-primary-medium checked:border-primary-medium focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer" - type="radio" - name="flexRadioDefault" - id="flexRadioPrivate" - value="Privat" - @change="checkRadioButton($event)" + class="form-check-input appearance-none rounded-full h-4 w-4 border border-gray-300 bg-white checked:bg-primary-medium checked:border-primary-medium focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer" + type="radio" + name="flexRadioDefault" + id="flexRadioPrivate" + value="Privat" + @change="checkRadioButton($event)" /> <label - class="form-check-label inline-block text-gray-800" - for="flexRadioPrivate" - id="radioBoxPrivateLabel" + class="form-check-label inline-block text-gray-800" + for="flexRadioPrivate" + id="radioBoxPrivateLabel" > Privat </label> @@ -56,23 +56,23 @@ <!-- Title --> <div class="mt-6" :class="{ error: v$.group.name.$errors.length }"> <label - class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" - id="titleLabel" - >Gruppenavn</label + class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" + id="titleLabel" + >Gruppenavn</label > <input - type="text" - id="title" - class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" - v-model="v$.group.name.$model" - required + type="text" + id="title" + class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" + v-model="v$.group.name.$model" + required /> <!-- error message for title--> <div - class="text-error" - v-for="(error, index) of v$.group.name.$errors" - :key="index" + class="text-error" + v-for="(error, index) of v$.group.name.$errors" + :key="index" > <div class="text-error text-sm"> {{ error.$message }} @@ -83,21 +83,22 @@ <!-- Place --> <div class="mt-6" :class="{ error: v$.group.place.$errors.length }"> <label - class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" - >By/Sted</label + class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" + id="positionLabel" + >By/Sted</label > <input - type="text" - class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" - v-model="v$.group.place.$model" - required + type="text" + class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" + v-model="v$.group.place.$model" + required /> <!-- error message for place--> <div - class="text-error" - v-for="(error, index) of v$.group.place.$errors" - :key="index" + class="text-error" + v-for="(error, index) of v$.group.place.$errors" + :key="index" > <div class="text-error text-sm"> {{ error.$message }} @@ -108,23 +109,23 @@ <!-- Description --> <div class="mt-6" :class="{ error: v$.group.description.$errors.length }"> <label - class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400" - id="descriptionLabel" - >Beskrivelse</label + class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400" + id="descriptionLabel" + >Beskrivelse</label > <textarea - id="description" - rows="4" - v-model="v$.group.description.$model" - class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" - required + id="description" + rows="4" + v-model="v$.group.description.$model" + class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" + required ></textarea> <!-- error message for description --> <div - class="text-error" - v-for="(error, index) of v$.group.description.$errors" - :key="index" + class="text-error" + v-for="(error, index) of v$.group.description.$errors" + :key="index" > <div class="text-error text-sm"> {{ error.$message }} @@ -135,19 +136,19 @@ <!-- Images --> <div class="mt-6"> <label - class="block mb-2 text-xl font-medium text-gray-900 dark:text-gray-400" - id="imageLabel" + class="block mb-2 text-xl font-medium text-gray-900 dark:text-gray-400" + id="imageLabel" > Bilde </label> <input - type="file" - ref="file" - style="display: none" - @change="addImage" - multiple - accept="image/png, image/jpeg" + type="file" + ref="file" + style="display: none" + @change="addImage" + multiple + accept="image/png, image/jpeg" /> <!-- Button for adding an image --> @@ -172,7 +173,12 @@ <!-- Save item button --> <div class="flex justify-center mt-10 float-right"> - <Button @click="saveClicked" id="saveButton" :text="'Lagre'"> </Button> + <Button + @click="saveClicked" + id="saveButton" + :text="'Lagre'" + > + </Button> </div> </div> </template> @@ -198,32 +204,32 @@ export default { group: { name: { required: helpers.withMessage( - () => "Navnt kan ikke være tom", - required + () => "Navnt kan ikke være tom", + required ), max: helpers.withMessage( - () => `Navnet kan være på max 50 tegn`, - maxLength(50) + () => `Navnet kan være på max 50 tegn`, + maxLength(50) ), }, place: { required: helpers.withMessage( - () => "Stedsnavn kan ikke være tom", - required + () => "Stedsnavn kan ikke være tom", + required ), max: helpers.withMessage( - () => `Stednavn kan være på max 50 tegn`, - maxLength(50) + () => `Stednavn kan være på max 50 tegn`, + maxLength(50) ), }, description: { required: helpers.withMessage( - () => "Beskrivelsen kan ikke være tom", - required + () => "Beskrivelsen kan ikke være tom", + required ), max: helpers.withMessage( - () => `Beskrivelsen kan inneholde max 200 tegn`, - maxLength(200) + () => `Beskrivelsen kan inneholde max 200 tegn`, + maxLength(200) ), }, }, diff --git a/src/components/FormComponents/LoginForm.vue b/src/components/FormComponents/LoginForm.vue index 58f1d672bc5daad7ba43ab4e11b85a065203be38..bbb849a1008414ed2abc3899b7216c9a80d7d562 100644 --- a/src/components/FormComponents/LoginForm.vue +++ b/src/components/FormComponents/LoginForm.vue @@ -3,11 +3,11 @@ class="md:ring-1 ring-gray-300 rounded-xl overflow-hidden mx-auto mb-auto max-w-md w-full" > <div class="px-6 py-4 mt-4"> - <h3 - class="text-xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" + <div + class="text-xl md:text-2xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" > Logg på - </h3> + </div> <div> <div diff --git a/src/components/FormComponents/NewPasswordForm.vue b/src/components/FormComponents/NewPasswordForm.vue index d13c08349360250ff4f0cf96b5f3faab00d7a841..e526187d5bc934887fe76196a25195852e8060bf 100644 --- a/src/components/FormComponents/NewPasswordForm.vue +++ b/src/components/FormComponents/NewPasswordForm.vue @@ -2,11 +2,8 @@ <div class="md:ring-1 ring-gray-300 rounded-xl overflow-hidden mx-auto mb-auto max-w-md w-full p-4" > - <h3 - class="text-xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" - > - Endre passord - </h3> + + <div class="text-2xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8">Endre passord</div> <div id="firstPasswordField" diff --git a/src/components/FormComponents/RegisterForm.vue b/src/components/FormComponents/RegisterForm.vue index a2fc3c208a551402412bb31dffc3e73fac640275..c79d4c0af2b58a9a901a908ac9d12490317d8584 100644 --- a/src/components/FormComponents/RegisterForm.vue +++ b/src/components/FormComponents/RegisterForm.vue @@ -2,11 +2,11 @@ <div class="w-full max-w-md mx-auto mb-auto md:ring-1 ring-gray-300 overflow-hidden rounded-xl p-4" > - <h3 - class="text-xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" + <div + class="text-xl md:text-2xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" id="registerLabel" > - Opprett ny bruker - </h3> + Opprett ny konto + </div> <form @submit.prevent> <div class="grid grid-cols-1 gap-6 mt-4"> @@ -157,7 +157,7 @@ </div> <div class="flex justify-end mt-6"> - <Button @click="submit" :text="'Lagre'"></Button> + <Button @click="submit" :text="'Opprett'"></Button> </div> </form> </div> diff --git a/src/components/FormComponents/ResetPasswordForm.vue b/src/components/FormComponents/ResetPasswordForm.vue index a4c2d80e1533e2c7be82804041bd49208b4ab6be..46efcc5efe92a3fba3345238d6db5703cac045ed 100644 --- a/src/components/FormComponents/ResetPasswordForm.vue +++ b/src/components/FormComponents/ResetPasswordForm.vue @@ -1,12 +1,7 @@ <template> - <div - class="md:ring-1 ring-gray-300 rounded-xl overflow-hidden mx-auto mb-auto max-w-md w-full p-4" - > - <h3 - class="text-xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" - > - Glemt passordet ditt? - </h3> + <div class="md:ring-1 ring-gray-300 rounded-xl overflow-hidden mx-auto mb-auto max-w-md w-full p-4"> + + <div class="text-2xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8">Glemt passordet ditt?</div> <div id="emailField" diff --git a/src/components/CommunityComponents/ItemCard.vue b/src/components/ItemComponents/ItemCard.vue similarity index 100% rename from src/components/CommunityComponents/ItemCard.vue rename to src/components/ItemComponents/ItemCard.vue diff --git a/src/components/CommunityComponents/NewItemForm.vue b/src/components/ItemComponents/NewItemForm.vue similarity index 72% rename from src/components/CommunityComponents/NewItemForm.vue rename to src/components/ItemComponents/NewItemForm.vue index 0d26eb64cd7af607ba61930339cf2a3bfddd5a93..8bc2ccd54f5bed6ef82077ca519c191a2c921dd1 100644 --- a/src/components/CommunityComponents/NewItemForm.vue +++ b/src/components/ItemComponents/NewItemForm.vue @@ -3,11 +3,7 @@ class="md:ring-1 ring-gray-300 rounded-xl overflow-hidden mx-auto mb-auto max-w-md w-full p-4" > <!-- Component heading --> - <h3 - class="text-xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-8" - > - Opprett ny utleie - </h3> + <div class="text-xl md:text-2xl font-medium text-center text-gray-600 dark:text-gray-200 mt-4 mb-10">Opprett ny utleie</div> <!-- Title --> <div class="mb-6" :class="{ error: v$.item.title.$errors.length }"> @@ -39,22 +35,22 @@ <!-- Select category --> <div class="mb-6"> <label - class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400" - id="selectCategoryLabel" - >Kategori</label + class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400" + id="selectCategoryLabel" + >Kategori</label > <select - v-model="v$.item.select.$model" - id="categories" - class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" + v-model="v$.item.select.$model" + id="categories" + class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" > <option class="text-gray-400" value="" disabled selected> - Select a category + Velg en kategori </option> <option - v-for="category in categories" - :key="category" - class="text-gray-900 text-sm" + v-for="category in categories" + :key="category" + class="text-gray-900 text-sm" > {{ category }} </option> @@ -62,9 +58,9 @@ <!-- error message for select box --> <div - class="text-error" - v-for="(error, index) of v$.item.select.$errors" - :key="index" + class="text-error" + v-for="(error, index) of v$.item.select.$errors" + :key="index" > <div class="text-error text-sm"> {{ error.$message }} @@ -72,42 +68,36 @@ </div> </div> - <!-- Select Group --> + <!-- Grupper --> <div class="mb-6"> <label - class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-400" - >Gruppe</label - > - <select - v-model="v$.item.selectGroup.$model" - class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-primary-light dark:focus:border-primary-light focus:ring-opacity-40 focus:outline-none focus:ring focus:ring-primary-light" - > - <option class="text-gray-400" value="" disabled selected> - Select a Group - </option> - <option - v-for="group in groups" - :key="group" - class="text-gray-900 text-sm" - > - {{ group }} - </option> - </select> - - <!-- error message for select box --> + class="block text-sm font-medium text-gray-900 dark:text-gray-400" + >Grupper</label> <div - class="text-error" - v-for="(error, index) of v$.item.selectGroup.$errors" - :key="index" + class="overflow-auto w-full h-32 mt-2 text-base list-none bg-white rounded divide-y divide-gray-100 dark:bg-gray-700" > - <div class="text-error text-sm"> - {{ error.$message }} - </div> + <ul class="py-1" aria-labelledby="dropdownDefault"> + <li> + <div class="form-check" v-for="group in groups" :key="group"> + <input + + class="form-check-input appearance-none h-4 w-4 border border-gray-300 rounded-sm bg-white checked:bg-primary-medium checked:bg-primary-medium focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer" + type="checkbox" + :value="group.communityId" + @change="onChangeGroup($event)" + > + <label class="form-check-label inline-block text-gray-800"> + {{ group.name }} + </label> + </div> + </li> + </ul> </div> + <label class="text-error text-sm block">{{ groupErrorMessage }}</label> </div> <!-- price --> - <div class="mb-6" :class="{ error: v$.item.price.$errors.length }"> + <div class="mb-6 mt-4" :class="{ error: v$.item.price.$errors.length }"> <label class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" id="priceLabel" @@ -164,6 +154,7 @@ <div class="mb-6" :class="{ error: v$.item.address.$errors.length }"> <label class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" + id="addressLabel" >Adresse</label > <input @@ -221,7 +212,7 @@ <script> import useVuelidate from "@vuelidate/core"; import { parseUserFromToken } from "@/utils/token-utils"; -import { postNewItem } from "@/utils/apiutil"; +import { postNewItem, getMyGroups } from "@/utils/apiutil"; import Button from "@/components/BaseComponents/ColoredButton"; import { @@ -280,9 +271,6 @@ export default { select: { required: helpers.withMessage(() => `Velg en kategori`, required), }, - selectGroup: { - required: helpers.withMessage(() => `Velg en gruppe`, required), - }, address: { required: helpers.withMessage( () => "Addressen kan ikke være tom", @@ -309,11 +297,13 @@ export default { type: "", images: [], userId: -1, - selectGroup: null, + selectedGroupId: -1, + selectedGroups: [], }, //Kategorier skal legges inn ved api/hente fra db, her må det endres etterhvert categories: ["Hage", "Kjøkken", "Musikk", "Annet"], - groups: [4040, 4041], + groups: [], + groupErrorMessage: '', }; }, methods: { @@ -321,7 +311,10 @@ export default { console.log("sjekker validering"); this.v$.item.$touch(); - if (this.v$.item.$invalid) { + if (this.v$.item.$invalid || this.item.selectedGroups.length === 0) { + if(this.item.selectedGroups.length === 0){ + this.groupErrorMessage = "Velg gruppe/grupper"; + } console.log("Invalid, avslutter..."); return false; } @@ -344,7 +337,7 @@ export default { console.log("Addressen: " + this.item.address); console.log("Pris: " + this.item.price); console.log("bilder: " + this.item.images); - console.log("gruppe: " + this.item.selectGroup); + console.log("gruppe: " + this.item.selectedGroups); const itemInfo = { title: this.item.title, @@ -353,7 +346,7 @@ export default { address: this.item.address, userID: this.item.userId, categoryNames: [], - communityIDs: [this.item.selectGroup], + communityIDs: this.item.selectedGroups, }; console.log(itemInfo); @@ -361,20 +354,49 @@ export default { const postRequest = await postNewItem(itemInfo); console.log("posted: " + postRequest); + + this.$router.push('/'); } }, checkUser: async function () { let user = parseUserFromToken(this.$store.state.user.token); this.item.userId = parseInt(user.accountId); - console.log("id: " + this.item.userId); }, addImage: function (event) { console.log(event.target.files); this.item.images.push(URL.createObjectURL(event.target.files[0])); - console.log("antall bilder: " + this.item.images.length); + }, + + getGroups: async function(){ + this.groups = await getMyGroups(); + }, + + onChangeGroup: function(e){ + this.selectedGroupId = e.target.value; + let alreadyInGroupList = false; + console.log("selected clicked"); + + for (let i = 0; i <= this.item.selectedGroups.length; i++) { + if (this.selectedGroupId == this.item.selectedGroups[i]) { + const index = this.item.selectedGroups.indexOf(this.selectedGroupId); + if (index > -1) { + this.item.selectedGroups.splice(index, 1); + } + alreadyInGroupList = true; + } + } + + if(!alreadyInGroupList){ + this.item.selectedGroups.push(this.selectedGroupId); + this.groupErrorMessage = ""; + } + }, }, + beforeMount() { + this.getGroups(); + } }; </script> diff --git a/src/components/CommunityComponents/SearchItemList.vue b/src/components/ItemComponents/SearchItemList.vue similarity index 97% rename from src/components/CommunityComponents/SearchItemList.vue rename to src/components/ItemComponents/SearchItemList.vue index 32d806a98d18ec9156da12eae1a2a1f715c0fcdc..00ed0583f51be18a36e249fb9e04a599a840d862 100644 --- a/src/components/CommunityComponents/SearchItemList.vue +++ b/src/components/ItemComponents/SearchItemList.vue @@ -31,7 +31,7 @@ </template> <script> -import ItemCard from "@/components/CommunityComponents/ItemCard"; +import ItemCard from "@/components/ItemComponents/ItemCard"; export default { name: "SearchItemListComponent", diff --git a/src/components/UserProfileComponents/LargeProfileCard.vue b/src/components/UserProfileComponents/LargeProfileCard.vue index 10eeba756a018cca14fe476c8ed3a6638496406e..9235ab472cdd07769260c182f5acc0fddd9632a8 100644 --- a/src/components/UserProfileComponents/LargeProfileCard.vue +++ b/src/components/UserProfileComponents/LargeProfileCard.vue @@ -40,7 +40,7 @@ </li> <li> <router-link - :to="'/user/' + id + '/groups'" + :to="'/user/' + id + '/communites'" class="block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" >Mine grupper </router-link> diff --git a/src/router/index.js b/src/router/index.js index 270883ea8f2db85c221b6f719c90f427ac1fc21f..d7d2137894ed778d5da52a196102c566c4ad2b80 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,8 +1,5 @@ import store from "@/store"; import { createRouter, createWebHistory } from "vue-router"; -import HomeView from "../views/CommunityViews/CommunityView.vue"; -import LoginView from "../views/FormViews/LoginView.vue"; -import NewPasswordView from "../views/FormViews/NewPasswordView"; /** * Guards routes. If token is null, no user is logged in and only the @@ -21,7 +18,7 @@ const routes = [ { path: "/", name: "home", - component: HomeView, + component: () => import("../views/CommunityViews/CommunityView.vue"), }, { path: "/profile/:id", @@ -37,27 +34,24 @@ const routes = [ { path: "/messages", name: "messages", - component: () => - import( - /* webpackChunkName: "register" */ "../views/ChatViews/ChatView.vue" - ), + component: () => import("../views/ChatViews/ChatView.vue"), beforeEnter: guardRoute, }, { path: "/login", name: "login", - component: LoginView, + component: () => import("../views/FormViews/LoginView.vue"), }, { path: "/newPassword", name: "newPassword", - component: NewPasswordView, + component: () => import("../views/FormViews/NewPasswordView"), beforeEnter: guardRoute, }, { path: "/searchItemList", name: "searchItemList", - component: () => import("../views/CommunityViews/SearchItemListView.vue"), + component: () => import("../views/ItemViews/SearchItemListView.vue"), }, { path: "/resetPassword", @@ -65,20 +59,21 @@ const routes = [ component: () => import("../views/FormViews/ResetPasswordView.vue"), }, { - path: "/createNewGroup", - name: "createNewGroup", + path: "/newCommunity", + name: "newCommunity", component: () => import("../views/CommunityViews/NewCommunityView.vue"), + beforeEnter: guardRoute, }, { - path: "/group/:communityID/memberlist", + path: "/community/:id/memberlist", name: "memberlist", component: () => import("../views/CommunityViews/MemberListView.vue"), beforeEnter: guardRoute, }, { - path: "/addNewItem", - name: "addNewItem", - component: () => import("../views/CommunityViews/NewItemView.vue"), + path: "/newItem", + name: "newItem", + component: () => import("../views/ItemViews/NewItemView.vue"), beforeEnter: guardRoute, }, { @@ -89,13 +84,14 @@ const routes = [ beforeEnter: guardRoute, }, { - path: "/user/:id/groups", - name: "myGroups", + path: "/user/:id/communities", + name: "myCommunities", component: () => import("../views/CommunityViews/MyCommunitiesView.vue"), + beforeEnter: guardRoute, }, { path: "/community/:communityID", - name: "GroupHome", + name: "communityHome", component: () => import("../views/CommunityViews/CommunityHomeView.vue"), }, { diff --git a/src/utils/apiutil.js b/src/utils/apiutil.js index d7703d811a1afc2c755a65b6ee820399b746bb3a..4779f526733519c3c1fdf78a5d02806d580bcc68 100644 --- a/src/utils/apiutil.js +++ b/src/utils/apiutil.js @@ -222,3 +222,17 @@ export async function GetIfUserAlreadyInCommunity(communityID) { return error; }); } + +export async function LeaveCommunity(communityID) { + return axios + .patch(API_URL + "communities/" + communityID + "/leave", communityID, { + headers: tokenHeader(), + }) + .then((response) => { + return response.data; + }) + .catch((error) => { + console.log(error.data); + return error; + }); +} diff --git a/src/views/CommunityViews/CommunityView.vue b/src/views/CommunityViews/CommunityView.vue index e207d85c264c56de681be55e4f5f676b1af31ffa..e501543c7e84a32f926879d00c60f02812b1d4f5 100644 --- a/src/views/CommunityViews/CommunityView.vue +++ b/src/views/CommunityViews/CommunityView.vue @@ -1,24 +1,23 @@ <template> <div v-if="loggedIn"> <div class="flex flex-row p-4 relative"> - <p class="capitalize font-bold w-full">Mine felleskap</p> - <PlusIcon - class="cursor-pointer max-h-6 max-w-6 float-right grow" - @click="$router.push('/createNewGroup')" - v-if="loggedIn" - alt="Lag ett nytt felleskap" + <div class="text-xl md:text-2xl text-gray-600 font-medium w-full">Mine grupper</div> + <UserAddIcon + class="cursor-pointer max-h-6 max-w-6 float-right grow" + @click="$router.push('/newCommunity')" + alt="Opprett ny gruppe" /> </div> - <CommunityList :communities="myCommunities" :member="true" /> + <CommunityList :communities="myCommunities" :member="true"/> </div> - <p class="capitalize font-bold w-full p-4">Offentlige felleskap</p> - <CommunityList :communities="publicCommunities" :member="false" /> + <p class="text-xl md:text-2xl text-gray-600 font-medium w-full p-4">Offentlige grupper</p> + <CommunityList :communities="publicCommunities" :member="false"/> </template> <script> import CommunityList from "@/components/CommunityComponents/CommunityList.vue"; -import { getMyGroups, getVisibleGroups } from "@/utils/apiutil"; -import { PlusIcon } from "@heroicons/vue/outline"; +import {getMyGroups, getVisibleGroups} from "@/utils/apiutil"; +import {UserAddIcon} from "@heroicons/vue/outline"; export default { name: "HomeView", @@ -31,7 +30,7 @@ export default { }, components: { CommunityList, - PlusIcon, + UserAddIcon, }, async created() { this.publicCommunities = await getVisibleGroups(); @@ -43,7 +42,7 @@ export default { //FIX TOMROWKRO // Remove all of the user's communities from the public communities arrays this.publicCommunities = this.publicCommunities.filter( - (val) => !this.myCommunities.includes(val) + (val) => !this.myCommunities.includes(val) ); }, }; diff --git a/src/views/CommunityViews/NewItemView.vue b/src/views/ItemViews/NewItemView.vue similarity index 75% rename from src/views/CommunityViews/NewItemView.vue rename to src/views/ItemViews/NewItemView.vue index 54978730632a5bf82595624b63bcb29c9f5b9c53..fc9db3697ba1fe00f740bb7457f233be22e6cee5 100644 --- a/src/views/CommunityViews/NewItemView.vue +++ b/src/views/ItemViews/NewItemView.vue @@ -5,7 +5,7 @@ </template> <script> -import AddNewItem from "@/components/CommunityComponents/NewItemForm"; +import AddNewItem from "@/components/ItemComponents/NewItemForm"; export default { name: "AddNewItemView.vue", diff --git a/src/views/CommunityViews/SearchItemListView.vue b/src/views/ItemViews/SearchItemListView.vue similarity index 71% rename from src/views/CommunityViews/SearchItemListView.vue rename to src/views/ItemViews/SearchItemListView.vue index 1725bf8e672f75b7fe3e2600f6ae9bffaf4c063c..7da50f9397c5dee29f471267b8cb08866edcccfb 100644 --- a/src/views/CommunityViews/SearchItemListView.vue +++ b/src/views/ItemViews/SearchItemListView.vue @@ -3,7 +3,7 @@ </template> <script> -import SearchItemListComponent from "@/components/CommunityComponents/SearchItemList"; +import SearchItemListComponent from "@/components/ItemComponents/SearchItemList"; export default { name: "SearchItemListView", components: { diff --git a/tests/unit/component-tests/community-component-tests/add-new-item.spec.js b/tests/unit/component-tests/community-component-tests/add-new-item.spec.js index 417812b108f62b53c5762732a59d4e969b8e4c3c..286a81848eb1b42f673d18a0f7bbc8db36af0aef 100644 --- a/tests/unit/component-tests/community-component-tests/add-new-item.spec.js +++ b/tests/unit/component-tests/community-component-tests/add-new-item.spec.js @@ -1,12 +1,11 @@ import { shallowMount } from "@vue/test-utils"; -import AddNewItem from "@/components/CommunityComponents/NewItemForm.vue"; +import AddNewItem from "@/components/ItemComponents/NewItemForm.vue"; describe("addNewItem elements rendering", () => { it("renders all labels", () => { const wrapper = shallowMount(AddNewItem); expect(wrapper.find("#titleLabel").text()).toMatch("Tittel"); - expect(wrapper.find("#selectCategoryLabel").text()).toMatch("Kategori"); expect(wrapper.find("#priceLabel").text()).toMatch("Pris"); expect(wrapper.find("#descriptionLabel").text()).toMatch("Beskrivelse"); expect(wrapper.find("#imageLabel").text()).toMatch("Bilde"); @@ -19,10 +18,6 @@ describe("addNewItem elements rendering", () => { await titleInput.setValue("Dyson"); expect(titleInput.element.value).toBe("Dyson"); - const selectedCategory = wrapper.find("#categories"); - await selectedCategory.setValue("Hage"); - expect(selectedCategory.element.value).toBe("Hage"); - const priceInput = wrapper.find("#price"); await priceInput.setValue(500); expect(priceInput.element.value).toBe("500"); diff --git a/tests/unit/component-tests/community-component-tests/item-card.spec.js b/tests/unit/component-tests/community-component-tests/item-card.spec.js index a03b348b8070bd4b572f33ec33d2aa641253458c..998c8d4f7d4c90b9407b6cea2d0db8cfa3ea242e 100644 --- a/tests/unit/component-tests/community-component-tests/item-card.spec.js +++ b/tests/unit/component-tests/community-component-tests/item-card.spec.js @@ -1,5 +1,5 @@ import { mount } from "@vue/test-utils"; -import ItemCard from "@/components/CommunityComponents/ItemCard.vue"; +import ItemCard from "@/components/ItemComponents/ItemCard.vue"; describe("ItemCard component", () => { let wrapper; diff --git a/tests/unit/component-tests/community-component-tests/new-item-form.spec.js b/tests/unit/component-tests/community-component-tests/new-item-form.spec.js index 8271342651aaae430c68cbac6f3a924b482384e1..03406c0a54a73cedc2be643c3741015749183312 100644 --- a/tests/unit/component-tests/community-component-tests/new-item-form.spec.js +++ b/tests/unit/component-tests/community-component-tests/new-item-form.spec.js @@ -1,5 +1,5 @@ import { mount } from "@vue/test-utils"; -import NewItemForm from "@/components/CommunityComponents/NewItemForm.vue"; +import NewItemForm from "@/components/ItemComponents/NewItemForm.vue"; describe("NewItemForm component", () => { let wrapper; diff --git a/tests/unit/component-tests/community-component-tests/search-item-list.spec.js b/tests/unit/component-tests/community-component-tests/search-item-list.spec.js index 145a56a66093be7fb062785bafbd11fa6c116f7a..691b8c4bce2d2057528870f628ce99d116cd3e8e 100644 --- a/tests/unit/component-tests/community-component-tests/search-item-list.spec.js +++ b/tests/unit/component-tests/community-component-tests/search-item-list.spec.js @@ -1,5 +1,5 @@ import { shallowMount } from "@vue/test-utils"; -import SearchItemListComponent from "@/components/CommunityComponents/SearchItemList.vue"; +import SearchItemListComponent from "@/components/ItemComponents/SearchItemList.vue"; describe("SearchItemListComponent elements rendering", () => { let wrapper; diff --git a/tests/unit/component-tests/user-component-tests/register-user-component.spec.js b/tests/unit/component-tests/user-component-tests/register-user-component.spec.js index 142860bf75a1138bfa4351ffb688c9982f01adbe..9accd167543e4b2291397821c4aeaedf42804313 100644 --- a/tests/unit/component-tests/user-component-tests/register-user-component.spec.js +++ b/tests/unit/component-tests/user-component-tests/register-user-component.spec.js @@ -17,7 +17,7 @@ describe("RegisterFormComponent", () => { }); it("renders the h2 text correctly", () => { - expect(wrapper.find("h3").text()).toBe("Opprett ny bruker"); + expect(wrapper.find("#registerLabel").text()).toBe("Opprett ny konto"); }); it("has a button", () => {