diff --git a/admin/dist/index.html b/admin/dist/index.html index 5896d74c2..25afd2ade 100644 --- a/admin/dist/index.html +++ b/admin/dist/index.html @@ -1,9 +1,9 @@ - - - - Makeradmin - Stockholm Makerspace + + + + Makeradmin v1.0 - Odense Makerspace - - - - Medlemssidor v0.1 - Stockholm Makerspace + + + + Memberpage v0.1 - Odense Makerspace ); })} - + ); } diff --git a/admin/src/Components/CollectionTable.js b/admin/src/Components/CollectionTable.js index df86b2107..bcffd44d3 100644 --- a/admin/src/Components/CollectionTable.js +++ b/admin/src/Components/CollectionTable.js @@ -168,18 +168,12 @@ export default class CollectionTable extends React.Component { {rows} - {loading ? ( -
-
- - {" "} - Hämtar data... - -
-
- ) : ( - "" - )} + {loading ? +
+
+ Retrieving data... +
+
: ''} {pagination} diff --git a/admin/src/Components/Currency.jsx b/admin/src/Components/Currency.jsx index a0f24f901..a0d5d509a 100644 --- a/admin/src/Components/Currency.jsx +++ b/admin/src/Components/Currency.jsx @@ -1,7 +1,7 @@ import React from "react"; const Currency = (props) => { - const formatter = new Intl.NumberFormat("sv-SE", { + const formatter = new Intl.NumberFormat('da-DK', { // style: 'currency', // currency: 'SEK', minimumFractionDigits: 2, diff --git a/admin/src/Components/FileInput.jsx b/admin/src/Components/FileInput.jsx index bd08ce26b..2c2704fea 100644 --- a/admin/src/Components/FileInput.jsx +++ b/admin/src/Components/FileInput.jsx @@ -105,36 +105,19 @@ module.exports = class FileInput extends React.Component { this.state.model.set(this.props.name, event.target.value); } */ - render() { - return ( -
-
-

- - {this.state.filename ? ( - - {this.state.filename} ( - - Ta bort - - ) - - ) : ( - - Ladda upp genom att dra och släppa en fil här - eller klicka på{" "} - - ladda upp - - - . - - )} -

+ render() + { + return ( +
+
+

+ + {this.state.filename ? + {this.state.filename} (Delete) + : + Upload by dragging and dropping a file here or click upload. + } +

{this.state.progressbarVisible ? (
diff --git a/admin/src/Components/GroupForm.js b/admin/src/Components/GroupForm.js index 99e4d74e2..ecb47dc62 100644 --- a/admin/src/Components/GroupForm.js +++ b/admin/src/Components/GroupForm.js @@ -1,6 +1,6 @@ import React from "react"; -import TextInput from "./TextInput"; import { withRouter } from "react-router"; +import TextInput from "./TextInput"; import Textarea from "./Textarea"; class GroupForm extends React.Component { @@ -51,24 +51,8 @@ class GroupForm extends React.Component {
- {group.id ? ( - - Ta bort - grupp - - ) : ( - "" - )} - + {group.id ? Remove group : ""} +
diff --git a/admin/src/Components/KeyHandoutForm.jsx b/admin/src/Components/KeyHandoutForm.jsx index 13b5b9849..480b6f7fa 100644 --- a/admin/src/Components/KeyHandoutForm.jsx +++ b/admin/src/Components/KeyHandoutForm.jsx @@ -1,14 +1,13 @@ import React from "react"; -import { Prompt } from "react-router"; -import TextInput from "./TextInput"; -import { withRouter } from "react-router"; -import Span, { filterCategory } from "../Models/Span"; +import { renderToString } from "react-dom/server"; +import { Prompt, withRouter } from "react-router"; import Collection from "../Models/Collection"; import { ADD_LABACCESS_DAYS } from "../Models/ProductAction"; -import { dateTimeToStr, parseUtcDate, utcToday } from "../utils"; +import Span, { filterCategory } from "../Models/Span"; import { get, post } from "../gateway"; import { notifySuccess } from "../message"; -import { renderToString } from "react-dom/server"; +import { dateTimeToStr, parseUtcDate, utcToday } from "../utils"; +import TextInput from "./TextInput"; function last_span_enddate(spans, category) { const last_span = filterCategory(spans, category).splice(-1)[0]; @@ -27,35 +26,14 @@ function DateView(props) { let status, text; if (!props.date) { - status = ( -
- Saknas -
- ); - text = ( -

- {props.placeholder} -

- ); + status =
Missing
; + text =

{props.placeholder}

; } else if (!is_valid) { - status = ( -
- Utgånget -
- ); - text = ( -

- Giltigt till:{" "} - - {props.date} - -

- ); + status =
Expired
; + text =

Valid untill: {props.date}

; } else { - status = ( -
OK
- ); - text =

Giltigt till: {props.date}

; + status =
OK
; + text =

Valid untill: {props.date}

; } // Override if there are pending days to be synchronized @@ -65,23 +43,12 @@ function DateView(props) { ); } - return ( -
-

- {props.title} -

- {status} - {text} - {props.pending ? ( -

- - ({props.pending} dagar kommer läggas till vid en - nyckelsynkronisering) - -

- ) : null} -
- ); + return
+

{props.title}

+ {status} + {text} + { props.pending ?

({props.pending} days will be added after key sync)

: null } +
; } class KeyHandoutForm extends React.Component { @@ -223,7 +190,7 @@ class KeyHandoutForm extends React.Component { if (this.state.accessy_in_org) { notifySuccess("Medlem redan i Makerspace Accessy org"); } else { - notifySuccess("Accessy invite skickad"); + notifySuccess("Accessy invite succeeded"); } }); return false; @@ -277,7 +244,7 @@ class KeyHandoutForm extends React.Component { } else { invite_part = ( - Invite skickad + Invite succeeded ); } diff --git a/admin/src/Components/Login.jsx b/admin/src/Components/Login.jsx index b1acfc3eb..a58919088 100644 --- a/admin/src/Components/Login.jsx +++ b/admin/src/Components/Login.jsx @@ -9,8 +9,9 @@ export default class Login extends React.Component { const username = this.username.value; const password = this.password.value; - if (!username || !password) { - showError("Du måste fylla i email/medlemsnummer och lösenord"); + if (!username || !password) + { + showError("You must enter a username and password"); return; } @@ -29,20 +30,13 @@ export default class Login extends React.Component { onSubmit={this.login.bind(this)} >
-

Logga in

+

Log in

- - { - this.username = c; - }} - className="uk-form-large uk-form-width-large" - type="text" - placeholder="Email/Medlemsnummer" - /> + + { this.username = c; }} className="uk-form-large uk-form-width-large" type="text" placeholder="Email / User ID" />
@@ -55,27 +49,17 @@ export default class Login extends React.Component { }} className="uk-form-large uk-form-width-large" type="password" - placeholder="Lösenord" + placeholder="Password" />
- +
- - Glömt ditt lösenord? - + Forgot your password?
diff --git a/admin/src/Components/MemberForm.js b/admin/src/Components/MemberForm.js index 450d8ca0a..b6077dc5e 100644 --- a/admin/src/Components/MemberForm.js +++ b/admin/src/Components/MemberForm.js @@ -1,8 +1,8 @@ import React from "react"; +import { withRouter } from "react-router"; import CountryDropdown from "./CountryDropdown"; import DateTimeShow from "./DateTimeShow"; import TextInput from "./TextInput"; -import { withRouter } from "react-router"; class MemberForm extends React.Component { constructor(props) { @@ -42,61 +42,23 @@ class MemberForm extends React.Component { Personuppgifter - - - - - + + + + +
- - Adress - + Address - - - - + + + +
- +
- - {member.id ? ( -
- - Metadata - - -
- -
- -   - -
-
- -
- -
- -   - -
-
-
- ) : ( - "" - )} + + {member.id + ? +
+ Metadata + +
+ +
+ +   + +
+
+ +
+ +
+ +   + +
+
+
+ : + ""}
- {member.id ? ( - - Ta bort medlem - - ) : ( - "" - )} - + {member.id ? Remove member : ""} +
diff --git a/admin/src/Components/MessageForm.jsx b/admin/src/Components/MessageForm.jsx index 2ce11a06d..4f276cb58 100644 --- a/admin/src/Components/MessageForm.jsx +++ b/admin/src/Components/MessageForm.jsx @@ -1,11 +1,11 @@ import React from "react"; import { withRouter } from "react-router"; -import TextInput from "./TextInput"; -import Textarea from "./Textarea"; import { Async } from "react-select"; -import { get } from "../gateway"; import Group from "../Models/Group"; import Member from "../Models/Member"; +import { get } from "../gateway"; +import TextInput from "./TextInput"; +import Textarea from "./Textarea"; const groupOption = (d) => { const id = d[Group.model.id]; @@ -13,7 +13,7 @@ const groupOption = (d) => { return { id, type, - label: `Grupp: ${d.title}`, + label: `Group: ${d.title}`, value: type + id, }; }; @@ -25,7 +25,7 @@ const memberOption = (d) => { return { id, type, - label: `Medlem: ${d.firstname} ${lastname} (#${d.member_number})`, + label: `Member: ${d.firstname} ${lastname} (#${d.member_number})`, value: type + id, }; }; @@ -123,20 +123,10 @@ class MessageForm extends React.Component {
-

- - {message.body.length} - {" "} - tecken -

+

{message.body.length} sign

- +
diff --git a/admin/src/Components/ProductForm.jsx b/admin/src/Components/ProductForm.jsx index a041b6ad9..d3dedf305 100644 --- a/admin/src/Components/ProductForm.jsx +++ b/admin/src/Components/ProductForm.jsx @@ -1,12 +1,12 @@ import React from "react"; -import TextInput from "./TextInput"; -import Textarea from "./Textarea"; -import DateTimeInput from "./DateTimeInput"; -import * as _ from "underscore"; -import SelectInput from "./SelectInput"; import ReactSelect from "react-select"; +import * as _ from "underscore"; import ProductAction, { ACTION_TYPES } from "../Models/ProductAction"; import CheckboxInput from "./CheckboxInput"; +import DateTimeInput from "./DateTimeInput"; +import SelectInput from "./SelectInput"; +import TextInput from "./TextInput"; +import Textarea from "./Textarea"; // Return list of available actions types based on selected ones const filterAvailableActions = (actions) => { @@ -118,46 +118,14 @@ class ProductForm extends React.Component { }} >
- - Produkt - - - - o.name} - getValue={(o) => o.id} - dataSource={"/webshop/category"} - /> - )} - {!this.state.csv_content && ( - this.exportMembers()} - > - Exportera alla aktiva medlemmar som CSV - {this.state.state === "loading" ? "..." : ""} + { !this.state.csv_content && ( + this.exportMembers()}> + Export all active members as CSV{this.state.state === "loading" ? "..." : ""} )}
diff --git a/admin/src/Membership/MemberList.jsx b/admin/src/Membership/MemberList.jsx index e45636320..ac3213d85 100644 --- a/admin/src/Membership/MemberList.jsx +++ b/admin/src/Membership/MemberList.jsx @@ -1,11 +1,11 @@ import React from "react"; import { Link } from "react-router-dom"; -import Date from "../Components/DateShow"; -import Collection from "../Models/Collection"; -import Member from "../Models/Member"; import CollectionTable from "../Components/CollectionTable"; +import Date from "../Components/DateShow"; import SearchBox from "../Components/SearchBox"; +import Collection from "../Models/Collection"; import CollectionNavigation from "../Models/CollectionNavigation"; +import Member from "../Models/Member"; const Row = (props) => { const { item, deleteItem } = props; @@ -41,27 +41,20 @@ class MemberList extends CollectionNavigation { render() { const columns = [ - { title: "#", sort: "member_id" }, - { title: "Förnamn", sort: "firstname" }, - { title: "Efternamn", sort: "lastname" }, - { title: "E-post", sort: "email" }, - { title: "Blev medlem", sort: "created_at" }, - { title: "" }, + {title: "#", sort: "member_id"}, + {title: "First name", sort: "firstname"}, + {title: "Last name", sort: "lastname"}, + {title: "Email", sort: "email"}, + {title: "Joined", sort: "created_at"}, + {title: ""}, ]; return (

Medlemmar

-

- På denna sida ser du en lista på samtliga medlemmar. -

- - Skapa ny medlem - +

On this page you see the list of all the members.

+ Create new member { - e.preventDefault(); - onSave(); - return false; - }} - > - - - this.setState({ showHistoric: e.target.checked }) - } - /> - {this.categoryPeriodsList.map((cp) => ( - - ))} - +
{e.preventDefault(); onSave(); return false;}}> + + this.setState({showHistoric: e.target.checked})}/> + {this.categoryPeriodsList.map(cp => )} + ); } diff --git a/admin/src/Membership/SpanList.jsx b/admin/src/Membership/SpanList.jsx index bc8c959d9..f2325c2a1 100644 --- a/admin/src/Membership/SpanList.jsx +++ b/admin/src/Membership/SpanList.jsx @@ -1,12 +1,12 @@ import React from "react"; import { Link } from "react-router-dom"; -import Date from "../Components/DateShow"; -import Collection from "../Models/Collection"; import CollectionTable from "../Components/CollectionTable"; +import Date from "../Components/DateShow"; import DateTimeShow from "../Components/DateTimeShow"; +import Collection from "../Models/Collection"; +import CollectionNavigation from "../Models/CollectionNavigation"; import Span from "../Models/Span"; import { confirmModal } from "../message"; -import CollectionNavigation from "../Models/CollectionNavigation"; const Row = (deleteItem) => (props) => { const { item } = props; @@ -67,25 +67,20 @@ class SpanList extends CollectionNavigation { ); const columns = [ - { title: "#", sort: "span_id" }, - { title: "Typ", sort: "type" }, - { title: "Skapad", sort: "created_at" }, - { title: "" }, - { title: "Raderad", sort: "deleted_at" }, - { title: "Medlem", sort: "member_id" }, - { title: "Start", sort: "startdate" }, - { title: "Slut", sort: "enddate" }, + {title: "#", sort: "span_id"}, + {title: "Type", sort: "type"}, + {title: "Created", sort: "created_at"}, + {title: ""}, + {title: "Deleted", sort: "deleted_at"}, + {title: "Member id", sort: "member_id"}, + {title: "Start", sort: "startdate"}, + {title: "End", sort: "enddate"}, ]; return (
-

Medlemsperioder

- +

Membership periods

+
); } diff --git a/admin/src/Membership/SpanShow.jsx b/admin/src/Membership/SpanShow.jsx index 2f8de734b..df5289ef8 100644 --- a/admin/src/Membership/SpanShow.jsx +++ b/admin/src/Membership/SpanShow.jsx @@ -25,7 +25,7 @@ class SpanShow extends React.Component { return (
-

Medlemsperiod {data.span_id}

+

Membership periods {data.span_id}

{_.keys(data).map((key) => (
diff --git a/admin/src/Sales/AccountingExport.jsx b/admin/src/Sales/AccountingExport.jsx index cd8c45dd8..406267a9c 100644 --- a/admin/src/Sales/AccountingExport.jsx +++ b/admin/src/Sales/AccountingExport.jsx @@ -47,7 +47,7 @@ class AccountingExport extends React.Component { }) .catch((error) => { showError( - "

Misslyckades ladda ner fil.

Kunde inte kommunicera med servern: " + + "

Failed ladda ner fil.

Could not communicate with the server: " + error.message, ); }); @@ -95,7 +95,7 @@ class AccountingExport extends React.Component { vilken period du vill exportera {
  • Filter - filtrera på datumintervall etc
  • Gruppering - Beräkna min/max/avg för dagar, veckor, - månader, etc + months, etc
  • diff --git a/admin/src/app.jsx b/admin/src/app.jsx index c3b106964..7e56cdfff 100644 --- a/admin/src/app.jsx +++ b/admin/src/app.jsx @@ -35,80 +35,80 @@ const nav = { brand: "MakerAdmin", items: [ { - text: "Medlemmar", + text: "Memberships", target: "/membership", icon: "user", children: [ { - text: "Medlemmar", + text: "Members", target: "/membership/members", icon: "user", }, { - text: "Grupper", + text: "Groups", target: "/membership/groups", icon: "group", }, { - text: "Nycklar", + text: "Keys", target: "/membership/keys", icon: "key", }, { - text: "Medlemsperioder", + text: "Membership spans", target: "/membership/spans", icon: "clock-o", }, { - text: "Exportera medlemmar", + text: "Export members", target: "/membership/export", icon: "download", }, ], }, { - text: "Försäljning", + text: "Sales", target: "/sales", icon: "shopping-basket", children: [ { - text: "Ordrar", + text: "Orders", target: "/sales/order", }, { - text: "Presentkort", + text: "Gift-cards", target: "/sales/gift-card", }, { - text: "Produkter", + text: "Products", target: "/sales/product", }, { - text: "Bilder", + text: "Images", target: "/sales/image", }, { - text: "Kategorier", + text: "Categories", target: "/sales/category", }, { - text: "Bokföring", + text: "Accounting", target: "/sales/accounting", }, ], }, { - text: "Utskick", + text: "Messages", target: "/messages", icon: "envelope", children: [ { - text: "Historik", + text: "History", target: "/messages/history", icon: "list", }, { - text: "Nytt utskick", + text: "New messages", target: "/messages/new", icon: "envelope", }, @@ -126,12 +126,12 @@ const nav = { ], }, { - text: "Statistik", + text: "Statistics", target: "/statistics", icon: "area-chart", }, { - text: "Inställningar", + text: "Settings", target: "/settings", icon: "cog", children: [ @@ -155,7 +155,7 @@ const nav = { icon: "crosshairs", }, { - text: "Logga ut", + text: "Log out", target: "/logout", icon: "sign-out", }, diff --git a/admin/src/auth.js b/admin/src/auth.js index c8095a3df..163f0f2e4 100644 --- a/admin/src/auth.js +++ b/admin/src/auth.js @@ -57,12 +57,12 @@ class Auth { .then((response) => { if (response.status === 401) { return Promise.reject( - "Felaktig email/medlemsnummer eller lösenord.", + "Wrong email/member number or password.", ); } if (response.status === 429) { return Promise.reject( - "För många misslyckades inloggningar. Kontot spärrat i 60 minuter.", + "För många failed inloggningar. Kontot spärrat i 60 minuter.", ); } if (response.status === 200) { @@ -70,11 +70,13 @@ class Auth { } return Promise.reject( - "Oväntad statuskod (" + response.status + ") från servern.", + "Unexpected status code (" + + response.status + + ") from the server.", ); }) .catch((msg) => { - showError("

    Inloggningen misslyckades

    " + msg); + showError("

    Login failed

    " + msg); return Promise.reject(null); }) .then((data) => { @@ -120,21 +122,21 @@ class Auth { .then(({ response, responseData }) => { if (response.status === 200) { showSuccess( - "Ett mail har skickats till dig med en inloggningslänk, använd den för att logga in.", + "A mail has been sent to you with a login link. Use it to log in.", ); } else if (responseData.status === "ambiguous") { showError( - "

    Inloggningen misslyckades

    Det finns flera medlemmar som matchar '" + + "

    Login failed

    Det finns flera medlemmar som matchar '" + tag + "'. Välj något som är mer unikt, t.ex email eller medlemsnummer.", ); } else if (responseData.status === "not found") { showError( - "

    Inloggningen misslyckades

    Ingen medlem med det namnet, email eller medlemsnummer existerar.", + "

    Login failed

    Ingen medlem med det namnet, email eller medlemsnummer existerar.", ); } else { showError( - "

    Inloggningen misslyckades

    Tog emot ett oväntat svar från servern:

    " + + "

    Login failed

    Received an unexpected answer from the server:

    " + response.status + " " + response.statusText, @@ -143,7 +145,7 @@ class Auth { }) .catch(() => { showError( - "

    Inloggningen misslyckades

    Kunde inte kommunicera med servern.", + "

    Login failed

    Could not communicate with the server.", ); }); } diff --git a/api/src/change_phone_request.py b/api/src/change_phone_request.py index 0c9b86725..c2ff2258d 100755 --- a/api/src/change_phone_request.py +++ b/api/src/change_phone_request.py @@ -85,7 +85,7 @@ def change_phone_request(member_id: int | None, phone: str) -> int: except NoAuthConfigured: pass except Exception: - raise BadRequest("Misslyckades med att skicka sms med verifikations kod") + raise BadRequest("Failed med att skicka sms med verifikations kod") change_request = PhoneNumberChangeRequest( member_id=member_id, phone=phone, validation_code=validation_code, completed=False, timestamp=datetime.utcnow() diff --git a/api/src/firstrun.py b/api/src/firstrun.py index c54e9a020..126a7e1f3 100644 --- a/api/src/firstrun.py +++ b/api/src/firstrun.py @@ -155,7 +155,7 @@ def create_required_stripe_products(): name="Base membership", defaults=dict( price=200, - unit="år", + unit="year", display_order=next_display_order(Product), category_id=member_category.id, product_metadata={ @@ -171,7 +171,7 @@ def create_required_stripe_products(): name="Makerspace access", defaults=dict( price=575, - unit="mån", + unit="month", display_order=next_display_order(Product), category_id=member_category.id, product_metadata={ @@ -188,7 +188,7 @@ def create_required_stripe_products(): name="Makerspace access starter pack", defaults=dict( price=750, - unit="st", + unit="piece", display_order=next_display_order(Product), category_id=member_category.id, product_metadata={ @@ -204,7 +204,7 @@ def create_required_stripe_products(): name="Base membership subscription", defaults=dict( price=200, - unit="år", + unit="year", display_order=next_display_order(Product), category_id=member_category.id, product_metadata={ @@ -219,7 +219,7 @@ def create_required_stripe_products(): name="Makerspace access subscription", defaults=dict( price=350, - unit="mån", + unit="month", display_order=next_display_order(Product), category_id=member_category.id, product_metadata={ @@ -348,7 +348,7 @@ def create_shop_products() -> None: name=name, defaults=dict( price=random.randint(5, 100), - unit="st", + unit="piece", display_order=next_display_order(Product), category_id=tools_category.id, product_metadata={}, diff --git a/api/src/messages/test/labacess_reminder_test.py b/api/src/messages/test/labacess_reminder_test.py index 09aa8b96a..151bdb11b 100644 --- a/api/src/messages/test/labacess_reminder_test.py +++ b/api/src/messages/test/labacess_reminder_test.py @@ -17,7 +17,7 @@ class Test(ShopTestMixin, FlaskTestBase): products = [ dict( price=100.0, - unit="st", + unit="piece", smallest_multiple=1, action=dict(action_type=ProductAction.ADD_LABACCESS_DAYS, value=30), ) diff --git a/api/src/messages/test/membership_reminder_test.py b/api/src/messages/test/membership_reminder_test.py index bc6fc7d49..bf9218de4 100644 --- a/api/src/messages/test/membership_reminder_test.py +++ b/api/src/messages/test/membership_reminder_test.py @@ -21,7 +21,7 @@ class Test(ShopTestMixin, FlaskTestBase): products = [ dict( price=100.0, - unit="st", + unit="piece", smallest_multiple=1, action=dict(action_type=ProductAction.ADD_MEMBERSHIP_DAYS, value=30), ) diff --git a/api/src/multiaccessy/README.md b/api/src/multiaccessy/README.md index cc4188bb3..84443f7b9 100644 --- a/api/src/multiaccessy/README.md +++ b/api/src/multiaccessy/README.md @@ -27,7 +27,7 @@ Måste plocka bort från Organisation. Skicka ny Accessy-invite till nytt nummer Fixat -## Inbjudan +## Invitation - Invite via API - SMS skickas till personen diff --git a/api/src/shop/stripe_subscriptions.py b/api/src/shop/stripe_subscriptions.py index 01f2d663a..a85819195 100644 --- a/api/src/shop/stripe_subscriptions.py +++ b/api/src/shop/stripe_subscriptions.py @@ -128,10 +128,10 @@ def setup_subscription_makeradmin_product( } interval = recurring_price["recurring"]["interval"] if interval == "month": - product.unit = "mån" + product.unit = "month" average_days = 30 elif interval == "year": - product.unit = "år" + product.unit = "year" average_days = 365 else: raise RuntimeError(f"Unexpected interval {interval} in stripe product") diff --git a/api/src/shop/test/stripe_product_price_test.py b/api/src/shop/test/stripe_product_price_test.py index f18d62a59..4f40ae91e 100644 --- a/api/src/shop/test/stripe_product_price_test.py +++ b/api/src/shop/test/stripe_product_price_test.py @@ -37,7 +37,7 @@ class StripeRecurringWithoutStripeTest(ShopTestMixin, FlaskTestBase): def test_makeradmin_to_stripe_recurring_recurring(self) -> None: makeradmin_test_product = self.db.create_product( - unit="mån", + unit="month", smallest_multiple=3, ) recurring = makeradmin_to_stripe_recurring(makeradmin_test_product, stripe_constants.PriceType.RECURRING) @@ -46,7 +46,7 @@ def test_makeradmin_to_stripe_recurring_recurring(self) -> None: def test_makeradmin_to_stripe_recurring_binding(self) -> None: makeradmin_test_product = self.db.create_product( - unit="mån", + unit="month", smallest_multiple=3, ) recurring = makeradmin_to_stripe_recurring(makeradmin_test_product, stripe_constants.PriceType.BINDING_PERIOD) @@ -55,7 +55,7 @@ def test_makeradmin_to_stripe_recurring_binding(self) -> None: def test_makeradmin_to_stripe_recurring_wrong_unit(self) -> None: makeradmin_test_product = self.db.create_product( - unit="st", + unit="piece", ) with self.assertRaises(ValueError) as context: (makeradmin_to_stripe_recurring(makeradmin_test_product, stripe_constants.PriceType.RECURRING),) @@ -103,7 +103,7 @@ def assertPrice( else: assert stripe_price.type == "recurring" reccuring = stripe_price.recurring - if "mån" in makeradmin_product.unit: + if "month" in makeradmin_product.unit: assert reccuring["interval"] == "month" else: assert reccuring["interval"] == "year" @@ -118,10 +118,10 @@ def assertPrice( def test_create_product(self) -> None: makeradmin_test_product = self.db.create_product( - name="test månad enkel", + name="test month enkel", price=100.0, id=self.base_stripe_id, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -135,7 +135,7 @@ def test_create_product_with_price_regular(self) -> None: name="test regular product", price=100.0, id=self.base_stripe_id + 1, - unit="st", + unit="piece", smallest_multiple=1, category_id=self.not_subscription_category.id, ) @@ -154,10 +154,10 @@ def test_create_product_with_price_regular(self) -> None: def test_create_product_with_price_monthly_simple(self) -> None: makeradmin_test_product = self.db.create_product( - name="test månad enkel", + name="test month enkel", price=100.0, id=self.base_stripe_id + 2, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -176,10 +176,10 @@ def test_create_product_with_price_monthly_simple(self) -> None: def test_create_product_with_price_yearly_simple(self) -> None: makeradmin_test_product = self.db.create_product( - name="test år enkel", + name="test year enkel", price=200.0, id=self.base_stripe_id + 3, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -198,10 +198,10 @@ def test_create_product_with_price_yearly_simple(self) -> None: def test_create_product_with_price_monthly_with_binding_period(self) -> None: makeradmin_test_product = self.db.create_product( - name="test månad med bindingstid", + name="test month med bindingstid", price=300.0, id=self.base_stripe_id + 4, - unit="mån", + unit="month", smallest_multiple=2, category_id=self.subscription_category.id, ) @@ -228,7 +228,7 @@ def test_activate_deactivate(self) -> None: name="test activate deactivate", price=100.0, id=self.base_stripe_id + 5, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -253,7 +253,7 @@ def test_update_product(self) -> None: name="test update product", price=100.0, id=self.base_stripe_id + 6, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -271,7 +271,7 @@ def test_replace_price(self) -> None: name="test update price", price=100.0, id=self.base_stripe_id + 7, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.not_subscription_category.id, ) @@ -301,7 +301,7 @@ def test_get_sync_product(self) -> None: name="test update product", price=100.0, id=self.base_stripe_id + 8, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -319,7 +319,7 @@ def test_get_sync_price(self) -> None: name="test update price", price=100.0, id=self.base_stripe_id + 9, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.not_subscription_category.id, ) @@ -352,7 +352,7 @@ def test_equal_product(self) -> None: name="test eq price", price=200.0, id=self.base_stripe_id + 10, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -360,7 +360,7 @@ def test_equal_product(self) -> None: name="test not eq price", price=200.0, id=self.base_stripe_id - 1, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -381,7 +381,7 @@ def test_equal_price(self) -> None: name="test eq price", price=200.0, id=self.base_stripe_id + 11, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -389,7 +389,7 @@ def test_equal_price(self) -> None: name="test not eq price", price=210.0, id=self.base_stripe_id - 1, - unit="mån", + unit="month", smallest_multiple=1, category_id=self.subscription_category.id, ) @@ -405,7 +405,7 @@ def test_equal_price(self) -> None: name="test not eq mult", price=200.0, id=self.base_stripe_id - 3, - unit="mån", + unit="month", smallest_multiple=2, category_id=self.subscription_category.id, ) @@ -413,7 +413,7 @@ def test_equal_price(self) -> None: name="test not eq category", price=200.0, id=self.base_stripe_id - 4, - unit="mån", + unit="month", smallest_multiple=2, category_id=self.not_subscription_category.id, ) diff --git a/api/src/shop/test/stripe_util_test.py b/api/src/shop/test/stripe_util_test.py index e88f94244..6284493ec 100644 --- a/api/src/shop/test/stripe_util_test.py +++ b/api/src/shop/test/stripe_util_test.py @@ -64,7 +64,7 @@ def test_stripe_amount_from_makeradmin_product(self) -> None: makeradmin_test_product = self.db.create_product( name="test", price=price, - unit="mån", + unit="month", smallest_multiple=5, ) for multiple in multiples: diff --git a/api/src/systest/api/purchase_test.py b/api/src/systest/api/purchase_test.py index 53997b345..2e1b80c83 100644 --- a/api/src/systest/api/purchase_test.py +++ b/api/src/systest/api/purchase_test.py @@ -9,7 +9,7 @@ class Test(ApiShopTestMixin, ApiTest): products = [ - dict(price=12.3, unit="st", smallest_multiple=1), + dict(price=12.3, unit="piece", smallest_multiple=1), dict(price=1.2, unit="mm", smallest_multiple=100), ] diff --git a/api/src/test_aid/obj.py b/api/src/test_aid/obj.py index c6125486f..93d15eac7 100644 --- a/api/src/test_aid/obj.py +++ b/api/src/test_aid/obj.py @@ -133,7 +133,7 @@ def create_product(self, **kwargs): name=f"product-{random_str(12)}", price=100.0, description=self.fake.bs(), - unit="st", + unit="piece", display_order=randint(int(1e8), int(9e8)), smallest_multiple=1, filter=None, diff --git a/public/src/templates/product.html b/public/src/templates/product.html index 7ec234c59..606c79986 100644 --- a/public/src/templates/product.html +++ b/public/src/templates/product.html @@ -21,9 +21,7 @@ > {{ _("Back") }} {{ _("Shopping Cart") }}Min kundvagn + >Shopping Cart
    diff --git a/public/ts/cartpage.tsx b/public/ts/cartpage.tsx index 0e87dd667..96aad7a58 100644 --- a/public/ts/cartpage.tsx +++ b/public/ts/cartpage.tsx @@ -117,12 +117,11 @@ const PaymentButton = ({ on_failure: (json: ServerResponse) => { if (json.status === UNAUTHORIZED) { UIkit.modal.alert( - "

    Betalningen misslyckades

    Du är inte inloggad", + "

    The payment failed

    You are not logged in", ); } else { UIkit.modal.alert( - "

    Betalningen misslyckades

    " + - common.get_error(json), + "

    The payment failed

    " + common.get_error(json), ); } }, @@ -136,7 +135,7 @@ const PaymentButton = ({ return ( <>
    -

    Betala med kort via Stripe

    +

    Pay by card via Stripe

    @@ -184,7 +183,7 @@ const PaymentButton = ({ } } } catch (e) { - common.show_error("Betalningen misslyckades", e); + common.show_error("The payment failed", e); } finally { setInProgress(false); } @@ -197,7 +196,7 @@ const PaymentButton = ({ uk-spinner={""} > - Betala / Pay + Pay {" "} {Cart.formatCurrency(cart.sum(productData.id2item))} @@ -217,7 +216,7 @@ const CartPage = ({ productData }: { productData: ProductData }) => {
    -

    Varukorg

    +

    Shopping basket

      {cart.items.length > 0 ? ( cart.items.map((cartItem) => ( @@ -230,7 +229,7 @@ const CartPage = ({ productData }: { productData: ProductData }) => { )) ) : (

      - Du har inga produkter i varukorgen. + You have no products in the bin.

      )}
    @@ -268,7 +267,7 @@ common.documentLoaded().then(() => { login.render_login(root, null, null); } else { UIkit.modal.alert( - "

    Misslyckades med att hämta köphistorik

    " + + "

    Failed to retrieve purchase history

    " + common.get_error(json), ); } diff --git a/public/ts/courses.tsx b/public/ts/courses.tsx index 98d88fe97..70919c850 100644 --- a/public/ts/courses.tsx +++ b/public/ts/courses.tsx @@ -21,7 +21,7 @@ const CourseButton = ({ quizInfo }: { quizInfo: QuizInfo }) => { if (completed) { actionBtn = (
    - Genomförd + Completed
    ); } else if (quizInfo.correctly_answered_questions > 0) { @@ -30,14 +30,14 @@ const CourseButton = ({ quizInfo }: { quizInfo: QuizInfo }) => { quizInfo.total_questions_in_quiz; actionBtn = (
    - Fortsätt ({Math.round(completed_fraction * 100)}%){" "} + Continue ({Math.round(completed_fraction * 100)}%){" "}
    ); } else { actionBtn = (
    - Ta kursen{" "} + Take the course{" "}
    ); @@ -61,12 +61,10 @@ const CoursesPage = ({ courses }: { courses: QuizInfo[] }) => {
    -

    Kurser

    +

    Courses

    - Här hittar du alla digitala kurser som Stockholm - Makerspace har. De flesta kurser sker på plats och - annonseras i facebook-gruppen och på slack. Men vissa - har en digital variant som du kan ta när du vill. + Here you can find all the online courses from The O'Town + Garage.

    {courses.map((quizInfo) => ( @@ -105,7 +103,7 @@ common.documentLoaded().then(() => { login.render_login(rootElement, null, null); } else { UIkit.modal.alert( - "

    Misslyckades med att hämta quiz-info

    " + + "

    Failed to retrieve the quiz info

    " + common.get_error(json), ); } diff --git a/public/ts/history.tsx b/public/ts/history.tsx index 5f4c63c1d..90d8149ab 100644 --- a/public/ts/history.tsx +++ b/public/ts/history.tsx @@ -24,7 +24,7 @@ const HistoryPage = ({
    -

    Köphistorik

    +

    Purchase History

    #{member.member_number} {member.firstname}{" "} {member.lastname} @@ -74,7 +74,7 @@ common.documentLoaded().then(() => { login.render_login(root, null, null); } else { UIkit.modal.alert( - "

    Misslyckades med att hämta köphistorik

    " + + "

    Failed to retrieve purchase history

    " + common.get_error(json), ); } diff --git a/public/ts/licenses.tsx b/public/ts/licenses.tsx index a134405db..cb74663b4 100644 --- a/public/ts/licenses.tsx +++ b/public/ts/licenses.tsx @@ -11,9 +11,9 @@ const LicensesPage = () => {
    -

    Licenser och Rabatter

    +

    Licenses and discounts

    - Det här är en lista med licenser och rabatter som + Det här är en lista med Licenses and discounts som medlemmar i Stockholm Makerspace kan använda fritt.

    diff --git a/public/ts/login.tsx b/public/ts/login.tsx index 9b7cdaa8c..6545ba195 100644 --- a/public/ts/login.tsx +++ b/public/ts/login.tsx @@ -29,17 +29,17 @@ export function login_via_password( }) .catch((response: ServerResponse) => { if (response.status === common.UNAUTHORIZED) { - return Promise.reject( - "Felaktig email/medlemsnummer eller lösenord.", - ); + return Promise.reject("Wrong email/member number or password."); } return Promise.reject( - "Oväntad statuskod (" + response.status + ") från servern.", + "Unexpected status code (" + + response.status + + ") from the server.", ); }) .catch((msg) => { - showError("

    Inloggningen misslyckades

    " + msg); + showError("

    Login failed

    " + msg); return Promise.reject(null); }) .then((data) => { @@ -67,11 +67,11 @@ export function login_via_single_use_link( // Yay, success, refresh page if (json.data.status === "sent") { showSuccess( - "Ett mail har skickats till dig med en inloggningslänk, använd den för att logga in.", + "A mail has been sent to you with a login link. Use it to log in.", ); } else { showError( - "

    Inloggningen misslyckades

    Tog emot ett oväntat svar från servern:

    " + + "

    Login failed

    Received an unexpected answer from the server:

    " + json.data.status, ); } @@ -79,18 +79,18 @@ export function login_via_single_use_link( .catch((json) => { if (json.status === "not found") { showError( - "

    Inloggningen misslyckades

    Hittar inte email eller medlemsnummer.", + "

    Login failed

    Hittar inte email eller medlemsnummer.", ); } else { showError( - "

    Inloggningen misslyckades

    Tog emot ett oväntat svar från servern:

    " + + "

    Login failed

    Received an unexpected answer from the server:

    " + json.message, ); } }) .catch(() => { showError( - "

    Inloggningen misslyckades

    Kunde inte kommunicera med servern.", + "

    Login failed

    Could not communicate with the server.", ); }); } @@ -132,7 +132,7 @@ export const Login = ({ redirect }: { redirect: string | null }) => { e.preventDefault(); // Error handling if (!tag) { - UIkit.modal.alert("Du måste fylla i din E-postadress"); + UIkit.modal.alert("You must enter your email"); return; } @@ -140,7 +140,7 @@ export const Login = ({ redirect }: { redirect: string | null }) => { loginMethod == LoginMethod.EmailAndPassword && !password ) { - UIkit.modal.alert("Du måste fylla i ditt lösenord"); + UIkit.modal.alert("You must enter your password"); return; } @@ -176,7 +176,7 @@ export const Login = ({ redirect }: { redirect: string | null }) => { class="uk-form-large uk-width-1-1" type="password" id="password" - placeholder="Lösenord" + placeholder="Password" value={password} onChange={(e) => setPassword(e.currentTarget.value)} /> @@ -208,8 +208,8 @@ export const Login = ({ redirect }: { redirect: string | null }) => { }} > {loginMethod === LoginMethod.EmailLink - ? "Logga in med lösenord" - : "Logga in med endast email"} + ? "login with password" + : "login with email"}

    @@ -226,7 +226,7 @@ function LoginPage({ heading: string | null; redirect: string | null; }) { - heading = heading || "Logga in"; + heading = heading || "log in"; return ( <> diff --git a/public/ts/member.tsx b/public/ts/member.tsx index 5a0e0eb02..daa98c46e 100644 --- a/public/ts/member.tsx +++ b/public/ts/member.tsx @@ -221,8 +221,8 @@ function SignedContractWarning({ member }: { member: member_t }) { const t = useTranslation(); return member.labaccess_agreement_at ? null : ( - Du måste delta på en medlemintroduktion. Du hittar - dem i kalendern. + You must participate in a member introduction. You + can find them in the calendar. ); } @@ -230,8 +230,8 @@ function SignedContractWarning({ member }: { member: member_t }) { function NoMembershipWarning({ membership }: { membership: membership_t }) { return membership.membership_active ? null : ( - Du måste köpa föreningsmedlemskap i{" "} - webshoppen. + You must buy a membership in{" "} + the webshop. ); } @@ -239,8 +239,8 @@ function NoMembershipWarning({ membership }: { membership: membership_t }) { function MissingPhoneNumber({ member }: { member: member_t }) { return member.phone ? null : ( - Du måste lägga in ditt telefonnummer i - personuppgifterna nedan. + You must enter your phine number + in the personal info underneath. ); } @@ -297,18 +297,17 @@ function PendingLabaccessInstructions({ if (!can_sync_labaccess && pending_labaccess_days) { return ( <> - Du behöver åtgärda ovanstående fel innan din labbaccess kan - synkas. När de är åtgärdade kommer den digitala nyckeln att - förlängas med {pending_labaccess_days} dagar{" "} - vid nästa nyckelsynkronisering. + You have to accept the rules above before your access to the + makerspace is approved. When accepted, we can plan a day to show + you around and we can give you the access to the space in + person. ); } else if (can_sync_labaccess && pending_labaccess_days) { return ( <> - {pending_labaccess_days} dagar kommer läggas - till vid nästa nyckelsynkronisering. Då kommer din access att - förlängas. + {pending_labaccess_days} days will be added to + your access to the garage. ); } else { @@ -494,10 +493,10 @@ async function send_accessy_invite() { "POST", `${window.apiBasePath}/webshop/member/current/accessy_invite`, ); - UIkit.modal.alert(`

    Inbjudan skickad

    `); + UIkit.modal.alert(`

    Invitation succeeded

    `); } catch (e) { UIkit.modal.alert( - `

    Inbjudan misslyckades

    ${get_error( + `

    Invitation failed

    ${get_error( e, )}`, ); @@ -713,7 +712,7 @@ function PersonalData({
    { login.render_login(root, null, null); } else { UIkit.modal.alert( - "

    Misslyckades med att hämta kvittot

    " + - get_error(json), + "

    Failed med att hämta kvittot

    " + get_error(json), ); } }); diff --git a/public/ts/register.tsx b/public/ts/register.tsx index cffbe375a..4eef1c2a1 100644 --- a/public/ts/register.tsx +++ b/public/ts/register.tsx @@ -834,8 +834,8 @@ const poorMansHistoryManager = ( const listener = (e: PopStateEvent) => { let newState = defaultState; if (location.hash.startsWith("#")) { - const st: T | undefined = parse(location.hash.slice(1)); - if (st !== undefined) newState = st; + const state: T | undefined = parse(location.hash.slice(1)); + if (state !== undefined) newState = state; } setState(newState); }; diff --git a/public/ts/shop.tsx b/public/ts/shop.tsx index 7dd75a73c..c6ac19f9a 100644 --- a/public/ts/shop.tsx +++ b/public/ts/shop.tsx @@ -317,7 +317,7 @@ common.documentLoaded().then(() => { login.render_login(root, null, null); } else { UIkit.modal.alert( - "

    Misslyckades med att hämta köphistorik

    " + + "

    Failed to retrieve purchase history

    " + common.get_error(json), ); } diff --git a/public/ts/sidebar.tsx b/public/ts/sidebar.tsx index bac601f6c..28d9ede97 100644 --- a/public/ts/sidebar.tsx +++ b/public/ts/sidebar.tsx @@ -71,7 +71,7 @@ export const Sidebar = ({ />
      - Medlemsvy + Member page Webshop @@ -98,7 +98,7 @@ export const Sidebar = ({ ))} - Min Kundvagn ( + Shopping Cart ( {Cart.formatCurrency( cart.cart.sum(cart.productData.id2item), )} @@ -107,13 +107,13 @@ export const Sidebar = ({
    )} - Min köphistorik + My purchase history - Kurser + Courses - Licenser och rabatter + Licenses and discounts
  • - Logga ut + Log out
  • @@ -133,7 +133,7 @@ export const Sidebar = ({ }`} > - Betala + Pay {Cart.formatCurrency( cart.cart.sum(cart.productData.id2item), diff --git a/public/ts/statistics.ts b/public/ts/statistics.ts index f81ab4ede..adf6ca738 100644 --- a/public/ts/statistics.ts +++ b/public/ts/statistics.ts @@ -809,12 +809,12 @@ function addProductPurchasedChart(root: HTMLElement, data: ProductStatistics) { addRevenueChart( root, membershipSales, - "Försäljning i webshoppen av medlemskap (senaste 12 månaderna)", + "Försäljning i webshoppen av medlemskap (senaste 12 monthsna)", ); addRevenueChart( root, otherSales, - "Försäljning i webshoppen av övriga produkter (senaste 12 månaderna)", + "Försäljning i webshoppen av övriga produkter (senaste 12 monthsna)", ); addRevenueChart( root, @@ -825,7 +825,7 @@ function addProductPurchasedChart(root: HTMLElement, data: ProductStatistics) { (x) => x.category_id == c.id, )?.amount ?? 0, })), - "Försäljning i webshoppen per kategori (senaste 12 månaderna)", + "Försäljning i webshoppen per kategori (senaste 12 monthsna)", ); } diff --git a/public/ts/translations.tsx b/public/ts/translations.tsx index 7d761dcff..03a3df8ac 100644 --- a/public/ts/translations.tsx +++ b/public/ts/translations.tsx @@ -25,15 +25,15 @@ const Eng = { cancel: "Cancel", apply_for_discounts: "I cannot afford the membership fee", unit: { - år: { + year: { one: "year", many: "years", }, - mån: { + month: { one: "month", many: "months", }, - st: { + piece: { one: "piece", many: "pieces", }, @@ -424,8 +424,8 @@ const Eng = { inactive_recent: (days: number) => `Your makerspace access expired ${days} days ago.`, inactive_yesterday: `Your makerspace access expired yesterday`, - active_hours_remaining: (hours: number) => - `Your makerspace access is valid for only ${hours} more hours.`, + active_hours_remaining: (piece: number) => + `Your makerspace access is valid for only ${piece} more piece.`, active_few_days_remaining: (end_date: string, days: number) => `Your makerspace access is valid through ${end_date} (only ${days} days left).`, active_days_remaining: (end_date: string, days: number) => @@ -436,8 +436,8 @@ const Eng = { inactive_recent: (days: number) => `Your base membership expired ${days} days ago.`, inactive_yesterday: `Your base membership expired yesterday`, - active_hours_remaining: (hours: number) => - `Your base membership is valid for only ${hours} more hours.`, + active_hours_remaining: (piece: number) => + `Your base membership is valid for only ${piece} more piece.`, active_few_days_remaining: (end_date: string, days: number) => `Your base membership is valid through ${end_date} (only ${days} days left).`, active_days_remaining: (end_date: string, days: number) => @@ -448,8 +448,8 @@ const Eng = { inactive_recent: (days: number) => `Your special makerspace access expired ${days} days ago.`, inactive_yesterday: `Your special makerspace access expired yesterday`, - active_hours_remaining: (hours: number) => - `You have been given special access to the premises, which is for only ${hours} more hours.`, + active_hours_remaining: (piece: number) => + `You have been given special access to the premises, which is for only ${piece} more piece.`, active_few_days_remaining: (end_date: string, days: number) => `You have been given special access to the premises through ${end_date} (only ${days} days left).`, active_days_remaining: (end_date: string, days: number) => @@ -508,8 +508,8 @@ const Eng = { `, expired_single_day: "Your lab membership expired yesterday.", - expires_today: (hours: number) => - `Your lab membership is valid for ${hours} more hours.`, + expires_today: (piece: number) => + `Your lab membership is valid for ${piece} more piece.`, valid: (enddate: string, days: number) => ` Your lab membership is valid through ${enddate}${" "} (only ${days} day(s) left). @@ -600,8 +600,8 @@ const Swe: typeof Eng = { Din labaccess är ogiltig sedan ${days} dagar (${enddate}). `, expired_single_day: "Din labaccess gick ut igår.", - expires_today: (hours: number) => - `Din labaccess är giltig i mindre än ${hours}${" "} timmar till.`, + expires_today: (piece: number) => + `Din labaccess är giltig i mindre än ${piece}${" "} timmar till.`, valid: (enddate: string, days: number) => ` Din labaccess är giltig t.o.m. ${enddate}${" "} (endast ${days} dagar till). @@ -711,7 +711,9 @@ export const TranslationWrapper = ({ }; export const translateUnit = (unit: string, count: number, t: Translator) => { - if (unit !== "mån" && unit !== "år" && unit !== "st") - throw new Error(`Unexpected unit '${unit}'. Expected one of år/mån/st`); + if (unit !== "month" && unit !== "year" && unit !== "piece") + throw new Error( + `Unexpected unit '${unit}'. Expected one of year/month/piece`, + ); return t(`unit.${unit}.${count > 1 ? "many" : "one"}`); };