mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 05:14:23 +00:00
android app progress + polls plugin
This commit is contained in:
@@ -38,6 +38,7 @@ dependencies {
|
||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||
implementation("com.google.android.material:material:1.8.0")
|
||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
||||
implementation("com.journeyapps:zxing-android-embedded:4.2.0")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||
|
||||
@@ -22,5 +22,7 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="true" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
</manifest>
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.janishutz.libreevent
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
@@ -9,5 +10,14 @@ class MainActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
val loginButton = findViewById<Button>(R.id.loginButton)
|
||||
loginButton.setOnClickListener {
|
||||
login()
|
||||
}
|
||||
}
|
||||
|
||||
private fun login() {
|
||||
val switchIntent = Intent(this, ScanActivity::class.java)
|
||||
startActivity(switchIntent)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,67 @@
|
||||
package com.janishutz.libreevent
|
||||
|
||||
class ScannerActivity {
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import androidx.core.app.ActivityCompat
|
||||
import com.journeyapps.barcodescanner.CaptureManager
|
||||
import com.journeyapps.barcodescanner.DecoratedBarcodeView
|
||||
|
||||
class ScanActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var barcodeView: DecoratedBarcodeView
|
||||
private lateinit var captureManager: CaptureManager
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_scanner)
|
||||
|
||||
barcodeView = findViewById(R.id.barcodeScannerView)
|
||||
|
||||
// Check for camera permission and request if not granted
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), CAMERA_PERMISSION_REQUEST)
|
||||
} else {
|
||||
setupScanner()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupScanner() {
|
||||
captureManager = CaptureManager(this, barcodeView)
|
||||
|
||||
captureManager.initializeFromIntent(intent, null)
|
||||
captureManager.decode()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
captureManager.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
captureManager.onPause()
|
||||
}
|
||||
|
||||
// Pass savedInstanceState to onSaveInstanceState
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
captureManager.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
if (requestCode == CAMERA_PERMISSION_REQUEST) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
setupScanner()
|
||||
} else {
|
||||
// Handle permission denied
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CAMERA_PERMISSION_REQUEST = 1
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<com.journeyapps.barcodescanner.DecoratedBarcodeView
|
||||
android:id="@+id/barcodeScannerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
47
src/server/backend/plugins/others/poll/css/popup.css
Normal file
47
src/server/backend/plugins/others/poll/css/popup.css
Normal file
@@ -0,0 +1,47 @@
|
||||
#popup, #popup-data {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
background-color: rgba( 0, 0, 0, 0.5 );
|
||||
}
|
||||
|
||||
.popup-positioning {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.submit {
|
||||
margin-top: 2%;
|
||||
background: linear-gradient(90deg, rgb(30, 36, 131), rgb(87, 66, 184), rgb(105, 115, 214), rgb(30, 36, 131), rgb(41, 128, 109), rgb(146, 50, 47));
|
||||
background-size: 300px;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
transition: all 3s;
|
||||
font-size: 75%;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.submit:hover {
|
||||
background-size: 200%;
|
||||
background-position: -100%;
|
||||
}
|
||||
|
||||
.popup-main {
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
padding: 5%;
|
||||
background-color: rgb(34, 34, 34);
|
||||
color: white;
|
||||
max-width: 70%;
|
||||
max-height: 70%;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
57
src/server/backend/plugins/others/poll/css/style.css
Normal file
57
src/server/backend/plugins/others/poll/css/style.css
Normal file
@@ -0,0 +1,57 @@
|
||||
html {
|
||||
height: 98%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: monospace;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.title-area {
|
||||
font-size: 1000%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.title-area h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-style: italic;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 70%;
|
||||
height: 40%;
|
||||
font-size: 150%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
width: 100%;
|
||||
padding: 2%;
|
||||
border-radius: 10px;
|
||||
resize: vertical;
|
||||
font-size: 90%;
|
||||
}
|
||||
1
src/server/backend/plugins/others/poll/data/voting.json
Normal file
1
src/server/backend/plugins/others/poll/data/voting.json
Normal file
@@ -0,0 +1 @@
|
||||
{"test":{"1":{"title":"test","comment":"test","id":1,"count":3}}}
|
||||
@@ -0,0 +1 @@
|
||||
{"test":{"allowAdding":true,"display":"test","id":"test","comment":"test2"}}
|
||||
108
src/server/backend/plugins/others/poll/html/settings.html
Normal file
108
src/server/backend/plugins/others/poll/html/settings.html
Normal file
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=7">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Settings - Polls :: libreevent-plugin</title>
|
||||
<link rel="stylesheet" href="/polls/css/style.css">
|
||||
<link rel="stylesheet" href="/polls/css/popup.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 24
|
||||
}
|
||||
|
||||
.voting-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.voting {
|
||||
border-radius: 500px;
|
||||
border: 1px black solid;
|
||||
font-size: 150%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.voting-counter {
|
||||
margin: 0;
|
||||
font-size: 150%;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 30vw;
|
||||
padding: 20px;
|
||||
border-radius: 20px;
|
||||
border: none;
|
||||
margin-bottom: 1vh;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.poll {
|
||||
border: black 2px solid;
|
||||
padding: 1% 10%;
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content" id="app">
|
||||
<h1>Polls plugin - Settings</h1>
|
||||
<div style="margin-bottom: 1%;">
|
||||
<a href="/admin/plugins">Back to the admin panel</a><br>
|
||||
<button @click="addPoll();">Add new poll</button>
|
||||
</div>
|
||||
<div v-for="poll in polls" class="poll">
|
||||
<h3>{{ poll.display }}</h3>
|
||||
<p>{{ poll.comment }}</p>
|
||||
<button @click="editPoll( poll.id )">Edit</button>
|
||||
</div>
|
||||
<div id="popup">
|
||||
<div class="popup-positioning">
|
||||
<div class="popup-main">
|
||||
<form id="popup-message">
|
||||
<h2 style="font-size: 200%;">{{ operation }} poll</h2>
|
||||
<label for="title">Poll title</label><br>
|
||||
<input type="text" v-model="newPoll.display" name="title" id="title" class="input"><br>
|
||||
<label for="id">Poll id</label><br>
|
||||
<input type="text" v-model="newPoll.id" name="id" id="id" class="input"><br>
|
||||
<label for="comment">Comments</label><br>
|
||||
<textarea type="text" v-model="newPoll.comment" name="comment" id="comment" class="input" rows="5"></textarea><br>
|
||||
<label for="id">Allow adding suggestions</label>
|
||||
<input type="checkbox" v-model="newPoll.allowAdding" name="allowAdding" id="allowAdding"><br>
|
||||
</form>
|
||||
<button @click="save()" class="submit">Save</button>
|
||||
<button @click="closePopup()" class="submit">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
|
||||
<script src="/polls/js/settings.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
114
src/server/backend/plugins/others/poll/html/voting.html
Normal file
114
src/server/backend/plugins/others/poll/html/voting.html
Normal file
@@ -0,0 +1,114 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=7">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Polls :: libreevent-plugin</title>
|
||||
<link rel="stylesheet" href="/polls/css/style.css">
|
||||
<link rel="stylesheet" href="/polls/css/popup.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
||||
<style>
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 24
|
||||
}
|
||||
|
||||
.voting-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.voting {
|
||||
border-radius: 500px;
|
||||
border: 1px black solid;
|
||||
font-size: 150%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.voting-counter {
|
||||
margin: 0;
|
||||
font-size: 150%;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 30vw;
|
||||
padding: 20px;
|
||||
border-radius: 20px;
|
||||
border: none;
|
||||
margin-bottom: 1vh;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.entry {
|
||||
border: black 2px solid;
|
||||
padding: 1% 10%;
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content" id="app">
|
||||
<div v-if="votingDetails.display">
|
||||
<h1>Voting on {{ votingDetails.display ?? 'untitled' }}</h1>
|
||||
<p v-if="votingDetails.description">{{ votingDetails.description }}</p>
|
||||
<div style="margin-bottom: 1%;" v-if="votingDetails.allowAdding">
|
||||
<button onclick="location.href = '/'">Back to website</button>
|
||||
<button @click="addSuggestion();">Add suggestion</button>
|
||||
</div>
|
||||
<div v-for="entry in entries" class="entry">
|
||||
<h3>{{ entry.title }}</h3>
|
||||
<p>{{ entry.comment }}</p>
|
||||
<div class="voting-wrapper">
|
||||
<span class="material-symbols-outlined voting" @click="vote( 'up', entry.id )" :class="votedOn[ entry.id ] === 'up' ? 'selected' : ''">arrow_upward</span>
|
||||
<p class="voting-counter">{{ entry.count ?? 0 }}</p>
|
||||
<span class="material-symbols-outlined voting" @click="vote( 'down', entry.id )" :class="votedOn[ entry.id ] === 'down' ? 'selected' : ''">arrow_downward</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="popup">
|
||||
<div class="popup-positioning">
|
||||
<div class="popup-main">
|
||||
<form id="popup-message">
|
||||
<h2 style="font-size: 200%;">Add new suggestion</h2>
|
||||
<label for="title">Suggestion title</label><br>
|
||||
<input type="text" v-model="newSuggestion.title" name="title" id="title" class="input"><br>
|
||||
<label for="title">Comments</label><br>
|
||||
<textarea type="text" v-model="newSuggestion.comment" name="comment" id="comment" class="input" rows="5"></textarea><br>
|
||||
</form>
|
||||
<button @click="save()" class="submit">Add</button>
|
||||
<button @click="closePopup()" class="submit">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else style="display: flex; justify-content: center; align-items: center; height: 100vh; font-size: 110%;">
|
||||
<h1>This poll does not exist!</h1>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
|
||||
<script src="/polls/js/voting.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
63
src/server/backend/plugins/others/poll/js/settings.js
Normal file
63
src/server/backend/plugins/others/poll/js/settings.js
Normal file
@@ -0,0 +1,63 @@
|
||||
const { createApp } = Vue;
|
||||
|
||||
createApp( {
|
||||
data() {
|
||||
return {
|
||||
polls: {},
|
||||
newPoll: {},
|
||||
operation: 'Add new',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
fetch( '/admin/plugins/polls/getData' ).then( response => {
|
||||
response.json().then( data => {
|
||||
this.polls = data;
|
||||
this.newPoll = {};
|
||||
} );
|
||||
} );
|
||||
},
|
||||
save() {
|
||||
if ( this.newPoll.comment && this.newPoll.display && this.newPoll.id ) {
|
||||
this.polls[ this.newPoll.id ] = this.newPoll;
|
||||
let fetchOptions = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( this.polls ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
},
|
||||
};
|
||||
fetch( '/admin/plugins/polls/save', fetchOptions ).then( response => {
|
||||
if ( response.status !== 200 ) {
|
||||
alert( 'there was an error updating' );
|
||||
}
|
||||
} );
|
||||
this.closePopup();
|
||||
this.getData();
|
||||
} else {
|
||||
alert( 'Not all required fields are filled out!' );
|
||||
}
|
||||
},
|
||||
closePopup() {
|
||||
$( '#popup' ).fadeOut( 500 );
|
||||
$( 'body' ).removeClass( 'menuOpen' );
|
||||
this.getData();
|
||||
},
|
||||
addPoll () {
|
||||
this.newPoll = { 'allowAdding': true };
|
||||
this.operation = 'Add new';
|
||||
$( '#popup' ).fadeIn( 500 );
|
||||
$( 'body' ).addClass( 'menuOpen' );
|
||||
},
|
||||
editPoll ( pollID ) {
|
||||
this.operation = 'Edit';
|
||||
this.newPoll = this.polls[ pollID ];
|
||||
$( '#popup' ).fadeIn( 500 );
|
||||
$( 'body' ).addClass( 'menuOpen' );
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getData();
|
||||
}
|
||||
} ).mount( '#app' );
|
||||
91
src/server/backend/plugins/others/poll/js/voting.js
Normal file
91
src/server/backend/plugins/others/poll/js/voting.js
Normal file
@@ -0,0 +1,91 @@
|
||||
const { createApp } = Vue;
|
||||
|
||||
createApp( {
|
||||
data() {
|
||||
return {
|
||||
entries: {},
|
||||
newSuggestion: {},
|
||||
votingDetails: {},
|
||||
votedOn: {},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
fetch( '/polls/get/' + location.pathname.substring( 7 ) ).then( response => {
|
||||
response.json().then( data => {
|
||||
this.entries = data;
|
||||
} );
|
||||
} );
|
||||
fetch( '/polls/getDetails/' + location.pathname.substring( 7 ) ).then( response => {
|
||||
response.json().then( data => {
|
||||
this.votingDetails = data;
|
||||
} );
|
||||
} );
|
||||
this.votedOn = JSON.parse( localStorage.getItem( 'itemsVotedOn' ) ?? '{}' );
|
||||
},
|
||||
save() {
|
||||
if ( this.newSuggestion.comment && this.newSuggestion.title ) {
|
||||
let fetchOptions = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( this.newSuggestion ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
},
|
||||
};
|
||||
fetch( '/polls/add/' + location.pathname.substring( 7 ), fetchOptions ).then( response => {
|
||||
if ( response.status !== 200 ) {
|
||||
alert( 'there was an error updating' );
|
||||
}
|
||||
} );
|
||||
this.closePopup();
|
||||
this.getData();
|
||||
} else {
|
||||
alert( 'Not all required fields are filled out!' );
|
||||
}
|
||||
},
|
||||
vote( type, suggestionID ) {
|
||||
let voteType = type;
|
||||
let didDeactivate = false;
|
||||
if ( this.votedOn[ suggestionID ] === type ) {
|
||||
didDeactivate = true;
|
||||
if ( type === 'up' ) {
|
||||
voteType = 'down';
|
||||
} else {
|
||||
voteType = 'up';
|
||||
}
|
||||
} else if ( this.votedOn[ suggestionID ] ) {
|
||||
return;
|
||||
}
|
||||
let fetchOptions = {
|
||||
method: 'post',
|
||||
body: JSON.stringify( { 'voteType': voteType, 'id': suggestionID } ),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'charset': 'utf-8'
|
||||
},
|
||||
};
|
||||
fetch( '/polls/vote/' + location.pathname.substring( 7 ), fetchOptions ).then( response => {
|
||||
if ( response.status !== 200 ) {
|
||||
alert( 'there was an error updating' );
|
||||
} else {
|
||||
this.votedOn[ suggestionID ] = didDeactivate ? undefined : voteType;
|
||||
localStorage.setItem( 'itemsVotedOn', JSON.stringify( this.votedOn ) );
|
||||
this.getData();
|
||||
}
|
||||
} );
|
||||
},
|
||||
closePopup() {
|
||||
$( '#popup' ).fadeOut( 500 );
|
||||
$( 'body' ).removeClass( 'menuOpen' );
|
||||
this.getData();
|
||||
},
|
||||
addSuggestion () {
|
||||
$( '#popup' ).fadeIn( 500 );
|
||||
$( 'body' ).addClass( 'menuOpen' );
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getData();
|
||||
}
|
||||
} ).mount( '#app' );
|
||||
@@ -6,8 +6,8 @@
|
||||
"pluginWebsite": "https://libreevent.janishutz.com/plugins/polls",
|
||||
"pluginDocs": "https://libreevent.janishutz.com/docs/plugins/polls",
|
||||
"gitURL": "https://github.com/simplePCBuilding/libreevent/tree/master/src/server/backend/plugins/others/poll",
|
||||
"settingsURL": "/admin/plugins/polls/settings",
|
||||
"mainPluginURL": "/polls",
|
||||
"settingsURL": "/admin/plugins/polls",
|
||||
"mainPluginURL": "/voting",
|
||||
"logo": "",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@@ -7,6 +7,99 @@
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = ( app, settings ) => {
|
||||
const path = require( 'path' );
|
||||
const fs = require( 'fs' );
|
||||
const bodyParser = require( 'body-parser' );
|
||||
|
||||
module.exports = ( app ) => {
|
||||
app.get( '/polls/:vote', ( req, res ) => {
|
||||
res.sendFile( path.join( __dirname + '/html/voting.html' ) );
|
||||
} );
|
||||
|
||||
app.get( '/polls/css/:file', ( req, res ) => {
|
||||
res.sendFile( path.join( __dirname + '/css/' + req.params.file ) );
|
||||
} );
|
||||
|
||||
app.get( '/polls/js/:file', ( req, res ) => {
|
||||
res.sendFile( path.join( __dirname + '/js/' + req.params.file ) );
|
||||
} );
|
||||
|
||||
app.get( '/polls/getDetails/:vote', ( req, res ) => {
|
||||
fs.readFile( path.join( __dirname + '/data/votingSettings.json' ), ( error, filedata ) => {
|
||||
res.send( JSON.parse( filedata )[ req.params.vote ] ?? {} );
|
||||
} );
|
||||
} );
|
||||
|
||||
app.get( '/polls/get/:vote', ( req, res ) => {
|
||||
fs.readFile( path.join( __dirname + '/data/voting.json' ), ( error, filedata ) => {
|
||||
res.send( JSON.parse( filedata )[ req.params.vote ] ?? {} );
|
||||
} );
|
||||
} );
|
||||
|
||||
app.post( '/polls/vote/:vote/', bodyParser.json(), ( req, res ) => {
|
||||
// up / down-voting
|
||||
fs.readFile( path.join( __dirname + '/data/voting.json' ), ( error, filedata ) => {
|
||||
let json = JSON.parse( filedata );
|
||||
if ( json[ req.params.vote ] ) {
|
||||
if ( req.body.voteType === 'up' ) {
|
||||
json[ req.params.vote ][ req.body.id ].count += 1;
|
||||
} else if ( req.body.voteType === 'down' ) {
|
||||
json[ req.params.vote ][ req.body.id ].count -= 1;
|
||||
}
|
||||
fs.writeFile( path.join( __dirname + '/data/voting.json' ), JSON.stringify( json ), ( err ) => {
|
||||
if ( err ) res.status( 500 ).send( 'ERR_VOTING' );
|
||||
res.send( 'ok' );
|
||||
} );
|
||||
} else {
|
||||
res.status( 404 ).send( 'ok' );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
app.post( '/polls/add/:vote', bodyParser.json(), ( req, res ) => {
|
||||
let data = req.body;
|
||||
if ( data.title && data.comment ) {
|
||||
fs.readFile( path.join( __dirname + '/data/voting.json' ), ( error, filedata ) => {
|
||||
let file = JSON.parse( filedata );
|
||||
if ( !file[ req.params.vote ] ) {
|
||||
file[ req.params.vote ] = {};
|
||||
}
|
||||
const id = parseInt( Object.keys( file[ req.params.vote ] )[ Object.keys( file[ req.params.vote ] ).length - 1 ] ?? 0 ) + 1;
|
||||
file[ req.params.vote ][ id ] = data;
|
||||
file[ req.params.vote ][ id ][ 'id' ] = id;
|
||||
file[ req.params.vote ][ id ][ 'count' ] = 1;
|
||||
fs.writeFile( path.join( __dirname + '/data/voting.json' ), JSON.stringify( file ), ( error ) => {
|
||||
if ( error ) console.error( 'failed to write data', file );
|
||||
res.send( 'ok' );
|
||||
} );
|
||||
} );
|
||||
} else {
|
||||
res.status( 400 ).send( 'incomplete' );
|
||||
}
|
||||
} );
|
||||
|
||||
app.get( '/admin/plugins/polls', ( req, res ) => {
|
||||
if ( req.session.loggedInAdmin ) {
|
||||
res.sendFile( path.join( __dirname + '/html/settings.html' ) );
|
||||
} else {
|
||||
res.status( 403 ).send( 'unauthorized' );
|
||||
}
|
||||
} );
|
||||
|
||||
app.get( '/admin/plugins/polls/getData', ( req, res ) => {
|
||||
if ( req.session.loggedInAdmin ) {
|
||||
res.sendFile( path.join( __dirname + '/data/votingSettings.json' ) );
|
||||
} else {
|
||||
res.status( 403 ).send( 'unauthorized' );
|
||||
}
|
||||
} );
|
||||
|
||||
app.post( '/admin/plugins/polls/save', bodyParser.json(), ( req, res ) => {
|
||||
if ( req.session.loggedInAdmin ) {
|
||||
fs.writeFileSync( path.join( __dirname + '/data/votingSettings.json' ), JSON.stringify( req.body ) );
|
||||
res.send( 'ok' );
|
||||
} else {
|
||||
res.status( 403 ).send( 'unauthorized' );
|
||||
}
|
||||
} );
|
||||
};
|
||||
Reference in New Issue
Block a user