{"id":14974879,"url":"https://github.com/aleksandertabor/flashcards","last_synced_at":"2025-10-27T10:31:40.564Z","repository":{"id":38153895,"uuid":"224922099","full_name":"aleksandertabor/flashcards","owner":"aleksandertabor","description":"Manage your flashcards with an app built with Laravel, Vue, GraphQL, Progressive Web App (PWA).","archived":false,"fork":false,"pushed_at":"2022-06-21T18:32:04.000Z","size":16424,"stargazers_count":8,"open_issues_count":11,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-09-27T19:41:06.113Z","etag":null,"topics":["graphql","graphql-api","laravel","laravel-sanctum","laravel-scout","laravel7","progressive-web-app","pwa","spa","vue","vue-router","vuejs","vuetify","vuex","workbox"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aleksandertabor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-29T21:05:58.000Z","updated_at":"2023-05-15T10:54:42.000Z","dependencies_parsed_at":"2022-09-15T14:41:45.175Z","dependency_job_id":null,"html_url":"https://github.com/aleksandertabor/flashcards","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksandertabor%2Fflashcards","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksandertabor%2Fflashcards/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksandertabor%2Fflashcards/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleksandertabor%2Fflashcards/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aleksandertabor","download_url":"https://codeload.github.com/aleksandertabor/flashcards/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219861468,"owners_count":16555994,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","graphql-api","laravel","laravel-sanctum","laravel-scout","laravel7","progressive-web-app","pwa","spa","vue","vue-router","vuejs","vuetify","vuex","workbox"],"created_at":"2024-09-24T13:51:12.826Z","updated_at":"2025-10-27T10:31:39.351Z","avatar_url":"https://github.com/aleksandertabor.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://flashcards.alexprojects.pl/\"\u003e\n    \u003cimg src=\"https://aleksandertabor.pl/wp-content/uploads/2020/04/icon-128x128-1.png\" alt=\"Flashcards logo\" title=\"Flashcards\" align=\"right\" height=\"100\" /\u003e\n\u003c/a\u003e\n\n🗃️ Flashcards\n======================\n\n\u003e [Flashcards](https://flashcards.alexprojects.pl/) - create your decks and add flashcards.\n\n## 🖥️ Demo\n\nLive demo: [flashcards.alexprojects.pl](https://flashcards.alexprojects.pl/)\n\n![flashcards](https://aleksandertabor.pl/wp-content/uploads/2020/04/mainflashcards.gif)\n\n# 🚩 Table of Contents\n\n1. [Requirements](#-requirements)\n2. [Installation](#-installation)\n3. [Helpers](#ℹ️-helpers)\n4. [Built with](#-built-with)\n5. [Frontend structure](#-frontend-structure)\n6. [GraphQL API](#-graphql-api)\n7. [Third Party APIs](#-third-party-apis)\n8. [Logs](#-logs)\n9. [Notifications](#-notifications)\n10. [Features](#-features)\n11. [Screenshots](#%EF%B8%8F-screenshots)\n12. [To-do](#-to-do)\n13. [Issues](#-issues)\n\n## 🔌 Requirements\n\n- PHP version: 7.3+\n- PHP additional xtensions: gmp, sqlite\n- Composer\n- Node.js\n\n## 🧾 Installation\n\n1. `git clone https://github.com/aleksandertabor/flashcards YOURPROJECTNAME`\n2. `cd YOURPROJECTNAME`\n3. Install dependencies:\n\n    `composer install`\n\n    `npm install`\n\n4. `cp .env.example .env`\n5. `php artisan key:generate`\n6. Set your `.env` with credentials to your database server (`DB_*` settings) and your domain config (`APP_URL`, `SANCTUM_STATEFUL_DOMAINS`, `SESSION_DOMAIN`). Remember about [3rd party APIs](#-third-party-apis) for which keys are required.\n7. `php artisan webpush:vapid`\n8. `php artisan migrate --seed`\n    - You can specify an amount of seeds. Available seeders:\n\n    `LanguagesTableSeeder::class`\n\n    ![LanguagesTableSeeder](https://aleksandertabor.pl/wp-content/uploads/2020/04/language-seeder-1024x92.png)\n\n    `UsersTableSeeder::class`\n\n    ![UsersTableSeeder](https://aleksandertabor.pl/wp-content/uploads/2020/04/user-seeder.png)\n\n    `DecksTableSeeder::class`\n\n    ![DecksTableSeeder](https://aleksandertabor.pl/wp-content/uploads/2020/04/deck-seeder.png)\n\n9. `php artisan storage:link` then `cd public || mv storage img`\n\n     Why? [Custom URL in Laravel Storage - Tutorial](https://medium.com/@aleksander.tabor/custom-url-in-laravel-storage-8392a32ac955)\n\n    - All storage links now have /img/ prefix e.g.:\n\n\n        \u003e `http://localhost:8000/img/example-image.jpg`\n\n10. `chmod -R 777 pdf` then `mv pdf storage/app/public`\n11. Build frontend with `npm run production` for production.\n\n\u003e ⚠️ Caution: Remember about giving proper permissions to the project directory e.g.:\n```bash\nsudo chgrp -R www-data /var/www/YOURPROJECTNAME\nsudo chmod -R 775 /var/www/YOURPROJECTNAME/storage\n```\n\n## ℹ️ Helpers\n\n- `npm build-pwa` for precaching files from `workbox.config.js`\n\n    originally: `workbox injectManifest workbox.config.js`\n\n## 🧰 Built with\n\n- Laravel 7\n- Vue\n- Vuetify\n- Vuex\n- Vue Router\n- GraphQL as API\n- Lighthouse as GraphQL Server\n- Apollo Client\n- Axios\n- Laravel Sanctum/Airlock for Auth\n- Laravel Scout for searching decks\n- Workbox for Progressive Web App (PWA) and working offline (caching) [compatibility](https://caniuse.com/#feat=mdn-api_serviceworker)\n- WebPush Notifications [compatibility](https://caniuse.com/#feat=mdn-api_notification)\n- Web Share API to share decks [compatibility](https://caniuse.com/#feat=web-share)\n- Web Devices API (Camera) to change avatar [compatibility](https://caniuse.com/#feat=mdn-api_mediadevices)\n- Babel for polyfills and browser compatibilities (.babelrc)\n\n\n## 📁 Frontend structure\n\nMain file: `resources/js/app.js`\n\nConfiguration files (routes, service-worker, store, vuetify): `resources/js/config`\n\nHTTP clients: `resources/js/httpClients`\n\nVuex modules: `resources/js/store/modules.js`\n\nGraphQL queries: `resources/js/queries`\n\nYou can manage PWA and Notifications with plugins: `resources/js/plugins/`\n\nShared components, mixins and utils: `resources/js/shared`\n\nComponents: `resources/js/views`\n\n## 💜 GraphQL API\n\nAll schemas: `routes/graphql/*.graphql`\n\nEndpoint: `api/graphql`\n\nPlayground (Live API): `api/graphql-playground`\n\n![GraphQL Playground](https://aleksandertabor.pl/wp-content/uploads/2020/04/graphql-playground-1024x502.png)\n\n## 🧻 Third Party APIs\nTo fill your flashcards you can add your content or third party resources. The app is configured to use:\n- Google Translation API for translations (need key in JSON) - `GOOGLE_API_CREDENTIALS`\n\n- Twinword API for example sentences (need key) - `TWINWORD_API_ENDPOINT`, `TWINWORD_API_KEY`\n\n- Wikipedia API for images (free) - `WIKIPEDIA_API_ENDPOINT`\n\n\u003e ⚠️ Caution: if none of APIs has keys, don't worry the app still working\n\nAPIs clients are binded with Singleton in: `app/Providers/AppServiceProvider.php`\n\nYou can use Facades to easily getting data from APIs everywhere you want:\n\n`TranslationFacade::translate(string $toTranslate, array $languages)` : `string`\n\n`TranslationFacade::langauges()` : `array`\n\n`ExampleFacade::example(string $wordToFind, string $sourceLanguage, string $targetLanguage)` : `array`\n\n`ImageFacade::random(string $imageToFind, string $sourceLanguage = null)` : ` string`\n\n## 📝 Logs\n\nYou can log everything you want by using special `'app'` channel that logs into `storage/logs/app.log`. Either local or production.\n\nE.g.: `Log::channel('app')-\u003einfo(\"{$currentUser-\u003eusername} logged in.\");`\n\nCurrently logging:\n\n- User logged in.\n\n- User registered.\n\n- New deck added.\n\n- New card added.\n\n- Calling to Google Translation API.\n\n## 💬 Notifications\n\nIf your browser supports Notification API you will receive Welcome Notification (PushRegistered):\n\n![PushRegistered](https://aleksandertabor.pl/wp-content/uploads/2020/04/welcomenotification.png)\n\nWhen added a new public deck or updated the current deck to visibility as `'public'`, you will receive notification (DeckPublished):\n\n![DeckPublished](https://aleksandertabor.pl/wp-content/uploads/2020/04/deckpublished.png)\n\n### Backend config:\n\nPushRegistered `app/Notifications/PushRegistered.php`\n\nDeckPublished `app/Notifications/DeckPublished.php`\n\n### Frontend config:\n\n`/resources/js/config/service-worker.js`\n\n`/resources/js/plugins/NotificationSystem.js`\n\n## 🎨 Features\n\n- Login with username or e-mail\n- Installable app - Add To Home Screen (A2HS)\n- Offline mode (data is limited to your memory size for cache)\n- Deck visibilities:\n    - public - anybody can see\n    - unlisted - only with link\n    - private - only you\n\n- Each deck is limited to 50 cards\n- Multi tabs logout - if you logout at one tab, you will be out of all currently running tabs in your browser\n- Add images from file or URL\n- Change avatar with your camera\n- Infinite scroll in searching decks\n- Find decks by filters (latest, oldest, random, cards count) and phrase\n- Two modes for creating flashcards with API (auto mode) or manually\n- Share your deck\n- Print your decks with \"Print Deck\" button\n\n    \u003e ⚠️ Caution: not supported all languages\n\n## 🖼️ Screenshots\n\n### Home:\n\n![Home](https://aleksandertabor.pl/wp-content/uploads/2020/04/flashcards-main.png)\n\n### Search:\n\n![Search](https://aleksandertabor.pl/wp-content/uploads/2020/04/searchdecks.png)\n\n### Profile:\n\n![Profile](https://aleksandertabor.pl/wp-content/uploads/2020/04/profile.png)\n\n### Deck:\n\n![Deck](https://aleksandertabor.pl/wp-content/uploads/2020/04/deck.png)\n\n### Deck editor:\n\n![Deck Editor](https://aleksandertabor.pl/wp-content/uploads/2020/04/deckeditor.png)\n\n### Card editor:\n\n![Card Editor](https://aleksandertabor.pl/wp-content/uploads/2020/04/cardeditor.png)\n\n\n### Print deck:\n\n![Print Deck](https://aleksandertabor.pl/wp-content/uploads/2020/04/printeddeck.png)\n\n### Installable App:\n\n\u003cimg src=\"https://aleksandertabor.pl/wp-content/uploads/2020/04/instalabble.gif\" width=\"70%\" alt=\"Install App\"/\u003e\n\n### Share deck:\n\n \u003cimg src=\"https://aleksandertabor.pl/wp-content/uploads/2020/04/sharedeck.gif\" width=\"70%\" alt=\"Share Deck\"/\u003e\n\n### Web Devices API (Camera):\n\n\u003cimg src=\"https://aleksandertabor.pl/wp-content/uploads/2020/04/changeavatar.gif\" width=\"70%\" alt=\"Change Avatar\"/\u003e\n\n## 📋 To-do\n\n- Use Background Sync API for creating decks offline\n\n- Show users which decks are currently cached\n\n- Live preview for deck and card editor\n\n- Auto mode for each input seperately in card editor\n\n- Gamification with quizzing\n\n- More social engagement with \"liking\" decks and filtering them by popularity\n\n- Easier installation with Docker\n\n## 🔴 Issues\n\n- If you have seen any bugs please report it by making an [issue](https://github.com/aleksandertabor/flashcards/issues).\n- You can PM me directly at [Facebook](https://www.facebook.com/aleksander.tabor.79), [Twitter](https://twitter.com/AlekTabor)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleksandertabor%2Fflashcards","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faleksandertabor%2Fflashcards","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleksandertabor%2Fflashcards/lists"}