Skip to content

Commit f4025ef

Browse files
committed
reworked sponsors
1 parent 6f8f2fc commit f4025ef

File tree

4 files changed

+161
-51
lines changed

4 files changed

+161
-51
lines changed

bruc/views.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,103 @@ class SponsorsViewSet(viewsets.ModelViewSet):
240240
ordering_fields = ['order']
241241
permission_classes = [IsAuthenticated]
242242

243+
@action(detail=False, methods=['get'], permission_classes=[AllowAny], url_path='public')
244+
def public(self, request):
245+
"""
246+
GET /api/sponsors/public/?slug=<slug>
247+
Returns a trimmed, safe payload for the sponsor portal.
248+
"""
249+
slug = request.query_params.get('slug')
250+
if not slug:
251+
return Response({"detail": "slug is required"}, status=400)
252+
253+
sponsor = Sponsors.objects.filter(slug=slug, visible=True).first()
254+
if not sponsor:
255+
return Response({"detail": "Not found"}, status=404)
256+
257+
serializer = self.get_serializer(sponsor)
258+
return Response(serializer.data)
259+
260+
@action(
261+
detail=False,
262+
methods=['get', 'post', 'delete'],
263+
permission_classes=[AllowAny],
264+
url_path='public/guests'
265+
)
266+
def public_guests(self, request):
267+
"""
268+
GET /api/sponsors/public/guests/?slug=<slug>
269+
POST /api/sponsors/public/guests/
270+
DELETE /api/sponsors/public/guests/?slug=<slug>&id=<guest_id>
271+
"""
272+
273+
# ------------------ GET ------------------
274+
if request.method == 'GET':
275+
slug = (request.query_params.get("slug") or "").strip()
276+
if not slug:
277+
return Response({"detail": "slug is required"}, status=400)
278+
279+
sponsor = Sponsors.objects.filter(slug=slug, visible=True).first()
280+
if not sponsor:
281+
return Response({"detail": "Sponsor not found"}, status=404)
282+
283+
tag_prefix = f"{sponsor.slug} "
284+
qs = Guests.objects.filter(tag__istartswith=tag_prefix).order_by("id")
285+
286+
return Response(
287+
GuestsSerializer(qs, many=True).data,
288+
status=200,
289+
)
290+
291+
# ------------------ DELETE ------------------
292+
if request.method == 'DELETE':
293+
slug = (request.query_params.get("slug") or "").strip()
294+
guest_id = (request.query_params.get("id") or "").strip()
295+
296+
if not slug or not guest_id:
297+
return Response({"detail": "slug and id are required"}, status=400)
298+
299+
sponsor = Sponsors.objects.filter(slug=slug).first()
300+
if not sponsor:
301+
return Response({"detail": "Sponsor not found"}, status=404)
302+
303+
guest = Guests.objects.filter(id=guest_id, tag__icontains=sponsor.slug).first()
304+
if not guest:
305+
return Response({"detail": "Guest not found"}, status=404)
306+
307+
guest.delete()
308+
return Response(status=status.HTTP_204_NO_CONTENT)
309+
310+
# ------------------ POST ------------------
311+
slug = (request.data.get("slug") or "").strip()
312+
name = (request.data.get("name") or "").strip()
313+
314+
if not slug or not name:
315+
return Response({"detail": "slug and name are required"}, status=400)
316+
317+
sponsor = Sponsors.objects.filter(slug=slug).first()
318+
if not sponsor:
319+
return Response({"detail": "Sponsor not found"}, status=404)
320+
321+
if getattr(sponsor, "guestCap", None) is not None:
322+
count = Guests.objects.filter(tag__icontains=sponsor.slug).count()
323+
if count >= int(sponsor.guestCap):
324+
return Response({"detail": "Guest limit reached"}, status=409)
325+
326+
tag = f"{sponsor.slug} VIP - Sponzor - {sponsor.name}"
327+
328+
guest = Guests.objects.create(
329+
name=name,
330+
tag=tag,
331+
bought=True,
332+
entered=False,
333+
)
334+
335+
return Response(
336+
{"id": guest.id, "name": guest.name, "tag": guest.tag},
337+
status=status.HTTP_201_CREATED,
338+
)
339+
243340
@transaction.atomic
244341
def perform_create(self, serializer):
245342
"""

ui/src/plugins/publicApi.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import axios from "axios";
2+
3+
export const publicApi = axios.create({
4+
baseURL: process.env.VUE_APP_BASE_URL,
5+
});

ui/src/views/AdminViews/SponsorsAddView.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import { uuid } from 'vue-uuid'
7575
import Sidebar from '@/components/NavbarAndFooter/Sidebar.vue'
7676
import sponsorsStore from '@/store/sponsorsStore'
7777
import ToggleSwitch from 'primevue/toggleswitch'
78+
import visibilityStore from '@/store/visibilityStore'
7879
7980
export default {
8081
name: "SponsorsAdd",
@@ -119,7 +120,7 @@ export default {
119120
this.url = sponsor.url
120121
this.email = sponsor.email
121122
this.guestCap = sponsor.guestCap
122-
this.guestsEnabled = sponsor.guestsEnabled
123+
this.guestsEnabled = sponsor.guestsEnabled == "1" ? true : false;
123124
this.visible = sponsor.visible
124125
this.currentImage = sponsor.image
125126
} else {
@@ -172,8 +173,8 @@ export default {
172173
formData.append("visible", this.visible ? "1" : "0")
173174
174175
// guestsEnabled logic
175-
if (this.guestsEnabled === '1') {
176-
const closeTime = 1668276000000
176+
if (this.guestsEnabled === true) {
177+
const closeTime = Date.parse(visibilityStore.state.SPONSORS_INPUT_TIME);
177178
formData.append("guestsEnabled", Date.now() > closeTime ? "2" : "1")
178179
} else {
179180
formData.append("guestsEnabled", "0")

ui/src/views/BruciWebViews/SponsorsPageView.vue

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<template>
22
<div class="bw-page-container sponsors-page">
3-
<NavbarBweb></NavbarBweb>
43
<div class="popis">
54

65
<div v-if="this.guestsEnabled != 0" class="popis-element1">
@@ -16,7 +15,8 @@
1615
</div>
1716

1817
<div>
19-
<h1 v-if="this.guestsEnabled == 0" class="page-title-dis" style="margin-left: 50px; margin-top: 70px;">Popis
18+
<h1 v-if="this.guestsEnabled == 0" class="page-title-dis" style="margin-left: 50px; margin-top: 70px;">
19+
Popis
2020
uzvanika</h1>
2121

2222
<div v-if="this.guestsEnabled != 0" class="infofield">
@@ -61,9 +61,9 @@
6161
<div class="sponsorsPage-table">
6262
<div class=row>
6363
<table id="guests">
64-
<tbody :class="{ [$style.tbodyHigh]: this.tbodyHigh }" style="overflow:auto;height: 35rem !important;"
65-
class="tbody">
66-
<tr v-for="guest in sponsorGuests" :key="guest.id">
64+
<tbody :class="{ [$style.tbodyHigh]: this.tbodyHigh }"
65+
style="overflow:auto;height: 35rem !important;" class="tbody">
66+
<tr v-for="guest in sponsorGuests" style=" width: 100%;" :key="guest.id">
6767
<td style="padding-left: 20% !important;">{{ guest.name }}</td>
6868
<td v-if="this.guestsEnabled != 0" style="padding-left: 10% !important;"><button
6969
class="button-icon" @click=sponsorDelete(guest)
@@ -77,15 +77,16 @@
7777
</div>
7878
</div>
7979

80-
<Footer></Footer>
8180
</div>
81+
<Footer></Footer>
8282
</template>
8383

8484
<script>
8585
import Footer from '@/components/NavbarAndFooter/Footer.vue'
8686
import NavbarBweb from '@/components/NavbarAndFooter/NavbarBweb.vue'
8787
import store from '@/store/visibilityStore'
88-
import axios from 'axios'
88+
import { publicApi } from "@/plugins/publicApi";
89+
import { api } from '@/plugins/api';
8990
9091
export default {
9192
components: { Footer, NavbarBweb },
@@ -97,7 +98,6 @@ export default {
9798
progress: 0,
9899
message: "",
99100
100-
sponsorss: [],
101101
name: '',
102102
id: '',
103103
len: '',
@@ -112,14 +112,14 @@ export default {
112112
mounted() {
113113
this.slug = this.$route.params.slug;
114114
if (this.slug != '0') {
115-
axios.get(process.env.VUE_APP_BASE_URL + '/sponsors/?search=' + this.slug + "&search_fields=slug")
115+
publicApi.get("/sponsors/public/", { params: { slug: this.slug } })
116116
.then(async response => {
117117
this.sponsors = response.data;
118118
if (this.sponsors.length == 0) {
119119
this.$router.push({ path: '/admin/sponsors-add/0' });
120120
}
121121
122-
this.sponsorsInstance = this.sponsors[0];
122+
this.sponsorsInstance = this.sponsors;
123123
this.name = this.sponsorsInstance.name;
124124
this.previewImage = this.sponsorsInstance.image;
125125
this.id = this.sponsorsInstance.id;
@@ -130,11 +130,9 @@ export default {
130130
131131
this.guestsEnabled = this.sponsorsInstance.guestsEnabled;
132132
133-
134-
135-
console.log(this.guestsEnabled)
136133
if (this.guestsEnabled != 2) {
137134
let closeTime = Date.parse(store.state.SPONSORS_INPUT_TIME); // pravi closetime 12.11.2022 u 19.00
135+
console.log(closeTime)
138136
if (Date.now() > closeTime) {
139137
console.log("zatvaraaaaj")
140138
console.log(this.sponsorsInstance)
@@ -168,50 +166,60 @@ export default {
168166
169167
methods: {
170168
created() {
171-
172-
if (this.slug != '0') {
173-
axios.get(process.env.VUE_APP_BASE_URL + '/guests/?search=' + this.slug + "&search_fields=tag")
169+
if (this.slug !== '0') {
170+
api
171+
.get(`${process.env.VUE_APP_BASE_URL}/sponsors/public/guests/`, {
172+
params: { slug: this.slug }
173+
})
174174
.then(response => {
175175
this.sponsorGuests = response.data;
176176
this.guestsAdded = this.sponsorGuests.length;
177-
axios.get(process.env.VUE_APP_BASE_URL + '/guests/')
178-
.then(response => {
179-
this.guests = response.data;
180-
})
181-
})
182-
183-
} else {
184-
axios.get(process.env.VUE_APP_BASE_URL + '/sponsors/?ordering=order',)
185-
.then(response => {
186-
this.sponsorss = response.data;
187177
})
178+
.catch(err => {
179+
const msg = err?.response?.data?.detail || "Greška pri dohvaćanju gostiju";
180+
window.alert(msg);
181+
});
188182
}
189183
},
190184
sponsorDelete(guest) {
191-
axios.delete(process.env.VUE_APP_BASE_URL + '/guests/' + guest.id + '/',
192-
{ auth: { username: process.env.VUE_APP_DJANGO_USER, password: process.env.VUE_APP_DJANGO_PASS } }
193-
)
194-
.then(() => {
195-
this.created();
196-
})
185+
api.delete(
186+
`${process.env.VUE_APP_BASE_URL}/sponsors/public/guests/`,
187+
{ params: { slug: this.slug, id: guest.id } }
188+
).then(() => {
189+
this.created();
190+
}).catch(err => {
191+
const msg = err?.response?.data?.detail || "Greška pri brisanju gosta";
192+
window.alert(msg);
193+
});
197194
},
198195
sponsorPost() {
199-
if (this.guestCap == this.guestsAdded) {
200-
window.alert("Već ste unjeli maximum dozvoljenih gostiju")
201-
} else {
202-
203-
let sponsorTag = this.slug + "VIP - Sponzor - " + this.name;
204-
205-
axios.post(process.env.VUE_APP_BASE_URL + '/guests/',
206-
{ name: this.sponsorName, tag: sponsorTag, bought: '1', entered: '0' },
207-
{ auth: { username: process.env.VUE_APP_DJANGO_USER, password: process.env.VUE_APP_DJANGO_PASS } }
208-
)
209-
.then(() => {
210-
this.sponsorName = "";
211-
this.created()
212-
})
196+
// Check if sponsor reached guest limit
197+
if (this.guestCap === this.guestsAdded) {
198+
window.alert("Već ste unijeli maksimalan broj dozvoljenih gostiju");
199+
return;
213200
}
201+
202+
const guestName = (this.sponsorName || "").trim();
203+
if (!guestName) {
204+
return;
205+
}
206+
207+
const payload = {
208+
slug: this.slug,
209+
name: guestName,
210+
};
211+
212+
api.post(`${process.env.VUE_APP_BASE_URL}/sponsors/public/guests/`, payload)
213+
.then(() => {
214+
this.sponsorName = "";
215+
this.created();
216+
})
217+
.catch(err => {
218+
const msg = err?.response?.data?.detail || "Greška pri unosu gosta";
219+
window.alert(msg);
220+
});
214221
}
222+
215223
}
216224
}
217225
</script>
@@ -286,7 +294,6 @@ export default {
286294
287295
.popis {
288296
position: relative;
289-
margin-top: 2%;
290297
display: grid;
291298
grid-template-rows: 55% 45%;
292299
width: 100%;
@@ -359,7 +366,7 @@ h1 {
359366
360367
.footery {
361368
background: var(--bw-footer-color);
362-
;
369+
;
363370
}
364371
365372
.footery::after {

0 commit comments

Comments
 (0)