its DOOMed, coz CORS came here :'(

This commit is contained in:
KUB0570 2025-02-19 20:51:19 +01:00
parent e6c1430e48
commit b593f68b66
19 changed files with 215 additions and 29 deletions

13
TODO
View file

@ -1,24 +1,11 @@
Nastylovat: Nastylovat:
- header nedrží
- footer - footer
- lazyload načítat o něco dříve (neli zrušit alespoň mimo galerii) - lazyload načítat o něco dříve (neli zrušit alespoň mimo galerii)
Naprogramovat: Naprogramovat:
- tlačítko "načíst další aktuality" v komponentě News (možná přidat i novou stránku /aktuality - tlačítko "načíst další aktuality" v komponentě News (možná přidat i novou stránku /aktuality
- přidat kalendář
- kotvičky
- přidat v galerii zvětsovač na obrázky - přidat v galerii zvětsovač na obrázky
- přidat backend
- přidat databázi
- kontakty
- clanky
- kalendar
- přidat api
- přidat volání na api - přidat volání na api
Naplánovat: Naplánovat:
- kurzy + cena: vyskakovací okno na rezervaci s jménem lekce? jak to vyřešit s kalendářem? (stránka /rezervace) - kurzy + cena: vyskakovací okno na rezervaci s jménem lekce? jak to vyřešit s kalendářem? (stránka /rezervace)
- změnit (logicky) pořadí komponent na hlavní stránce
Čeká na Ondru:
- Důležité kontakty + obrázky jak se dostat nebo vzdálenosti od městské dopravy? přidat do googlu

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View file

@ -46,11 +46,15 @@ DEBUG_TOOLBAR_PANELS = [
] ]
ALLOWED_HOSTS = [ ALLOWED_HOSTS = [
"0.0.0.0", "localhost", "127.0.0.1", "localhost",
] ]
INTERNAL_IPS = [ INTERNAL_IPS = [
"0.0.0.0", "localhost", "127.0.0.1", "localhost",
]
CORS_ALLOWED_ORIGINS = [
"http://localhost:8000",
] ]
# Application definition # Application definition
@ -62,6 +66,7 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'tko.apps.TkoConfig',
"debug_toolbar", "debug_toolbar",
'rest_framework', 'rest_framework',
] ]

View file

@ -15,10 +15,14 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import include, path from django.urls import path
from debug_toolbar.toolbar import debug_toolbar_urls from debug_toolbar.toolbar import debug_toolbar_urls
from tko.views import ContactView, ArticleListView, EventListView
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('create-contact/', ContactView.as_view(), name='create-contact'),
path('load-articles/', ArticleListView.as_view(), name='load-articles'),
path('load-events/', EventListView.as_view(), name='load-events'),
] + debug_toolbar_urls() ] + debug_toolbar_urls()

View file

@ -1,19 +1,29 @@
from django.contrib import admin from django.contrib import admin
# Register your models here.
from . import models from . import models
@admin.register(models.Contact) @admin.register(models.Contact)
class ContactAdmin(admin.ModelAdmin): class ContactAdmin(admin.ModelAdmin):
fields = "__all__" list_display = ['name', 'email', 'phone_number', 'content']
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None):
return False
@admin.register(models.Article) @admin.register(models.Article)
class ArticleAdmin(admin.ModelAdmin): class ArticleAdmin(admin.ModelAdmin):
fields = "__all__" list_display = ['title', 'date', 'author']
@admin.register(models.Event) @admin.register(models.Event)
class EventAdmin(admin.ModelAdmin): class EventAdmin(admin.ModelAdmin):
fields = "__all__" list_display = ['title', 'start_date', 'end_date', 'color']

View file

@ -0,0 +1,46 @@
# Generated by Django 5.1.5 on 2025-02-19 16:16
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Article',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('content', models.TextField()),
('date', models.DateField()),
('author', models.CharField(max_length=100)),
('active_to', models.DateField(blank=True, null=True)),
],
),
migrations.CreateModel(
name='Contact',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('first_name', models.CharField(max_length=100)),
('last_name', models.CharField(max_length=100)),
('email', models.EmailField(max_length=254)),
('phone_number', models.CharField(max_length=16)),
('content', models.TextField()),
],
),
migrations.CreateModel(
name='Event',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('start_date', models.DateTimeField()),
('end_date', models.DateTimeField()),
('color', models.CharField(max_length=100)),
],
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 5.1.5 on 2025-02-19 16:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tko', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='article',
name='image',
field=models.FileField(null=True, upload_to='articles/%Y/%m/%d'),
),
]

View file

@ -0,0 +1,22 @@
# Generated by Django 5.1.5 on 2025-02-19 18:33
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('tko', '0002_article_image'),
]
operations = [
migrations.RenameField(
model_name='contact',
old_name='first_name',
new_name='name',
),
migrations.RemoveField(
model_name='contact',
name='last_name',
),
]

View file

@ -2,25 +2,33 @@ from django.db import models
# Create your models here. # Create your models here.
class Contact(models.Model): class Contact(models.Model):
first_name = models.CharField(max_length=100) name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.EmailField() email = models.EmailField()
phone_number = models.CharField(max_length=16) phone_number = models.CharField(max_length=16)
content = models.TextField() content = models.TextField()
def __str__(self):
return f"{self.name}, {self.email}, {self.phone_number}"
class Article(models.Model): class Article(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
content = models.TextField() content = models.TextField()
# image = models.ImageField(upload_to='articles/%Y/%m/%d') image = models.FileField(upload_to='articles/%Y/%m/%d', null=True)
date = models.DateField() date = models.DateField()
author = models.CharField(max_length=100) author = models.CharField(max_length=100)
active_to = models.DateField(null=True, blank=True) # do not show some invitation after this date active_to = models.DateField(null=True, blank=True) # do not show some invitation after this date
def __str__(self):
return self.title
class Event(models.Model): class Event(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
start_date = models.DateTimeField() start_date = models.DateTimeField()
end_date = models.DateTimeField() end_date = models.DateTimeField()
color = models.CharField(max_length=100) color = models.CharField(max_length=100)
def __str__(self):
return self.title

View file

@ -0,0 +1,21 @@
from rest_framework import serializers
from tko.models import Contact, Article, Event
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = '__all__'
class ArticleListSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = '__all__'
class EventListSerializer(serializers.ModelSerializer):
class Meta:
model = Event
fields = '__all__'

View file

@ -1,3 +1,22 @@
from django.shortcuts import render from rest_framework.generics import ListAPIView, CreateAPIView
from rest_framework import permissions
# Create your views here. from tko.models import Article, Event
from tko.serializers import ArticleListSerializer, EventListSerializer, ContactSerializer
class ContactView(CreateAPIView):
serializer_class = ContactSerializer
permission_classes = [permissions.AllowAny]
class ArticleListView(ListAPIView):
queryset = Article.objects.all()
serializer_class = ArticleListSerializer
permission_classes = [permissions.AllowAny]
class EventListView(ListAPIView):
queryset = Event.objects.all()
serializer_class = EventListSerializer
permission_classes = [permissions.AllowAny]

View file

@ -17,6 +17,10 @@
<script setup lang="ts"> <script setup lang="ts">
import './assets/css/main.css' import './assets/css/main.css'
import {useAPI} from "~/composables/useAPI";
const { error, data } = await useAPI('load-events/', {method: "GET"});
const value = [new Date()]; const value = [new Date()];
const events = [ const events = [

View file

@ -1,6 +1,6 @@
<template> <template>
<v-card class="contact"> <v-card class="contact">
<v-form v-model="valid" @submit="sendContact"> <v-form v-model="valid">
<v-container> <v-container>
<v-card-title class="contact__title">Kontaktujte nás!</v-card-title> <v-card-title class="contact__title">Kontaktujte nás!</v-card-title>
<v-row> <v-row>
@ -51,6 +51,7 @@
<v-btn <v-btn
class="contact__button" class="contact__button"
type="submit" type="submit"
@click.prevent="sendContact"
> >
Poslat Poslat
</v-btn> </v-btn>
@ -62,6 +63,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import './assets/css/main.css' import './assets/css/main.css'
import {useAPI} from "~/composables/useAPI";
const valid = ref<boolean>(false); const valid = ref<boolean>(false);
@ -71,7 +73,15 @@ const phone = ref<string>("");
const textField = ref<string>(""); const textField = ref<string>("");
function sendContact() { function sendContact() {
console.log("KONTAKT NEZASLAN"); useAPI('create-contact/', {
method: "POST",
body: {
name: fullName.value,
email: email.value,
phone_number: phone.value,
content: textField.value,
}
});
} }
</script> </script>

View file

@ -44,6 +44,11 @@
<script setup lang="ts"> <script setup lang="ts">
import './assets/css/main.css' import './assets/css/main.css'
import {useAPI} from "~/composables/useAPI";
const { error, data } = await useAPI('load-articles/', {method: "GET"});
console.log(error.value);
const articles = [ const articles = [
{ {
autor: "Bebloid Obecný", autor: "Bebloid Obecný",

View file

@ -1,4 +1,5 @@
<template> <template>
<ClientOnly>
<v-layout> <v-layout>
<v-app-bar style="position: fixed"> <v-app-bar style="position: fixed">
<v-app-bar-nav-icon <v-app-bar-nav-icon
@ -49,8 +50,8 @@
</v-list-item> </v-list-item>
</v-list> </v-list>
</v-navigation-drawer> </v-navigation-drawer>
</v-layout> </v-layout>
</ClientOnly>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View file

@ -0,0 +1,19 @@
import type { UseFetchOptions } from "nuxt/app";
export function useAPI<T>(
endpoint: string,
options?: UseFetchOptions<T>,
) {
if (!endpoint.startsWith("/")) {
endpoint = `/${endpoint}`
}
const cfg = useRuntimeConfig()
const fullUrl = `${cfg.public.backendUrl}${endpoint}`
return useFetch(
fullUrl,
{...options}
)
}

View file

@ -3,11 +3,17 @@ import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
export default defineNuxtConfig({ export default defineNuxtConfig({
compatibilityDate: '2024-11-01', compatibilityDate: '2024-11-01',
ssr: false,
devtools: { enabled: true }, devtools: { enabled: true },
typescript: { typeCheck: true}, typescript: { typeCheck: true},
build: { build: {
transpile: ['vuetify'], transpile: ['vuetify'],
}, },
runtimeConfig: {
public: {
backendUrl: process.env.BACKEND_URL ?? "http://localhost:8000"
},
},
modules: [ modules: [
(_options, nuxt) => { (_options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) => { nuxt.hooks.hook('vite:extendConfig', (config) => {

View file

@ -19,5 +19,7 @@
<courses/> <courses/>
<contact-us/> <contact-us/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
</script> </script>

View file

@ -66,6 +66,5 @@ export default defineNuxtPlugin((app) => {
} }
}) })
app.vueApp.use(vuetify) app.vueApp.use(vuetify)
}) })