Skip to content

Commit

Permalink
feat: try to provide a share scoresheet link
Browse files Browse the repository at this point in the history
  • Loading branch information
bdelbosc committed Jan 22, 2021
1 parent d624333 commit a2c143e
Show file tree
Hide file tree
Showing 9 changed files with 690 additions and 393 deletions.
847 changes: 513 additions & 334 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^7.0.0",
"standard-version": "^8.0.2",
"svelte": "^3.0.0"
"standard-version": "^9.1.0",
"svelte": "^3.0.0",
"svelte-calendar": "^2.0.4"
},
"dependencies": {
"jspdf": "^1.5.3",
Expand Down
35 changes: 7 additions & 28 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
import {OverallDto} from './js/Overall';
import {UserDto} from './js/User';
import {BeerDto} from './js/Beer';
import {PdfRenderer} from './js/PdfRenderer';
import pkg from '../package.json'
import Octocat from "./comp/Octocat.svelte";
import {fade} from 'svelte/transition';
import Guideline from "./comp/Guideline.svelte";
import {generatePdf} from "./js/PdfGenerator";
let visible = false;
Expand Down Expand Up @@ -140,39 +140,18 @@
let currentTab = 1;
function submit() {
let json = JSON.stringify({
let json = {
'user': user,
'beer': beer,
'aroma': aroma,
'appearance': appearance,
'flavor': flavor,
'mouthfeel': mouthfeel,
'overall': overall,
'start': start,
'score': totalScore,
'version': pkg.version
});
console.info("Generate PDF");
console.info(json);
let renderer = new PdfRenderer("BEER SCORESHEET", totalScore);
renderer.addMetdata(pkg.version, user.name, beer.entry, beer.category, json);
renderScoresheet(renderer);
let name = 'scoresheet-' + start.toISOString().slice(0, 10).replace(/-/g, "");
name += '-' + beer.entry.replace(/\W/g, '_');
name += '-' + beer.category.replace(/\W/g, '_');
name += '-' + user.name.replace(/\W/g, '_') + '.pdf';
renderer.produce(name);
}
function renderScoresheet(renderer) {
renderer.addVersion(pkg.version);
user.render(renderer, beer.tastingDate);
beer.render(renderer);
aroma.render(renderer);
appearance.render(renderer);
flavor.render(renderer);
mouthfeel.render(renderer);
overall.render(renderer, totalScore);
'version': pkg.version,
};
generatePdf(json);
}
function beerEdit() {
Expand Down Expand Up @@ -200,9 +179,9 @@
onMount(() => {
if (!user.isCompleted()) userEdit();
else if (!beer.isCompleted() || beer.isFromShareLink() || beer.isSelectedTab()) beerEdit();
else if (!beer.isCompleted() || beer.isFromSharedBeerEntry() || beer.isSelectedTab()) beerEdit();
else evaluationEdit();
if (!beer.isFromShareLink()) {
if (!beer.isFromSharedBeerEntry()) {
window.onbeforeunload = function () {
return "";
}
Expand Down
99 changes: 81 additions & 18 deletions src/Beer.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
<script>
import SelectCheck from "./comp/SelectCheck.svelte";
import {CATEGORY_OPTIONS} from './js/Beer';
import {BeerDto, CATEGORY_OPTIONS} from './js/Beer';
import SvgIcon from "./comp/SvgIcon.svelte";
import {beerIcon, trashIcon} from "./js/AppIcons";
import {parsePDF} from "./js/PdfRenderer";
import Tabs from "./comp/Tabs.svelte";
import {TextRenderer} from "./js/TextRenderer";
import pkg from "../package.json";
import {generatePdf} from "./js/PdfGenerator";
import {UserDto} from "./js/User";
import {AromaDto} from "./js/Aroma";
import {AppearanceDto} from "./js/Appearance";
import {MouthfeelDto} from "./js/Mouthfeel";
import {OverallDto} from "./js/Overall";
import {FlavorDto} from "./js/Flavor";
import Datepicker from 'svelte-calendar';
export let user;
export let beer;
Expand Down Expand Up @@ -90,14 +99,36 @@
}
}
function shareLink() {
let link = "http://beer-feedback.surge.sh/?"
link += "beerEntry=" + encodeURIComponent(beer.entry)
link += "&beerCategory=" + encodeURIComponent(beer.category)
link += "&beerSpecial=" + encodeURIComponent(beer.special)
link += "&beerComment=" + encodeURIComponent(beer.comment)
console.info("Copying link: " + link);
let input = document.getElementById("sharedLink");
function shareEntryLink() {
let link = "https://beer-feedback.surge.sh/?";
link += "beerEntry=" + encodeURIComponent(beer.entry);
link += "&beerCategory=" + encodeURIComponent(beer.category);
link += "&beerSpecial=" + encodeURIComponent(beer.special);
link += "&beerComment=" + encodeURIComponent(beer.comment);
console.info("Copying entry link: " + link);
let input = document.getElementById("sharedEntryLink");
input.value = link;
input.select();
input.setSelectionRange(0, 99999);
document.execCommand("copy");
}
function shareScoresheetLink() {
let link = "https://beer-feedback.surge.sh/?"
let json = JSON.stringify({
'user': user,
'beer': beer,
'aroma': aroma,
'appearance': appearance,
'flavor': flavor,
'mouthfeel': mouthfeel,
'overall': overall,
'score': totalScore,
'version': pkg.version
});
link += "renderPdf=" + encodeURIComponent(json);
console.info("Copying score link: " + link);
let input = document.getElementById("sharedScoresheetLink");
input.value = link;
input.select();
input.setSelectionRange(0, 99999);
Expand Down Expand Up @@ -128,8 +159,8 @@
}
function checkShareLinkAndRedirect(theUser) {
console.info("checkShareLink");
if (beer.isFromShareLink() && theUser.isCompleted()) {
console.info("Check for shared link");
if (beer.isFromSharedBeerEntry() && theUser.isCompleted()) {
if (resetData("Make sure you have generated a PDF of your current Scoresheet before starting a new Beer Entry")) {
beer.loadFromShareLink();
aroma.save();
Expand All @@ -139,6 +170,33 @@
overall.save();
}
window.location.href = "/?tab=beer";
} else if (beer.isFromSharedScoresheet()) {
const params = new URLSearchParams(window.location.search);
if (params.has("renderPdf")) {
let json = JSON.parse(unescape(params.get("renderPdf")));
let pdfJson = {};
pdfJson.user = new UserDto();
pdfJson.beer = new BeerDto();
pdfJson.aroma = new AromaDto();
pdfJson.appearance = new AppearanceDto();
pdfJson.flavor = new FlavorDto();
pdfJson.mouthfeel = new MouthfeelDto();
pdfJson.overall = new OverallDto();
pdfJson.user.load(json.user);
pdfJson.beer.load(json.beer);
pdfJson.aroma.load(json.aroma);
pdfJson.appearance.load(json.appearance);
pdfJson.flavor.load(json.flavor);
pdfJson.mouthfeel.load(json.mouthfeel);
pdfJson.overall.load(json.overall);
pdfJson.score = json.score;
generatePdf(pdfJson).then(() => {
alert("You have a new Scoresheet in your Download folder!");
window.location.href = "/"
}
, () => alert("PDF generation failure"));
}
}
}
Expand Down Expand Up @@ -166,7 +224,7 @@
<Tabs bind:activeTabValue={currentTab} items={tabItems}/>
{#if 1 === currentTab}
<div>
<SelectCheck on:change={updateHandler} bind:value={beer.category} options={CATEGORY_OPTIONS} noCheck="true" required="true">
<SelectCheck bind:value={beer.category} options={CATEGORY_OPTIONS} noCheck="true" required="true">
Category
</SelectCheck>
</div>
Expand All @@ -183,7 +241,9 @@

<div>
<span class="label">Tasting date</span>
<input type="text" class="fixedInput" on:change={updateHandler} bind:value={beer.tastingDate}/>
<Datepicker bind:selected={beer._tastingDate} bind:dateChosen={beer.updated}>
<button class="fixedInput">{beer.tastingDate}</button>
</Datepicker>
</div>

<div>
Expand All @@ -207,16 +267,19 @@

{:else if 3 === currentTab}
<div>
<p class="help">Share the beer entry description with other judges, copying the following link:</p>
<input type="text" value="..." id="sharedLink"/>
<button on:click={() => shareLink()}>Copy</button>
<p class="help">Share this <b>Beer Entry</b> with other judges, copying the following link:</p>
<input type="text" value="..." id="sharedEntryLink"/>
<button disabled={!beer.isCompleted()} on:click={() => shareEntryLink()}>Copy</button>

<p class="help">Note that if you want to share the Scoresheet itself, you have to generate a PDF</p>
<p class="help">Share your <b>Scoresheet</b>, copying the following link:</p>
<input type="text" value="..." id="sharedScoresheetLink"/>
<button disabled={!beer.isCompleted()} on:click={() => shareScoresheetLink()}>Copy</button>
<p class="help">Because the link contains the Scoresheet data it can be very long and may not work everywhere.</p>
</div>
{:else if 4 === currentTab}
<div>
<p class="help">Generate a text Scoresheet</p>
<textarea type="text" value="..." id="exportText"/>
<button on:click={() => exportText()}>Export as Text</button>
<button disabled={!beer.isCompleted()} on:click={() => exportText()}>Export as Text</button>
</div>
{/if}
5 changes: 5 additions & 0 deletions src/User.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
}
</style>

{#if !user.name}
<h2>Welcome to <a href="https://github.com/bdelbosc/beer-feedback#-beer-feedback" rel="noopener" target="_blank">Beer
Feedback</a>!</h2>
{/if}

<h3>
<SvgIcon d={userIcon} fill="blue" boxSize="20"/>
Who are you?
Expand Down
40 changes: 32 additions & 8 deletions src/js/Beer.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,20 @@ const CATEGORY_OPTIONS = [
];

function today() {
const today = new Date();
return today.toLocaleDateString();
const d = new Date();
return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, '0') + "-" + String(d.getDate()).padStart(2, '0');
}

function stringAsDate(s) {
const dateParts = s.split("-");
if (dateParts.length >=3)
return new Date(dateParts[0], dateParts[1]-1, dateParts[2]);
console.error("Invalid tasting date: " + s + " fall back to today")
return new Date();
}

function dateAsString(d) {
return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, '0') + "-" + String(d.getDate()).padStart(2, '0');
}

class Beer extends BaseCategory {
Expand All @@ -145,6 +157,7 @@ class Beer extends BaseCategory {
this.special = this.getValue('beerSpecial', '');
this.comment = this.getValue('beerComment', '');
this.tastingDate = this.getValue('beerTastingDate', today());
this._tastingDate = stringAsDate(this.tastingDate);
console.log("entry: " + this.entry);
if (this.entry === undefined) console.log("Entry undefined!");
}
Expand All @@ -154,6 +167,7 @@ class Beer extends BaseCategory {
this.comment = '';
this.special = '';
this.tastingDate = today();
this._tastingDate = stringAsDate(this.tastingDate);
}

load(json) {
Expand All @@ -163,6 +177,7 @@ class Beer extends BaseCategory {
this.comment = json.comment;
if (json.tastingDate)
this.tastingDate = json.tastingDate;
this._tastingDate = null;
this.updateHandler();
}

Expand All @@ -186,15 +201,18 @@ class Beer extends BaseCategory {
this.completed = (this.required.length === 0);
}

updateHandler(sort = false) {
updateHandler() {
super.updateHandler();
if (sort) {
this.flavors.sort(compareCategory);
}
if (this._tastingDate)
this.tastingDate = dateAsString(this._tastingDate);
else if (this.tastingDate)
this._tastingDate = stringAsDate(this.tastingDate);
}

save() {
console.info("Saving beer");
if (this._tastingDate)
this.tastingDate = dateAsString(this._tastingDate);
if (this.entry)
localStorage.setItem('beerEntry', this.entry);
else
Expand Down Expand Up @@ -230,21 +248,27 @@ class Beer extends BaseCategory {
return defaultValue;
}

isFromShareLink() {
isFromSharedBeerEntry() {
const params = new URLSearchParams(window.location.search);
if (params.has("beerCategory"))
return true;
return false;
}

isFromSharedScoresheet() {
const params = new URLSearchParams(window.location.search);
if (params.has("renderPdf"))
return true;
return false;
}

isSelectedTab() {
const params = new URLSearchParams(window.location.search);
if (params.has("tab") && params.get("tab") == "beer")
return true;
return false;
}


loadFromShareLink() {
const params = new URLSearchParams(window.location.search);
if (params.has("beerEntry"))
Expand Down
32 changes: 32 additions & 0 deletions src/js/PdfGenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {PdfRenderer} from "./PdfRenderer";
import pkg from "../../package.json";

function generatePdf(json) {
let jsonString = JSON.stringify(json);
console.info("Generate PDF");
console.info(json);
let renderer = new PdfRenderer("BEER SCORESHEET", json.score);
renderer.addMetdata(pkg.version, json.user.name, json.beer.entry, json.beer.category, jsonString);
renderScoresheet(renderer, json);
// let name = 'scoresheet-' + json.beer.tastingDate.toISOString().slice(0, 10).replace(/-/g, "");
let name = 'scoresheet-' + json.beer.tastingDate.replace(/-/g, "");
name += '-' + json.beer.entry.replace(/\W/g, '_');
name += '-' + json.beer.category.replace(/\W/g, '_');
name += '-' + json.user.name.replace(/\W/g, '_') + '.pdf';
console.info("Produce PDF " + name);
return renderer.produce(name);
}

function renderScoresheet(renderer, json) {
renderer.addVersion(pkg.version);
json.user.render(renderer, json.beer.tastingDate);
json.beer.render(renderer);
json.aroma.render(renderer);
json.appearance.render(renderer);
json.flavor.render(renderer);
json.mouthfeel.render(renderer);
json.overall.render(renderer, json.score);
}


export {generatePdf}
Loading

0 comments on commit a2c143e

Please sign in to comment.