Compare commits
No commits in common. "main" and "usefetch-to-fetch" have entirely different histories.
main
...
usefetch-t
21 changed files with 158 additions and 440 deletions
3
.idea/dictionaries/project.xml
generated
3
.idea/dictionaries/project.xml
generated
|
@ -1,3 +0,0 @@
|
||||||
<component name="ProjectDictionaryState">
|
|
||||||
<dictionary name="project" />
|
|
||||||
</component>
|
|
6
.idea/tailwindcss.xml
generated
6
.idea/tailwindcss.xml
generated
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="TailwindSettings">
|
|
||||||
<option name="lspConfiguration" value="{ "includeLanguages": { "ftl": "html", "jinja": "html", "jinja2": "html", "smarty": "html", "tmpl": "gohtml", "cshtml": "html", "vbhtml": "html", "razor": "html", "scss": "scss", "html": "html", "javascript": "javascript", "typescript": "typescript", "css": "css", "vue": "vue", "sass": "sass", "twig": "twig" }, "files": { "exclude": [ "**/.git/**", "**/node_modules/**", "**/.hg/**", "**/.svn/**" ] }, "emmetCompletions": false, "classAttributes": ["class", "className", "ngClass"], "colorDecorators": true, "showPixelEquivalents": true, "rootFontSize": 16, "hovers": true, "suggestions": true, "codeActions": true, "validate": true, "lint": { "invalidScreen": "error", "invalidVariant": "error", "invalidTailwindDirective": "error", "invalidApply": "error", "invalidConfigPath": "error", "cssConflict": "warning", "recommendedVariantOrder": "warning" }, "experimental": { "configFile": null, "classRegex": [] } }" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
1
.idea/web.iml
generated
1
.idea/web.iml
generated
|
@ -4,6 +4,5 @@
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="@types/tailwindcss" level="application" />
|
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
75
.idea/workspace.xml
generated
75
.idea/workspace.xml
generated
|
@ -6,14 +6,19 @@
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="5e320804-68c9-4504-97d5-d421de3438b2" name="Changes" comment="">
|
<list default="true" id="5e320804-68c9-4504-97d5-d421de3438b2" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/components/LoadingIcon.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/LoadingIcon.vue" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/components/admin/lists.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/admin/lists.vue" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/components/admin/showings.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/admin/showings.vue" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/pages/admin/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/admin/index.vue" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/pages/lists/[id].vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/lists/[id].vue" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/pages/lists/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/lists/index.vue" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/pages/schedule/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/schedule/index.vue" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ComposerSettings" synchronizationState="SYNCHRONIZE">
|
<component name="ComposerSettings">
|
||||||
<execution />
|
<execution />
|
||||||
</component>
|
</component>
|
||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
|
@ -22,7 +27,6 @@
|
||||||
<option value="CSS File" />
|
<option value="CSS File" />
|
||||||
<option value="Vue Single File Component" />
|
<option value="Vue Single File Component" />
|
||||||
<option value="TypeScript File" />
|
<option value="TypeScript File" />
|
||||||
<option value="Vue Composition API Component" />
|
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
@ -56,37 +60,31 @@
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"WebServerToolWindowFactoryState": "false",
|
"WebServerToolWindowFactoryState": "false",
|
||||||
"code.cleanup.on.save": "true",
|
"code.cleanup.on.save": "true",
|
||||||
"git-widget-placeholder": "main",
|
"git-widget-placeholder": "usefetch-to-fetch",
|
||||||
"junie.onboarding.icon.badge.shown": "true",
|
"last_opened_file_path": "/home/tiradoe/Projects/movie-night/web/src/types",
|
||||||
"last_opened_file_path": "/home/tiradoe/Projects/MovieNight/movie-night-web",
|
"list.type.of.created.stylesheet": "CSS",
|
||||||
"list.type.of.created.stylesheet": "CSS",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.standard": "true",
|
||||||
"node.js.detected.package.standard": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.standard": "",
|
||||||
"node.js.selected.package.standard": "",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"nodejs_package_manager_path": "npm",
|
||||||
"nodejs_package_manager_path": "npm",
|
"npm.dev.executor": "Run",
|
||||||
"npm.dev.executor": "Run",
|
"prettierjs.PrettierConfiguration.Package": "/home/tiradoe/Projects/movie-night/web/src/node_modules/prettier",
|
||||||
"prettierjs.PrettierConfiguration.Package": "/home/tiradoe/Projects/MovieNight/movie-night-web/src/node_modules/prettier",
|
"rearrange.code.on.save": "true",
|
||||||
"rearrange.code.on.save": "true",
|
"settings.editor.selected.configurable": "settings.vue",
|
||||||
"settings.editor.selected.configurable": "configurable.group.editor",
|
"ts.external.directory.path": "/home/tiradoe/Projects/movie-night/web/src/node_modules/typescript/lib",
|
||||||
"ts.external.directory.path": "/home/tiradoe/Projects/MovieNight/movie-night-web/src/node_modules/typescript/lib",
|
"vue.rearranger.settings.migration": "true"
|
||||||
"vue.rearranger.settings.migration": "true"
|
|
||||||
},
|
|
||||||
"keyToStringList": {
|
|
||||||
"vue.recent.templates": [
|
|
||||||
"Vue Composition API Component"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$/src/types" />
|
<recent name="$PROJECT_DIR$/src/types" />
|
||||||
|
@ -114,8 +112,8 @@
|
||||||
<component name="SharedIndexes">
|
<component name="SharedIndexes">
|
||||||
<attachedChunks>
|
<attachedChunks>
|
||||||
<set>
|
<set>
|
||||||
<option value="bundled-js-predefined-d6986cc7102b-b26f3e71634d-JavaScript-PS-251.26094.133" />
|
<option value="bundled-js-predefined-d6986cc7102b-1632447f56bf-JavaScript-PS-243.26053.13" />
|
||||||
<option value="bundled-php-predefined-a98d8de5180a-c5828cf854d9-com.jetbrains.php.sharedIndexes-PS-251.26094.133" />
|
<option value="bundled-php-predefined-a98d8de5180a-1ec7b7818973-com.jetbrains.php.sharedIndexes-PS-243.26053.13" />
|
||||||
</set>
|
</set>
|
||||||
</attachedChunks>
|
</attachedChunks>
|
||||||
</component>
|
</component>
|
||||||
|
@ -139,13 +137,6 @@
|
||||||
<workItem from="1743904898331" duration="20256000" />
|
<workItem from="1743904898331" duration="20256000" />
|
||||||
<workItem from="1743998844137" duration="23268000" />
|
<workItem from="1743998844137" duration="23268000" />
|
||||||
<workItem from="1744430699183" duration="32152000" />
|
<workItem from="1744430699183" duration="32152000" />
|
||||||
<workItem from="1745179755243" duration="40533000" />
|
|
||||||
<workItem from="1745366380362" duration="223000" />
|
|
||||||
<workItem from="1745366610986" duration="319000" />
|
|
||||||
<workItem from="1745366940811" duration="4297000" />
|
|
||||||
<workItem from="1748541588253" duration="2587000" />
|
|
||||||
<workItem from="1750288132986" duration="18089000" />
|
|
||||||
<workItem from="1750873961750" duration="644000" />
|
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -2,5 +2,3 @@ Movie Night Web
|
||||||
=
|
=
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Uses filmstrip icon by momentbloom (https://www.vecteezy.com/vector-art/36659391-filmstrip)
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,48 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
viewBox="1413.5 192.80002 108.59998 149.10001"
|
|
||||||
width="108.59998"
|
|
||||||
height="149.10001"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
sodipodi:docname="poster-placeholder.svg"
|
|
||||||
inkscape:export-filename="poster-placeholder2.svg"
|
|
||||||
inkscape:export-xdpi="96"
|
|
||||||
inkscape:export-ydpi="96"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:export-bgcolor="#ffffffff">
|
|
||||||
<inkscape:page
|
|
||||||
x="0"
|
|
||||||
y="0"
|
|
||||||
width="108.59998"
|
|
||||||
height="149.10001"
|
|
||||||
id="page2"
|
|
||||||
margin="0"
|
|
||||||
bleed="0" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<rect
|
|
||||||
style="fill:#5c5b79;fill-opacity:1"
|
|
||||||
id="rect1"
|
|
||||||
width="108.28388"
|
|
||||||
height="148.72725"
|
|
||||||
x="1413.6864"
|
|
||||||
y="193.17278" />
|
|
||||||
<path
|
|
||||||
fill="#cccccc"
|
|
||||||
d="m 1413.5,242.5 c 0,16.6 0,33.1 0,49.7 36.2,49.7 72.4,-49.7 108.6,0 0,-16.6 0,-33.1 0,-49.7 -36.2,-49.7 -72.4,49.7 -108.6,0 z m 8.7,56.7 c -1.6,-1.3 -3.3,-2.8 -4.9,-4.6 0,-1.6 0,-3.3 0,-4.9 1.6,1.8 3.3,3.3 4.9,4.6 0,1.7 0,3.3 0,4.9 z m 0,-39.8 c -1.6,-1.3 -3.3,-2.8 -4.9,-4.6 0,-1.6 0,-3.3 0,-4.9 1.6,1.8 3.3,3.3 4.9,4.6 0,1.6 0,3.3 0,4.9 z m 9.6,44.4 c -1.6,-0.4 -3.3,-0.9 -4.9,-1.7 0,-1.6 0,-3.3 0,-4.9 1.6,0.8 3.3,1.4 4.9,1.7 0,1.7 0,3.3 0,4.9 z m 0,-39.8 c -1.6,-0.4 -3.3,-0.9 -4.9,-1.7 0,-1.6 0,-3.3 0,-4.9 1.6,0.8 3.3,1.4 4.9,1.7 0,1.7 0,3.3 0,4.9 z m 9.6,39.8 c -1.6,0.3 -3.3,0.5 -4.9,0.5 0,-1.6 0,-3.3 0,-4.9 1.6,0 3.3,-0.2 4.9,-0.5 0,1.7 0,3.3 0,4.9 z m 0,-39.8 c -1.6,0.3 -3.3,0.5 -4.9,0.5 0,-1.6 0,-3.3 0,-4.9 1.6,0 3.3,-0.2 4.9,-0.5 0,1.6 0,3.3 0,4.9 z m 9.6,36.4 c -1.6,0.8 -3.3,1.5 -4.9,2.1 0,-1.6 0,-3.3 0,-4.9 1.6,-0.6 3.3,-1.3 4.9,-2.1 0,1.7 0,3.3 0,4.9 z m 0,-39.8 c -1.6,0.8 -3.3,1.5 -4.9,2.1 0,-1.6 0,-3.3 0,-4.9 1.6,-0.6 3.3,-1.3 4.9,-2.1 0,1.6 0,3.3 0,4.9 z m 9.5,34.3 c -1.6,1.1 -3.3,2.1 -4.9,3 0,-1.6 0,-3.3 0,-4.9 1.6,-1 3.3,-2 4.9,-3 0,1.6 0,3.2 0,4.9 z m 0,-39.8 c -1.6,1.1 -3.3,2.1 -4.9,3 0,-1.6 0,-3.3 0,-4.9 1.6,-1 3.3,-2 4.9,-3 0,1.6 0,3.2 0,4.9 z m 9.6,33.3 c -1.6,1.1 -3.3,2.3 -4.9,3.4 0,-1.6 0,-3.3 0,-4.9 1.6,-1.1 3.3,-2.2 4.9,-3.4 0,1.6 0,3.2 0,4.9 z m 0,-39.8 c -1.6,1.1 -3.3,2.3 -4.9,3.4 0,-1.6 0,-3.3 0,-4.9 1.6,-1.1 3.3,-2.2 4.9,-3.4 0,1.6 0,3.2 0,4.9 z m 9.6,33.6 c -1.6,1 -3.3,2 -4.9,3.1 0,-1.6 0,-3.3 0,-4.9 1.6,-1.1 3.3,-2.1 4.9,-3.1 0,1.6 0,3.3 0,4.9 z m 0,-39.8 c -1.6,1 -3.3,2 -4.9,3.1 0,-1.6 0,-3.3 0,-4.9 1.6,-1.1 3.3,-2.1 4.9,-3.1 0,1.6 0,3.2 0,4.9 z m 9.6,35.1 c -1.6,0.6 -3.3,1.3 -4.9,2.1 0,-1.6 0,-3.3 0,-4.9 1.6,-0.8 3.3,-1.5 4.9,-2.1 0,1.7 0,3.3 0,4.9 z m 0,-39.8 c -1.6,0.6 -3.3,1.3 -4.9,2.1 0,-1.6 0,-3.3 0,-4.9 1.6,-0.8 3.3,-1.5 4.9,-2.1 0,1.7 0,3.3 0,4.9 z m 9.6,37.9 c -1.6,0 -3.3,0.2 -4.9,0.6 0,-1.6 0,-3.3 0,-4.9 1.6,-0.3 3.3,-0.5 4.9,-0.6 0,1.7 0,3.3 0,4.9 z m 0,-39.8 c -1.6,0 -3.3,0.2 -4.9,0.6 0,-1.6 0,-3.3 0,-4.9 1.6,-0.3 3.3,-0.5 4.9,-0.6 0,1.6 0,3.3 0,4.9 z m 14.2,0 c 1.6,1.2 3.3,2.7 4.9,4.5 0,1.6 0,3.3 0,4.9 -1.6,-1.8 -3.3,-3.2 -4.9,-4.5 0,-1.6 0,-3.2 0,-4.9 z m 0,39.8 c 1.6,1.2 3.3,2.7 4.9,4.5 0,1.6 0,3.3 0,4.9 -1.6,-1.8 -3.3,-3.2 -4.9,-4.5 0,-1.6 0,-3.2 0,-4.9 z m -9.6,-44.2 c 1.6,0.3 3.3,0.9 4.9,1.6 0,1.6 0,3.3 0,4.9 -1.6,-0.8 -3.3,-1.3 -4.9,-1.6 0,-1.7 0,-3.3 0,-4.9 z m 0,39.8 c 1.6,0.3 3.3,0.9 4.9,1.6 0,1.6 0,3.3 0,4.9 -1.6,-0.8 -3.3,-1.3 -4.9,-1.6 0,-1.7 0,-3.3 0,-4.9 z"
|
|
||||||
id="path1" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.6 KiB |
|
@ -1,31 +0,0 @@
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
class="flex absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 flex-col"
|
|
||||||
>
|
|
||||||
<video alt="Loading" autoplay class="max-h-52" loop muted playsinline>
|
|
||||||
<source
|
|
||||||
v-if="supportsHEVC"
|
|
||||||
src="/assets/img/movie-loader.mov"
|
|
||||||
type="video/quicktime"
|
|
||||||
/>
|
|
||||||
<source v-else src="/assets/img/movie-loader.webm" type="video/webm" />
|
|
||||||
</video>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const supportsHEVC = ref(false);
|
|
||||||
const props = defineProps(["showQuote"]);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
||||||
|
|
||||||
// iOS devices also support HEVC
|
|
||||||
const isIOS =
|
|
||||||
/iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as any).MSStream;
|
|
||||||
|
|
||||||
supportsHEVC.value = isSafari || isIOS;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,14 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-show="visible" id="movie-modal" class="movie-modal movie-card">
|
<div v-show="visible" id="movie-modal" class="movie-modal movie-card p-5">
|
||||||
<div class="max-w-4xl mx-auto flex flex-col px-2 sm:px-0">
|
<span
|
||||||
<span
|
class="hover-pointer font-bold w-full block text-right sm:pr-5 pb-3 pt-5"
|
||||||
class="hover-pointer font-bold self-end pr-1 sm:pr-5 pt-5 pb-5 sm:pb-0"
|
@click="toggleModal()"
|
||||||
@click="toggleModal()"
|
>
|
||||||
>
|
X
|
||||||
<span class="bg-red-600 p-2 rounded">X</span>
|
</span>
|
||||||
</span>
|
<slot class=""></slot>
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
<script lang="ts" setup>
|
|
||||||
import placeholderPoster from "assets/img/poster-placeholder.svg";
|
|
||||||
|
|
||||||
const imgRef = ref<HTMLImageElement | null>(null);
|
|
||||||
const props = defineProps(["image"]);
|
|
||||||
|
|
||||||
const handleImageError = function (event: Event) {
|
|
||||||
(event.target as HTMLImageElement).classList.remove("lazyload");
|
|
||||||
(event.target as HTMLImageElement).classList.add("object-cover");
|
|
||||||
(event.target as HTMLImageElement).src = placeholderPoster;
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.image,
|
|
||||||
(newImage) => {
|
|
||||||
if (imgRef.value && newImage) {
|
|
||||||
imgRef.value.classList.add("lazyload");
|
|
||||||
imgRef.value.setAttribute("data-src", newImage);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="aspect-[2/3] w-full text-blue-300">
|
|
||||||
<img
|
|
||||||
ref="imgRef"
|
|
||||||
:data-src="props.image"
|
|
||||||
alt="Movie Details"
|
|
||||||
class="lazyload hover-pointer w-full h-full"
|
|
||||||
@error="handleImageError"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,54 +0,0 @@
|
||||||
<template>
|
|
||||||
<blockquote
|
|
||||||
class="flex flex-col gap-10 movie-card p-10 neon-border text-center"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
{{ quote.quote }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div class="flex gap-2 italic flex-col">
|
|
||||||
<span>{{ quote.actor }}</span>
|
|
||||||
<span>{{ quote.movie }}</span>
|
|
||||||
</div>
|
|
||||||
</blockquote>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const quotes = [
|
|
||||||
{
|
|
||||||
actor: "Darren Ewing as Arnold",
|
|
||||||
movie: "Troll 2",
|
|
||||||
quote: "They're eating her... and then they're going to eat me! OH MY GOD!",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actor: "Tommy Wiseau as Johnny",
|
|
||||||
movie: "The Room",
|
|
||||||
quote: "You're tearing me apart, Lisa!",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actor: "Arnold Schwaarzenegger as T-800",
|
|
||||||
movie: "Terminator 2: Judgment Day",
|
|
||||||
quote: "Hasta la vista, baby.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actor: "Karolyn Grimes as Zuzu",
|
|
||||||
movie: "It's a Wonderful Life",
|
|
||||||
quote: "Every time a bell rings, an angel gets his wings.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actor: "Pat Morita as Mr. Miyagi",
|
|
||||||
movie: "The Karate Kid",
|
|
||||||
quote: "Wax on, Wax off",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actor: "Dolph Lundgren as Drago",
|
|
||||||
movie: "Rocky 4",
|
|
||||||
quote: "I must break you.",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const randomQuote = () => quotes[Math.floor(Math.random() * quotes.length)];
|
|
||||||
|
|
||||||
const quote = ref(randomQuote());
|
|
||||||
</script>
|
|
|
@ -1,5 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<LoadingIcon v-if="loading" class="p-1 bg-gray-900 rounded-3xl" />
|
|
||||||
<form class="py-3 p-sm-0 align-items-center" @submit="findMovies">
|
<form class="py-3 p-sm-0 align-items-center" @submit="findMovies">
|
||||||
<label class="px-0" for="search-field">Search</label>
|
<label class="px-0" for="search-field">Search</label>
|
||||||
<div class="px-0 mx-0">
|
<div class="px-0 mx-0">
|
||||||
|
@ -9,7 +8,12 @@
|
||||||
</form>
|
</form>
|
||||||
<ul class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-4">
|
<ul class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-4">
|
||||||
<li v-for="movie in movies" class="p-1 movie-card">
|
<li v-for="movie in movies" class="p-1 movie-card">
|
||||||
<MoviePoster :image="movie.poster" @click="showModal(movie)" />
|
<img
|
||||||
|
:src="movie.poster"
|
||||||
|
alt="movie poster"
|
||||||
|
class="neon-border hover-pointer"
|
||||||
|
@click="showModal(movie)"
|
||||||
|
/>
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<h5 class="text-center">{{ movie.title }} ({{ movie.year }})</h5>
|
<h5 class="text-center">{{ movie.title }} ({{ movie.year }})</h5>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,9 +23,6 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { Movie } from "~/types/movie";
|
import type { Movie } from "~/types/movie";
|
||||||
import "lazysizes";
|
|
||||||
|
|
||||||
const loading = ref(false);
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "show-modal", movie: Movie): void;
|
(e: "show-modal", movie: Movie): void;
|
||||||
|
@ -35,7 +36,6 @@ const showModal = (movie: Movie) => {
|
||||||
const findMovies = async function (e: Event) {
|
const findMovies = async function (e: Event) {
|
||||||
let config = useRuntimeConfig();
|
let config = useRuntimeConfig();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
loading.value = true;
|
|
||||||
let searchTerm = (document.getElementById("search-field") as HTMLInputElement)
|
let searchTerm = (document.getElementById("search-field") as HTMLInputElement)
|
||||||
?.value;
|
?.value;
|
||||||
|
|
||||||
|
@ -43,27 +43,28 @@ const findMovies = async function (e: Event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fetch<Movie[]>(`${config.public.apiURL}/movies/search?q=${searchTerm}`, {
|
const { data, error } = await useFetch<Movie[]>(
|
||||||
method: "GET",
|
`${config.public.apiURL}/movies/search?q=${searchTerm}`,
|
||||||
headers: {
|
{
|
||||||
"Content-type": "application/json",
|
method: "GET",
|
||||||
Authorization: `Token ${useCookie("token").value}`,
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
Authorization: `Token ${useCookie("token").value}`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
);
|
||||||
.then((data) => {
|
|
||||||
movies.value = data;
|
if (error.value) {
|
||||||
loading.value = false;
|
if (error.value.statusCode === 401) {
|
||||||
})
|
alert("Unauthorized");
|
||||||
.catch((err) => {
|
}
|
||||||
if (err.statusCode === 401) {
|
} else {
|
||||||
navigateTo("/login");
|
if (!data.value) {
|
||||||
} else if (err.statusCode === 404) {
|
alert("No movies found.");
|
||||||
alert("No movies found");
|
} else {
|
||||||
loading.value = false;
|
movies.value = data.value || [];
|
||||||
} else {
|
}
|
||||||
alert("An error occurred. Please try again later.");
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="props.movie != null" class="sm:m-5 p-10 movie-card neon-border">
|
<div v-if="props.movie != null" class="sm:m-5 p-10 movie-card neon-border">
|
||||||
<div>
|
<div>
|
||||||
<h2 id="modal-title" class="row pb-10 text-center sm:text-left">
|
<h2 id="modal-title" class="row pb-3">
|
||||||
{{ movie.title }} ({{ movie.year }})
|
{{ movie.title }} ({{ movie.year }})
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="grid sm:grid-cols-2 gap-5">
|
<div class="grid sm:grid-cols-2">
|
||||||
<!-- MODAL POSTER -->
|
<!-- MODAL POSTER -->
|
||||||
<MoviePoster
|
<div class="text-end">
|
||||||
:image="movie.poster"
|
<img
|
||||||
class="max-h-72 max-w-60 sm:max-h-2xl sm:max-w-72 mx-auto sm:mx-0"
|
id="modal-poster"
|
||||||
/>
|
:src="movie.poster"
|
||||||
|
alt="poster"
|
||||||
|
class="pt-5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mx-auto sm:mx-none">
|
<div class="pt-5">
|
||||||
<label class="" for="list-picker">Add To List</label><br />
|
<label class="" for="list-picker">Add To List</label><br />
|
||||||
<select id="list-picker" v-model="list_id" class="p-1 text-black">
|
<select id="list-picker" v-model="list_id" class="p-1 text-black">
|
||||||
<option v-for="list in lists" :value="list.id">
|
<option v-for="list in lists" :value="list.id">
|
||||||
|
|
|
@ -1,32 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="sm:m-5 p-10 movie-card neon-border">
|
<div class="sm:m-5 p-10 movie-card neon-border">
|
||||||
<div>
|
<div>
|
||||||
<LoadingIcon v-if="updating" />
|
<h2 class="text-xl pb-3 text-center sm:text-left">
|
||||||
<h2 class="text-xl pb-10 text-center sm:text-left">
|
|
||||||
{{ movie.title }} ({{ movie.year }})
|
{{ movie.title }} ({{ movie.year }})
|
||||||
</h2>
|
</h2>
|
||||||
<div class="sm:inline-flex sm:space-x-5">
|
<div class="sm:inline-flex sm:space-x-5">
|
||||||
<MoviePoster
|
<img
|
||||||
:image="movie.poster"
|
:src="movie.poster"
|
||||||
class="max-h-80 max-w-60 mx-auto sm:mx-none"
|
alt="movie poster"
|
||||||
|
class="mx-auto sm:mx-0 neon-border"
|
||||||
/>
|
/>
|
||||||
<div class="pt-5 sm:pt-0">
|
<div class="pt-5 sm:pt-0">
|
||||||
<p>{{ movie.plot }}</p>
|
<p>{{ movie.plot }}</p>
|
||||||
|
|
||||||
<ScheduleMovie
|
<ScheduleMovie
|
||||||
v-if="logged_in"
|
v-if="logged_in"
|
||||||
:movie="movie"
|
:movie="movie"
|
||||||
class="mt-5"
|
class="mt-5"
|
||||||
@close-modal="$emit('close-modal')"
|
@close-modal="$emit('close-modal')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button
|
|
||||||
v-if="logged_in"
|
|
||||||
class="my-10 btn p-2 rounded"
|
|
||||||
@click="updateMovie"
|
|
||||||
>
|
|
||||||
Refresh movie
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,14 +27,10 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import ScheduleMovie from "~/components/forms/ScheduleMovie.vue";
|
import ScheduleMovie from "~/components/forms/ScheduleMovie.vue";
|
||||||
|
|
||||||
const props = defineProps(["movie", "updating"]);
|
const props = defineProps(["movie"]);
|
||||||
const emits = defineEmits(["close-modal", "update-movie"]);
|
const emits = defineEmits(["close-modal"]);
|
||||||
const logged_in = ref(false);
|
const logged_in = ref(false);
|
||||||
|
|
||||||
const updateMovie = function () {
|
|
||||||
emits("update-movie");
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const token = useCookie("token").value;
|
const token = useCookie("token").value;
|
||||||
if (token) {
|
if (token) {
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container mx-auto">
|
<div class="container mx-auto">
|
||||||
<Navbar />
|
<Navbar/>
|
||||||
<NuxtPage class="mb-32" />
|
<NuxtPage/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "default",
|
name: "default",
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -24,7 +24,7 @@ export default defineNuxtConfig({
|
||||||
|
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
public: {
|
public: {
|
||||||
apiURL: process.env.API_URL || "http://localhost:8000/v1",
|
apiURL: process.env.API_URL || "http://localhost:8000/api",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<LoadingIcon v-if="loading" show-quote="true" />
|
<div v-if="list_id !== 0" class="p-5 sm:p-0">
|
||||||
<div v-else class="p-5 sm:p-0">
|
|
||||||
<Modal ref="movie_modal">
|
<Modal ref="movie_modal">
|
||||||
<ShowMovie
|
<ShowMovie
|
||||||
v-if="modal_movie"
|
v-if="modal_movie"
|
||||||
:movie="modal_movie"
|
:movie="modal_movie"
|
||||||
:updating="updating"
|
|
||||||
@close-modal="closeModal"
|
@close-modal="closeModal"
|
||||||
@update-movie="updateMovie(modal_movie)"
|
|
||||||
></ShowMovie>
|
></ShowMovie>
|
||||||
</Modal>
|
</Modal>
|
||||||
<h2 class="text-xl font-bold pb-5">{{ list.name }}</h2>
|
<h2 class="text-xl font-bold pb-5">{{ list.name }}</h2>
|
||||||
<div
|
<div class="grid grid-cols-2 rounded movie-card neon-border p-5">
|
||||||
v-if="movies.length > 1 && !loading"
|
|
||||||
class="grid grid-cols-2 rounded movie-card neon-border p-5"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<ul class="flex flex-row">
|
<ul class="flex flex-row">
|
||||||
<li>
|
<li>
|
||||||
|
@ -37,27 +31,23 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="movies.length < 1 && !loading" class="mt-10 flex gap-5 flex-col">
|
|
||||||
No Movies Found
|
|
||||||
<MovieQuote />
|
|
||||||
</div>
|
|
||||||
<!-- MOVIE LIST -->
|
<!-- MOVIE LIST -->
|
||||||
<ul
|
<ul
|
||||||
v-else
|
|
||||||
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-2 mt-5"
|
class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-2 mt-5"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
v-for="movie in filtered_movies"
|
v-for="movie in filtered_movies"
|
||||||
:key="movie.poster"
|
:key="movie.id"
|
||||||
class="rounded movie-card neon-border flex flex-col overflow-hidden"
|
class="rounded movie-card neon-border"
|
||||||
>
|
>
|
||||||
<!-- POSTER -->
|
<!-- POSTER -->
|
||||||
<MoviePoster
|
<img
|
||||||
:image="movie.poster"
|
:data-src="movie.poster"
|
||||||
class="flex-shrink-0"
|
alt="movie poster"
|
||||||
|
class="lazyload p-3 movie-poster hover-pointer mx-auto"
|
||||||
@click="showModal(movie)"
|
@click="showModal(movie)"
|
||||||
/>
|
/>
|
||||||
<div class="p-5 flex flex-col justify-between flex-1">
|
<div class="p-5 flex flex-col">
|
||||||
<!-- TITLE -->
|
<!-- TITLE -->
|
||||||
<span class="font-bold text-center mb-1">{{ movie.title }}</span>
|
<span class="font-bold text-center mb-1">{{ movie.title }}</span>
|
||||||
<span
|
<span
|
||||||
|
@ -79,13 +69,9 @@ import "lazysizes";
|
||||||
import type { MovieList } from "~/types/movielist";
|
import type { MovieList } from "~/types/movielist";
|
||||||
import type { Movie } from "~/types/movie";
|
import type { Movie } from "~/types/movie";
|
||||||
import Modal from "~/components/Modal.vue";
|
import Modal from "~/components/Modal.vue";
|
||||||
import { useCookie } from "#app";
|
|
||||||
import { $fetch } from "ofetch";
|
|
||||||
import MoviePoster from "~/components/MoviePoster.vue";
|
|
||||||
|
|
||||||
const list_id = ref(0);
|
const list_id = ref(0);
|
||||||
const list = defineModel<MovieList>("movie_list", { default: [] });
|
const list = defineModel<MovieList>("movie_list", { default: [] });
|
||||||
const loading = ref(true);
|
|
||||||
const modal_movie: Ref<Movie | null> = ref(null);
|
const modal_movie: Ref<Movie | null> = ref(null);
|
||||||
const movies = defineModel<Movie[] | []>("movies", {
|
const movies = defineModel<Movie[] | []>("movies", {
|
||||||
default: [],
|
default: [],
|
||||||
|
@ -96,25 +82,18 @@ const logged_in = ref(false);
|
||||||
const hide_scheduled = ref(false);
|
const hide_scheduled = ref(false);
|
||||||
|
|
||||||
const getList = async function (list_id: number) {
|
const getList = async function (list_id: number) {
|
||||||
loading.value = true;
|
|
||||||
let config = useRuntimeConfig();
|
let config = useRuntimeConfig();
|
||||||
let headers: any = {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof useCookie("token").value !== "undefined") {
|
|
||||||
headers["Authorization"] = `Token ${useCookie("token").value}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fetch<MovieList>(`${config.public.apiURL}/lists/${list_id}`, {
|
$fetch<MovieList>(`${config.public.apiURL}/lists/${list_id}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: headers,
|
headers: {
|
||||||
|
"Content-type": "application/json",
|
||||||
|
Authorization: `Token ${useCookie("token").value}`,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
list.value = data;
|
list.value = data;
|
||||||
movies.value = data?.movies || [];
|
movies.value = data?.movies || [];
|
||||||
filtered_movies.value = movies.value;
|
filtered_movies.value = movies.value;
|
||||||
loading.value = false;
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (err.statusCode === 401) {
|
if (err.statusCode === 401) {
|
||||||
|
@ -128,9 +107,9 @@ const getList = async function (list_id: number) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideScheduled = function () {
|
const hideScheduled = function () {
|
||||||
if (hide_scheduled.value && movies.value.length > 0) {
|
if (hide_scheduled && movies.value.length > 0) {
|
||||||
let filtered = movies.value.filter((movie) => {
|
let filtered = movies.value.filter((movie) => {
|
||||||
return !movie.has_been_scheduled;
|
return movie.last_watched === null;
|
||||||
});
|
});
|
||||||
if (typeof filtered != "undefined") {
|
if (typeof filtered != "undefined") {
|
||||||
filtered_movies.value = filtered;
|
filtered_movies.value = filtered;
|
||||||
|
@ -179,38 +158,6 @@ const removeMovie = async function (movie_id: string) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updating = ref(false);
|
|
||||||
const updateMovie = async function (movie: Movie) {
|
|
||||||
let config = useRuntimeConfig();
|
|
||||||
updating.value = true;
|
|
||||||
|
|
||||||
$fetch<Movie>(`${config.public.apiURL}/movies/${movie.id}/`, {
|
|
||||||
method: "PUT",
|
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
Authorization: `Token ${useCookie("token").value}`,
|
|
||||||
},
|
|
||||||
body: JSON.stringify(movie),
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
modal_movie.value = data || [];
|
|
||||||
movies.value = movies.value.map((movie) => {
|
|
||||||
return movie.id === data.id ? data : movie;
|
|
||||||
});
|
|
||||||
filtered_movies.value = movies.value;
|
|
||||||
updating.value = false;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
if (err.statusCode === 401) {
|
|
||||||
navigateTo("/");
|
|
||||||
}
|
|
||||||
if (err.statusCode === 404) {
|
|
||||||
alert("Unable to update movie");
|
|
||||||
}
|
|
||||||
updating.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const filterMovies = function () {
|
const filterMovies = function () {
|
||||||
if (!movie_query) {
|
if (!movie_query) {
|
||||||
filtered_movies.value = movies.value;
|
filtered_movies.value = movies.value;
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="p-5 sm:p-0">
|
||||||
<LoadingIcon
|
<div v-if="lists.length < 1">
|
||||||
v-if="loading"
|
|
||||||
class="w-full p-5 sm:p-0 max-w-2xl"
|
|
||||||
show-quote="true"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div v-if="lists.length < 1 && !loading" class="flex flex-col gap-10">
|
|
||||||
<p>No lists found</p>
|
<p>No lists found</p>
|
||||||
<MovieQuote />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="grid grid-cols-2 gap-3 mt-5">
|
<ul class="grid grid-cols-2 gap-3 mt-5">
|
||||||
<li v-for="list in lists" class="movie-card neon-border p-5 rounded">
|
<li v-for="list in lists" class="movie-card neon-border p-5 rounded">
|
||||||
<div class="grid grid-rows-2 gap-3">
|
<div class="grid grid-rows-2 gap-3">
|
||||||
|
@ -29,10 +21,7 @@ import type { MovieList } from "~/types/movielist";
|
||||||
import { useCookie } from "#app";
|
import { useCookie } from "#app";
|
||||||
|
|
||||||
const lists = defineModel<MovieList[]>("movie_list", { default: [] });
|
const lists = defineModel<MovieList[]>("movie_list", { default: [] });
|
||||||
const loading = ref(true);
|
|
||||||
|
|
||||||
const updateLists = async function () {
|
const updateLists = async function () {
|
||||||
loading.value = true;
|
|
||||||
let config = useRuntimeConfig();
|
let config = useRuntimeConfig();
|
||||||
let headers: any = {
|
let headers: any = {
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
|
@ -48,7 +37,6 @@ const updateLists = async function () {
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
lists.value = data || [];
|
lists.value = data || [];
|
||||||
loading.value = false;
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (err.statusCode === 401) {
|
if (err.statusCode === 401) {
|
||||||
|
|
|
@ -1,19 +1,44 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="p-5 sm:p-0">
|
<div class="p-5 sm:p-0">
|
||||||
<LoadingIcon v-if="loading" show-quote="true" />
|
<div v-if="schedule && schedule?.showings.length < 1" class="p-5">
|
||||||
<div v-else>
|
<span>No Showings Found</span>
|
||||||
<div
|
</div>
|
||||||
v-if="schedule && schedule?.showings.length < 1 && !loading"
|
<ul class="flex flex-col gap-5">
|
||||||
class="p-5"
|
<li
|
||||||
|
v-for="showing in schedule?.showings"
|
||||||
|
class="p-5 movie-card neon-border"
|
||||||
>
|
>
|
||||||
<span>No Showings Found</span>
|
<div class="sm:grid grid-cols-2 lg:grid-cols-3">
|
||||||
<MovieQuote />
|
<img
|
||||||
</div>
|
:src="showing.movie.poster"
|
||||||
|
alt="Movie Poster"
|
||||||
|
class="mx-auto mb-5 sm:mb-0 sm:mx-0 neon-border bg-black schedule-poster"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="self-center text-left">
|
||||||
|
<h5 class="text-center sm:text-left mb-3 text-xl">
|
||||||
|
{{ showing.movie.title }}
|
||||||
|
</h5>
|
||||||
|
<h5 class="text-center sm:text-left mb-3">
|
||||||
|
{{ formatDate(showing.showtime) }}
|
||||||
|
</h5>
|
||||||
|
<span class="">{{ showing.movie.plot }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- PREVIOUS SHOWINGS -->
|
||||||
|
<div id="previous-showings" class="mt-5 list-group">
|
||||||
|
<span
|
||||||
|
class="block mb-5 hover-pointer underline"
|
||||||
|
@click="getSchedule(true)"
|
||||||
|
>
|
||||||
|
Previous Showings
|
||||||
|
</span>
|
||||||
|
<span id="loader" class="hidden">Loading...</span>
|
||||||
<ul class="flex flex-col gap-5">
|
<ul class="flex flex-col gap-5">
|
||||||
<li
|
<li v-for="showing in past_showings" class="p-5 movie-card neon-border">
|
||||||
v-for="showing in schedule?.showings"
|
|
||||||
class="p-5 movie-card neon-border"
|
|
||||||
>
|
|
||||||
<div class="sm:grid grid-cols-2 lg:grid-cols-3">
|
<div class="sm:grid grid-cols-2 lg:grid-cols-3">
|
||||||
<img
|
<img
|
||||||
:src="showing.movie.poster"
|
:src="showing.movie.poster"
|
||||||
|
@ -22,48 +47,13 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="self-center text-left">
|
<div class="self-center text-left">
|
||||||
<h5 class="text-center sm:text-left mb-3 text-xl">
|
<h5 class="text-xl mb-3">{{ showing.movie.title }}</h5>
|
||||||
{{ showing.movie.title }}
|
<h5 class="mb-3">{{ formatDate(showing.showtime) }}</h5>
|
||||||
</h5>
|
|
||||||
<h5 class="text-center sm:text-left mb-3">
|
|
||||||
{{ formatDate(showing.showtime) }}
|
|
||||||
</h5>
|
|
||||||
<span class="">{{ showing.movie.plot }}</span>
|
<span class="">{{ showing.movie.plot }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- PREVIOUS SHOWINGS -->
|
|
||||||
<LoadingIcon v-if="loadingPrevious" />
|
|
||||||
<div v-else id="previous-showings" class="p-5 mt-5 list-group">
|
|
||||||
<span
|
|
||||||
class="block mb-5 hover-pointer underline"
|
|
||||||
@click="getSchedule(true)"
|
|
||||||
>
|
|
||||||
Previous Showings
|
|
||||||
</span>
|
|
||||||
<ul class="flex flex-col gap-5">
|
|
||||||
<li
|
|
||||||
v-for="showing in past_showings"
|
|
||||||
class="p-5 movie-card neon-border"
|
|
||||||
>
|
|
||||||
<div class="sm:grid grid-cols-2 lg:grid-cols-3">
|
|
||||||
<img
|
|
||||||
:src="showing.movie.poster"
|
|
||||||
alt="Movie Poster"
|
|
||||||
class="mx-auto mb-5 sm:mb-0 sm:mx-0 neon-border bg-black schedule-poster"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="self-center text-left">
|
|
||||||
<h5 class="text-xl mb-3">{{ showing.movie.title }}</h5>
|
|
||||||
<h5 class="mb-3">{{ formatDate(showing.showtime) }}</h5>
|
|
||||||
<span class="">{{ showing.movie.plot }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -78,8 +68,6 @@ const schedule = defineModel<Schedule>("schedule");
|
||||||
const past_showings = defineModel<Showing[]>("past_showings", {
|
const past_showings = defineModel<Showing[]>("past_showings", {
|
||||||
default: [],
|
default: [],
|
||||||
});
|
});
|
||||||
const loading = ref(true);
|
|
||||||
const loadingPrevious = ref(false);
|
|
||||||
const got_previous = ref(false);
|
const got_previous = ref(false);
|
||||||
const months = [
|
const months = [
|
||||||
"January",
|
"January",
|
||||||
|
@ -104,28 +92,23 @@ const formatDate = function (date_string: string) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSchedule = async function (previous = false) {
|
const getSchedule = async function (previous = false) {
|
||||||
if (previous) loadingPrevious.value = true;
|
|
||||||
else loading.value = true;
|
|
||||||
|
|
||||||
let config = useRuntimeConfig();
|
let config = useRuntimeConfig();
|
||||||
if (got_previous.value) {
|
if (got_previous.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById("loader")?.classList.toggle("hidden");
|
||||||
|
|
||||||
let params = "";
|
let params = "";
|
||||||
if (previous) params = "?past_showings=true";
|
if (previous) params = "?past_showings=true";
|
||||||
|
|
||||||
let headers: any = {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof useCookie("token").value !== "undefined") {
|
|
||||||
headers["Authorization"] = `Token ${useCookie("token").value}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
await $fetch(`${config.public.apiURL}/schedules/1${params}`, {
|
await $fetch(`${config.public.apiURL}/schedules/1${params}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: headers,
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
"Content-type": "application/json",
|
||||||
|
Authorization: `Token ${useCookie("token").value}`,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (previous) {
|
if (previous) {
|
||||||
|
@ -133,8 +116,7 @@ const getSchedule = async function (previous = false) {
|
||||||
} else {
|
} else {
|
||||||
schedule.value = data;
|
schedule.value = data;
|
||||||
}
|
}
|
||||||
loading.value = false;
|
document.getElementById("loader")?.classList.toggle("hidden");
|
||||||
loadingPrevious.value = false;
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
switch (err.statusCode) {
|
switch (err.statusCode) {
|
||||||
|
@ -144,7 +126,6 @@ const getSchedule = async function (previous = false) {
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
alert("Unable to find schedule");
|
alert("Unable to find schedule");
|
||||||
navigateTo("/");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,5 +10,5 @@ export type Movie = {
|
||||||
actors: string;
|
actors: string;
|
||||||
plot: string;
|
plot: string;
|
||||||
poster: string;
|
poster: string;
|
||||||
has_been_scheduled: boolean;
|
last_watched: string;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue