├── .nvmrc
├── config
├── .gitkeep
├── logging.php
├── social.php
├── auth.php
├── mail.php
├── app.php
├── services.php
└── database.php
├── app
├── Handlers
│ ├── Events
│ │ ├── .gitkeep
│ │ └── SlackSubscriber.php
│ └── Commands
│ │ └── .gitkeep
├── Events
│ └── Event.php
├── Http
│ ├── Controllers
│ │ ├── Controller.php
│ │ ├── Api
│ │ │ ├── MeController.php
│ │ │ ├── BiosController.php
│ │ │ ├── TalksController.php
│ │ │ ├── UserBiosController.php
│ │ │ └── UserTalksController.php
│ │ ├── HomeController.php
│ │ ├── RejectionController.php
│ │ ├── SubmissionReactionsController.php
│ │ ├── AcceptancesController.php
│ │ ├── DashboardController.php
│ │ └── Auth
│ │ │ ├── ForgotPasswordController.php
│ │ │ ├── ResetPasswordController.php
│ │ │ └── LoginController.php
│ ├── Requests
│ │ ├── Request.php
│ │ ├── SpeakerSearchRequest.php
│ │ ├── SaveTalkRequest.php
│ │ └── Auth
│ │ │ ├── LoginFormRequest.php
│ │ │ └── RegisterFormRequest.php
│ └── Middleware
│ │ └── Social.php
├── Exceptions
│ ├── InvalidAddressGeocodingException.php
│ └── ValidationException.php
├── Models
│ ├── TalkReaction.php
│ ├── UserSocial.php
│ ├── TightenSlack.php
│ ├── Bio.php
│ └── UuidBase.php
├── helpers.php
├── Collections
│ └── TalksCollection.php
├── Policies
│ └── ConferencePolicy.php
├── Filament
│ └── Resources
│ │ ├── ConferenceResource
│ │ └── Pages
│ │ │ ├── ListConferences.php
│ │ │ └── EditConference.php
│ │ └── ConferenceIssueResource
│ │ └── Pages
│ │ ├── ListConferenceIssues.php
│ │ └── ViewConferenceIssue.php
├── Services
│ ├── FakeCaptcha.php
│ ├── Currency.php
│ ├── Geocoder
│ │ └── Geocoder.php
│ └── CreateBioForm.php
├── Casts
│ ├── Coordinates.php
│ └── Url.php
├── Providers
│ ├── CaptchaServiceProvider.php
│ ├── BusServiceProvider.php
│ ├── ConfigServiceProvider.php
│ └── EventServiceProvider.php
├── CallingAllPapers
│ └── Client.php
├── macros.php
├── Mail
│ └── ContactRequest.php
├── Console
│ └── Commands
│ │ ├── VerifyConferenceImporterHeartbeat.php
│ │ └── SendNotificationForOpenCFPs.php
├── Notifications
│ ├── ConferenceImporterInactive.php
│ ├── NewConference.php
│ ├── ConferenceImporterError.php
│ ├── NewUser.php
│ ├── ConferenceIssueReported.php
│ └── CFPsAreOpen.php
├── ApiResources
│ ├── Me.php
│ ├── Bio.php
│ └── Conference.php
└── Transformers
│ └── TalkForConferenceTransformer.php
├── database
├── migrations
│ ├── .gitkeep
│ ├── 2024_07_02_000000_rename_password_resets_table.php
│ ├── 2019_04_19_142914_create_password_resets_table.php
│ ├── 2019_04_19_142914_create_oauth_personal_access_clients_table.php
│ ├── 2022_08_25_164159_add_soft_deletes_to_conferences_table.php
│ ├── 2021_11_10_115054_add_reason_to_rejections_table.php
│ ├── 2019_04_19_142914_create_favorites_table.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_bios_table.php
│ ├── 2021_11_10_115106_add_reason_to_acceptances_table.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_talks_table.php
│ ├── 2020_01_09_104729_add_featured_column_to_users_table.php
│ ├── 2021_03_29_153621_add_provider_to_oauth_clients_table.php
│ ├── 2020_01_09_122305_add_featured_column_to_conferences_table.php
│ ├── 2022_07_21_193843_add_speaker_packages_column_to_conferences_table.php
│ ├── 2024_12_20_115249_add_location_name_to_conferences_table.php
│ ├── 2022_11_11_132039_add_rejected_at_column_to_conferences_table.php
│ ├── 2019_04_19_142914_create_oauth_refresh_tokens_table.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_conferences_table.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_users_social_table.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_talk_revisions_table.php
│ ├── 2021_10_13_143629_add_rejection_id_to_submissions_table.php
│ ├── 2019_04_19_142914_create_users_social_table.php
│ ├── 2021_11_22_161401_add_has_cfp_column_to_conferences_table.php
│ ├── 2022_05_25_101856_create_talk_reactions_table.php
│ ├── 2019_04_19_142914_create_dismissed_conferences_table.php
│ ├── 2019_08_20_094313_extend_cap_id_field_by_four_characters_for_the_year.php
│ ├── 2019_04_19_142914_create_talks_table.php
│ ├── 2019_04_19_142914_create_bios_table.php
│ ├── 2019_04_19_142914_create_failed_jobs_table.php
│ ├── 2019_04_19_142914_create_oauth_auth_codes_table.php
│ ├── 2019_04_19_142914_create_acceptances_table.php
│ ├── 2019_10_25_152352_add_conference_location.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_favorites_table.php
│ ├── 2019_04_19_142914_create_oauth_access_tokens_table.php
│ ├── 2019_04_19_142914_create_oauth_clients_table.php
│ ├── 2019_04_19_142914_create_submissions_table.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_acceptances_table.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_dismissed_conferences_table.php
│ ├── 2022_08_23_145646_create_conference_issues_table.php
│ ├── 2020_10_30_131213_rename_featured_columns_to_is_featured.php
│ ├── 2021_10_28_000000_add_uuid_to_failed_jobs_table.php
│ ├── 2019_04_19_142914_create_talk_revisions_table.php
│ ├── 2023_03_31_000348_add_admin_note_column_to_conference_issues_table.php
│ ├── 2019_05_09_222406_drop_joindin_add_cap.php
│ ├── 2019_04_19_142915_add_foreign_keys_to_submissions_table.php
│ ├── 2021_10_13_142431_create_rejections_table.php
│ └── 2019_04_19_142914_create_conferences_table.php
├── seeders
│ ├── .gitkeep
│ ├── UsersSeeder.php
│ ├── AcceptanceSeeder.php
│ ├── SubmissionsSeeder.php
│ ├── RejectionSeeder.php
│ ├── ConferencesSeeder.php
│ ├── DatabaseSeeder.php
│ └── BiosSeeder.php
├── .gitignore
└── factories
│ ├── UserSocialFactory.php
│ ├── RejectionFactory.php
│ ├── AcceptanceFactory.php
│ ├── BioFactory.php
│ ├── TalkRevisionFactory.php
│ └── ConferenceIssueFactory.php
├── .gitattributes
├── bootstrap
├── cache
│ └── .gitignore
└── providers.php
├── storage
├── logs
│ └── .gitignore
├── app
│ ├── .gitignore
│ └── private
│ │ └── .gitignore
├── .gitignore
└── framework
│ ├── cache
│ ├── data
│ │ └── .gitignore
│ └── .gitignore
│ ├── views
│ └── .gitignore
│ ├── sessions
│ └── .gitignore
│ └── .gitignore
├── public
├── robots.txt
├── favicon.ico
├── img
│ ├── missing.png
│ ├── placekitten.jpg
│ ├── pronto-logo.png
│ ├── joindin-button.png
│ ├── symposium-logo.png
│ ├── symposium-banner.png
│ ├── symposium-screenshot.png
│ └── profile_pictures
│ │ ├── missing.png
│ │ └── hires
│ │ └── missing.png
├── mix-manifest.json
├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ ├── glyphicons-halflings-regular.woff2
│ └── vendor
│ │ └── bootstrap-sass
│ │ └── bootstrap
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.ttf
│ │ └── glyphicons-halflings-regular.woff
├── index.php
└── .htaccess
├── symposium-banner.png
├── tests
├── stubs
│ └── test.jpg
├── Api
│ ├── JsonApiTest.php
│ ├── ApiTestCase.php
│ └── MeApiTest.php
├── Unit
│ ├── SpeakerPackageTest.php
│ ├── UserTest.php
│ ├── TalkRevisionTest.php
│ ├── ContactRequestTest.php
│ └── Notifications
│ │ ├── ConferenceImporterErrorTest.php
│ │ ├── ConferenceImporterInactiveTest.php
│ │ ├── CFPsAreOpenTest.php
│ │ ├── NewConferenceTest.php
│ │ └── ConferenceIssueReportedTest.php
├── TestCase.php
└── Feature
│ ├── VerifyConferenceImporterHeartbeatTest.php
│ ├── HomeTest.php
│ ├── ConferenceIssuesTest.php
│ └── SyncCallingAllPapersEventsTest.php
├── resources
├── views
│ ├── bios
│ │ ├── listing-empty.blade.php
│ │ ├── index.blade.php
│ │ ├── show-public.blade.php
│ │ ├── form.blade.php
│ │ ├── listing.blade.php
│ │ ├── create.blade.php
│ │ ├── edit.blade.php
│ │ └── show.blade.php
│ ├── talks
│ │ ├── listing-empty.blade.php
│ │ ├── create.blade.php
│ │ ├── edit.blade.php
│ │ ├── show-public.blade.php
│ │ └── listing.blade.php
│ ├── auth
│ │ ├── emails
│ │ │ └── password.blade.php
│ │ ├── login.blade.php
│ │ ├── passwords
│ │ │ ├── email.blade.php
│ │ │ └── reset.blade.php
│ │ └── no-signups.blade.php
│ ├── components
│ │ ├── notice
│ │ │ ├── info.blade.php
│ │ │ ├── error.blade.php
│ │ │ ├── success.blade.php
│ │ │ └── index.blade.php
│ │ ├── alert
│ │ │ ├── warning.blade.php
│ │ │ └── index.blade.php
│ │ ├── tag
│ │ │ ├── success.blade.php
│ │ │ └── index.blade.php
│ │ ├── heading
│ │ │ └── list-item.blade.php
│ │ ├── input
│ │ │ ├── upload.blade.php
│ │ │ ├── date.blade.php
│ │ │ ├── group.blade.php
│ │ │ ├── textarea.blade.php
│ │ │ ├── radios.blade.php
│ │ │ ├── toggle.blade.php
│ │ │ └── text.blade.php
│ │ ├── menu
│ │ │ ├── item.blade.php
│ │ │ └── index.blade.php
│ │ ├── nav-item.blade.php
│ │ ├── button
│ │ │ ├── icon.blade.php
│ │ │ ├── secondary.blade.php
│ │ │ ├── primary.blade.php
│ │ │ ├── mobile-nav.blade.php
│ │ │ └── base.blade.php
│ │ ├── form.blade.php
│ │ ├── info.blade.php
│ │ ├── mobile-nav-item.blade.php
│ │ ├── modal
│ │ │ └── add-talk-reaction.blade.php
│ │ ├── listing.blade.php
│ │ ├── panel
│ │ │ └── index.blade.php
│ │ └── side-menu.blade.php
│ ├── conferences
│ │ ├── listing-empty.blade.php
│ │ ├── showPublic.blade.php
│ │ ├── create.blade.php
│ │ ├── show.blade.php
│ │ ├── issues
│ │ │ └── create.blade.php
│ │ └── edit.blade.php
│ ├── partials
│ │ ├── authentication-errors.blade.php
│ │ ├── flash-messages.blade.php
│ │ └── footer.blade.php
│ ├── emails
│ │ ├── open-cfps.blade.php
│ │ ├── newsignup.blade.php
│ │ └── public-profile-contact.blade.php
│ ├── account
│ │ ├── oauth-settings.blade.php
│ │ └── confirm-delete.blade.php
│ └── layouts
│ │ └── index.blade.php
├── svg
│ ├── arrow-thick-left.svg
│ ├── folder.svg
│ ├── trash.svg
│ ├── plus.svg
│ ├── compose.svg
│ ├── folder-outline.svg
│ ├── star-full.svg
│ ├── close.svg
│ ├── flag.svg
│ ├── clipboard.svg
│ ├── link.svg
│ ├── star-empty.svg
│ ├── logo.svg
│ ├── dropdown.svg
│ ├── map-pin.svg
│ ├── calendar.svg
│ ├── chevron-left.svg
│ ├── chevron-right.svg
│ ├── rectangle.svg
│ ├── check-circle.svg
│ ├── user-group.svg
│ ├── github.svg
│ ├── circle.svg
│ ├── dots.svg
│ ├── icon_find.svg
│ ├── icon_versioncontrol.svg
│ ├── icon_trackconferences.svg
│ └── icon_tracktalks.svg
├── css
│ ├── calendar.css
│ ├── app.css
│ └── mobile-menu-button.css
└── js
│ ├── components
│ ├── ModalToggle.vue
│ ├── CfpFields.vue
│ ├── CurrencySelection.vue
│ ├── LoadingSpinner.vue
│ ├── MenuToggle.vue
│ └── UpdateQueryString.vue
│ └── directives
│ └── Dismiss.js
├── .github
├── screenshots
│ ├── talks-page.png
│ ├── conference-list.png
│ ├── symposium-calendar.png
│ └── symposium-dashboard.png
└── workflows
│ └── lint.yml
├── phpspec.yml
├── postcss.config.cjs
├── .editorconfig
├── lang
└── en
│ └── conference.php
├── artisan
├── .gitignore
├── routes
├── console.php
└── api.php
├── vite.config.js
├── google-guide.md
├── LICENSE.md
└── .env.example
/.nvmrc:
--------------------------------------------------------------------------------
1 | 18.20.3
2 |
--------------------------------------------------------------------------------
/config/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/Handlers/Events/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/migrations/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/seeders/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/app/Handlers/Commands/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/.gitignore:
--------------------------------------------------------------------------------
1 | *.sqlite
2 |
--------------------------------------------------------------------------------
/bootstrap/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/storage/logs/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/storage/app/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !private/
3 | !.gitignore
--------------------------------------------------------------------------------
/storage/app/private/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/.gitignore:
--------------------------------------------------------------------------------
1 | laravel.log
2 | database.sqlite
3 |
--------------------------------------------------------------------------------
/storage/framework/cache/data/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/storage/framework/views/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/sessions/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/storage/framework/cache/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !data/
3 | !.gitignore
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/app/Events/Event.php:
--------------------------------------------------------------------------------
1 |
2 | No bios yet.
3 |
4 |
--------------------------------------------------------------------------------
/resources/views/talks/listing-empty.blade.php:
--------------------------------------------------------------------------------
1 |
2 | No talks yet.
3 |
4 |
--------------------------------------------------------------------------------
/public/img/joindin-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/img/joindin-button.png
--------------------------------------------------------------------------------
/public/img/symposium-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/img/symposium-logo.png
--------------------------------------------------------------------------------
/public/mix-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "/js/app.js": "/js/app.js",
3 | "/css/app.css": "/css/app.css"
4 | }
5 |
--------------------------------------------------------------------------------
/public/img/symposium-banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/img/symposium-banner.png
--------------------------------------------------------------------------------
/.github/screenshots/talks-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/.github/screenshots/talks-page.png
--------------------------------------------------------------------------------
/config/logging.php:
--------------------------------------------------------------------------------
1 | [
6 | //
7 | ],
8 |
9 | ];
10 |
--------------------------------------------------------------------------------
/resources/views/auth/emails/password.blade.php:
--------------------------------------------------------------------------------
1 | Click here to reset your password: {{ url('password/reset/' . $token) }}
2 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 |
2 | {{ $slot }}
3 |
4 |
--------------------------------------------------------------------------------
/.github/screenshots/conference-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/.github/screenshots/conference-list.png
--------------------------------------------------------------------------------
/phpspec.yml:
--------------------------------------------------------------------------------
1 | suites:
2 | main:
3 | namespace: Symposium
4 | psr4_prefix: Symposium
5 | src_path: app
6 |
--------------------------------------------------------------------------------
/public/img/profile_pictures/missing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/img/profile_pictures/missing.png
--------------------------------------------------------------------------------
/resources/views/components/alert/warning.blade.php:
--------------------------------------------------------------------------------
1 |
2 | {{ $slot }}
3 |
4 |
--------------------------------------------------------------------------------
/resources/views/components/notice/error.blade.php:
--------------------------------------------------------------------------------
1 |
2 | {{ $slot }}
3 |
4 |
--------------------------------------------------------------------------------
/resources/views/components/notice/success.blade.php:
--------------------------------------------------------------------------------
1 |
2 | {{ $slot }}
3 |
4 |
--------------------------------------------------------------------------------
/resources/views/components/tag/success.blade.php:
--------------------------------------------------------------------------------
1 |
2 | {{ $slot }}
3 |
4 |
--------------------------------------------------------------------------------
/resources/views/conferences/listing-empty.blade.php:
--------------------------------------------------------------------------------
1 |
2 | No conferences match this filter
3 |
4 |
--------------------------------------------------------------------------------
/.github/screenshots/symposium-calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/.github/screenshots/symposium-calendar.png
--------------------------------------------------------------------------------
/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/.github/screenshots/symposium-dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/.github/screenshots/symposium-dashboard.png
--------------------------------------------------------------------------------
/resources/svg/arrow-thick-left.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/public/img/profile_pictures/hires/missing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/img/profile_pictures/hires/missing.png
--------------------------------------------------------------------------------
/resources/views/components/alert/index.blade.php:
--------------------------------------------------------------------------------
1 |
class([
2 | 'mb-5 p-4 rounded'
3 | ]) }}>
4 | {{ $slot }}
5 |
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 4
9 |
--------------------------------------------------------------------------------
/resources/svg/folder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/svg/trash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/svg/plus.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/app/Http/Requests/Request.php:
--------------------------------------------------------------------------------
1 | [
6 |
7 | 'github' => [
8 | 'name' => 'GitHub',
9 | ],
10 |
11 | ],
12 |
13 | ];
14 |
--------------------------------------------------------------------------------
/resources/svg/compose.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/svg/folder-outline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/resources/svg/star-full.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eventyio/symposium/HEAD/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: Coding Standards
2 |
3 | on: [push]
4 |
5 | permissions:
6 | contents: write
7 |
8 | jobs:
9 | lint:
10 | uses: laravel/.github/.github/workflows/coding-standards.yml@main
11 |
--------------------------------------------------------------------------------
/resources/views/components/heading/list-item.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'href',
3 | ])
4 |
5 |
10 |
--------------------------------------------------------------------------------
/resources/views/partials/authentication-errors.blade.php:
--------------------------------------------------------------------------------
1 | @if ($errors->count() > 0)
2 |
3 | @foreach ($errors->all() as $error)
4 | {{ $error }}
5 | @endforeach
6 |
7 | @endif
8 |
--------------------------------------------------------------------------------
/resources/svg/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/config/auth.php:
--------------------------------------------------------------------------------
1 | [
6 | 'api' => [
7 | 'driver' => 'passport',
8 | 'provider' => 'users',
9 | 'hash' => false,
10 | ],
11 | ],
12 |
13 | ];
14 |
--------------------------------------------------------------------------------
/bootstrap/providers.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/resources/svg/clipboard.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/views/components/tag/index.blade.php:
--------------------------------------------------------------------------------
1 | merge([
3 | 'class' => 'font-medium leading-4 rounded-lg text-xs whitespace-nowrap',
4 | 'style' => 'padding: 2px 10px;'
5 | ]) }}
6 | >
7 | {{ $slot }}
8 |
9 |
--------------------------------------------------------------------------------
/resources/views/emails/open-cfps.blade.php:
--------------------------------------------------------------------------------
1 | @component('mail::message')
2 | The following CFPs are now open:
3 |
4 | @foreach ($conferences as $conference)
5 | - [{{ $conference->title }}]({{ $conference->cfp_url ?: $conference->url }})
6 | @endforeach
7 | @endcomponent
8 |
--------------------------------------------------------------------------------
/resources/views/emails/newsignup.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | New User Signup
8 |
9 |
10 | New user signed up: {{ $email }}
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/Models/TalkReaction.php:
--------------------------------------------------------------------------------
1 |
11 |
12 | @isset($help)
13 | {{ $help }}
14 | @endisset
15 |
--------------------------------------------------------------------------------
/lang/en/conference.php:
--------------------------------------------------------------------------------
1 | [
5 | 'duplicate' => 'This is a duplicate conference',
6 | 'incorrect' => 'This conference has missing or incorrect information',
7 | 'spam' => 'This is a spam listing',
8 | 'other' => 'Other',
9 | ],
10 | ];
11 |
--------------------------------------------------------------------------------
/database/factories/UserSocialFactory.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/svg/star-empty.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/resources/views/account/oauth-settings.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'OAuth settings'])
2 |
3 | @section('content')
4 |
5 |
6 |
7 |
8 |
9 | @endsection
10 |
--------------------------------------------------------------------------------
/app/Models/UserSocial.php:
--------------------------------------------------------------------------------
1 | null,
3 | 'route' => null,
4 | 'show' => true,
5 | ])
6 |
7 | @if ($show)
8 |
12 | {{ $slot }}
13 |
14 | @endif
15 |
--------------------------------------------------------------------------------
/resources/views/components/nav-item.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'route',
3 | ])
4 |
5 |
14 | {{ $slot }}
15 |
16 |
--------------------------------------------------------------------------------
/resources/svg/logo.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/views/components/button/icon.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'href' => null,
3 | 'icon' => null,
4 | ])
5 |
6 | @php
7 | $element = isset($href) ? 'a' : 'button';
8 | @endphp
9 |
10 | <{{ $element }}
11 | @isset($href) href="{{ $href }}" @endisset
12 | {{ $attributes->class('leading-none') }}
13 | >
14 | @svg($icon, 'fill-current inline w-5')
15 | {{ $element }}>
16 |
--------------------------------------------------------------------------------
/resources/views/components/button/secondary.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'href' => null,
3 | 'icon' => null,
4 | 'size' => 'sm',
5 | ])
6 |
7 |
15 | {{ $slot }}
16 |
17 |
--------------------------------------------------------------------------------
/resources/views/conferences/showPublic.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 | @if ($conference->isFlagged())
6 | An issue has been reported for this conference.
7 | @endif
8 |
9 |
12 |
13 |
14 |
15 |
16 | @endsection
17 |
--------------------------------------------------------------------------------
/app/helpers.php:
--------------------------------------------------------------------------------
1 | '.(new Parsedown)->text($text).'';
7 | }
8 | }
9 |
10 | if (! function_exists('menuRoute')) {
11 | function menuRoute($name, $parameters = [], $absolute = true)
12 | {
13 | return app('url')->menuRoute($name, $parameters, $absolute);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/resources/views/bios/index.blade.php:
--------------------------------------------------------------------------------
1 | @extends('layouts.index', ['title' => 'All Bios'])
2 |
3 | @section('actions')
4 |
9 | Add Bio
10 |
11 | @endsection
12 |
13 | @section('list')
14 | @each('bios.listing', $bios, 'bio', 'bios.listing-empty')
15 | @endsection
16 |
--------------------------------------------------------------------------------
/app/Collections/TalksCollection.php:
--------------------------------------------------------------------------------
1 | sortBy(function (Talk $talk) {
13 | return strtolower($talk->currentRevision->title);
14 | })->values();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/resources/svg/dropdown.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/svg/map-pin.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/views/components/button/primary.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'href' => null,
3 | 'icon' => null,
4 | 'size' => 'sm',
5 | ])
6 |
7 |
15 | {{ $slot }}
16 |
17 |
--------------------------------------------------------------------------------
/resources/views/components/notice/index.blade.php:
--------------------------------------------------------------------------------
1 | class([
3 | 'cursor-pointer fixed inset-x-0 lg:inset-x-auto mx-auto p-4 lg:right-4 rounded text-center top-32 w-4/5 lg:w-1/5 z-50'
4 | ]) }}
5 | v-dismiss="2000"
6 | >
7 |
10 | {{ $slot }}
11 |
12 |
--------------------------------------------------------------------------------
/resources/views/components/form.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'action',
3 | 'upload' => false,
4 | ])
5 |
6 |
18 |
--------------------------------------------------------------------------------
/resources/views/components/info.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'icon' => null,
3 | 'iconColor' => 'text-gray-500',
4 | 'textColor' => 'text-gray-500',
5 | ])
6 |
7 | merge([
8 | 'class' => "{$iconColor} text-sm flex items-center"
9 | ]) }}>
10 | @if ($icon)
11 | @svg($icon, 'inline fill-current w-4 mr-1')
12 | @endif
13 |
14 | {{ $slot }}
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/Exceptions/ValidationException.php:
--------------------------------------------------------------------------------
1 | errors = $errors;
16 | }
17 |
18 | public function errors()
19 | {
20 | return $this->errors;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/Models/TightenSlack.php:
--------------------------------------------------------------------------------
1 | [
6 | 'mailgun' => [
7 | 'transport' => 'mailgun',
8 | // 'client' => [
9 | // 'timeout' => 5,
10 | // ],
11 | ],
12 |
13 | 'roundrobin' => [
14 | 'transport' => 'roundrobin',
15 | 'mailers' => [
16 | 'ses',
17 | 'postmark',
18 | ],
19 | ],
20 | ],
21 |
22 | ];
23 |
--------------------------------------------------------------------------------
/database/factories/RejectionFactory.php:
--------------------------------------------------------------------------------
1 | TalkRevision::factory(),
15 | 'conference_id' => Conference::factory(),
16 | ];
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/resources/svg/calendar.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/MeController.php:
--------------------------------------------------------------------------------
1 | guard('api')->user());
14 |
15 | return response()->jsonApi([
16 | 'data' => $me->toArray(),
17 | ]);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/Http/Controllers/HomeController.php:
--------------------------------------------------------------------------------
1 | User::whereFeatured()->limit(6)->get(),
15 | 'conferences' => Conference::whereFeatured()->limit(3)->get(),
16 | ]);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/database/factories/AcceptanceFactory.php:
--------------------------------------------------------------------------------
1 | TalkRevision::factory(),
15 | 'conference_id' => Conference::factory(),
16 | ];
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/database/migrations/2024_07_02_000000_rename_password_resets_table.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/Policies/ConferencePolicy.php:
--------------------------------------------------------------------------------
1 | isAdmin()) {
16 | return true;
17 | }
18 |
19 | return $conference->author_id == $user->id;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/artisan:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | handleCommand(new ArgvInput);
17 |
18 | exit($status);
19 |
--------------------------------------------------------------------------------
/resources/svg/chevron-right.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/resources/svg/rectangle.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/resources/views/components/button/mobile-nav.blade.php:
--------------------------------------------------------------------------------
1 |
5 |
15 |
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /vendor
3 | .env
4 | .sass-cache/
5 | /storage/*.key
6 | /storage/pail
7 | /public/css/app.css
8 | /public/css/app.css.map
9 | /public/css/filament
10 | /public/js/app.js
11 | /public/js/app.js.map
12 | /public/js/filament
13 | /public/js/location.js
14 | /public/js/location.js.map
15 | /public/storage
16 | /storage/debugbar
17 | /storage/framework/testing
18 | /.phpunit.cache
19 | /.phpunit.result.cache
20 | .idea/*
21 | phpunit.xml
22 | /public/build
23 | /public/hot
24 | /.nova
25 |
--------------------------------------------------------------------------------
/resources/views/emails/public-profile-contact.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Contact from your public profile page on Symposium
8 |
9 |
10 | Email: {{ $email }}
11 | Name: {{ $name }}
12 | Message:
13 |
14 | {!! str_replace("\n", "
", htmlentities($userMessage)) !!}
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tests/Api/JsonApiTest.php:
--------------------------------------------------------------------------------
1 | call('GET', '/api/user/1/talks');
13 |
14 | $this->assertEquals(200, $response->getStatusCode());
15 | $this->assertEquals('application/vnd.api+json', $response->headers->get('Content-Type'));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/Filament/Resources/ConferenceResource/Pages/ListConferences.php:
--------------------------------------------------------------------------------
1 |
3 | {{ Session::get('success-message', 'success') }}
4 |
5 | @endif
6 |
7 | @if (Session::has('error-message'))
8 |
9 | {{ Session::get('error-message') }}
10 |
11 | @endif
12 |
13 | @if (Session::has('message'))
14 |
15 | {{ Session::get('message') }}
16 |
17 | @endif
18 |
--------------------------------------------------------------------------------
/resources/css/calendar.css:
--------------------------------------------------------------------------------
1 | #calendar button {
2 | @apply bg-indigo-500 text-white h-auto shadow-none;
3 | }
4 |
5 | #calendar .fc-button-group {
6 | @apply rounded overflow-hidden;
7 | }
8 |
9 | #calendar .fc-button-group button {
10 | @apply bg-indigo rounded-none;
11 | }
12 |
13 | #calendar .fc-button-group button.fc-button-active {
14 | @apply bg-indigo-900;
15 | }
16 |
17 | #calendar .fc-event-title {
18 | @apply p-1;
19 | }
20 |
21 | #calendar .fc-popover-close:after {
22 | @apply hidden;
23 | }
24 |
--------------------------------------------------------------------------------
/resources/views/bios/show-public.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 |
6 |
11 | Return to profile for {{ $user->name }}
12 |
13 |
14 | {{ $bio->nickname }}
15 |
16 | {!! str_replace("\n", "
", $bio->body) !!}
17 |
18 |
19 | @endsection
20 |
--------------------------------------------------------------------------------
/app/Services/FakeCaptcha.php:
--------------------------------------------------------------------------------
1 | valid;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/resources/js/components/ModalToggle.vue:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/resources/views/bios/form.blade.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
13 |
14 |
23 |
--------------------------------------------------------------------------------
/app/Casts/Coordinates.php:
--------------------------------------------------------------------------------
1 | latitude = $latitude;
14 | $this->longitude = $longitude;
15 | }
16 |
17 | public function getLatitude()
18 | {
19 | return $this->latitude;
20 | }
21 |
22 | public function getLongitude()
23 | {
24 | return $this->longitude;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/resources/views/bios/listing.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | @svg('compose', 'w-5 fill-current inline')
5 |
6 |
7 | @svg('trash', 'w-5 fill-current inline')
8 |
9 |
10 | {{ $bio->nickname }}
11 |
12 |
--------------------------------------------------------------------------------
/app/Filament/Resources/ConferenceIssueResource/Pages/ListConferenceIssues.php:
--------------------------------------------------------------------------------
1 | create([
15 | 'name' => 'Matt Stauffer',
16 | 'email' => 'matt@savemyproposals.com',
17 | ]);
18 |
19 | User::factory()->count(10)->create([
20 | 'is_featured' => rand(0, 1),
21 | ]);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/resources/views/conferences/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Create Conference'])
2 |
3 | @section('content')
4 |
5 |
6 | @foreach ($errors->all() as $message)
7 | - {{ $message }}
8 | @endforeach
9 |
10 |
11 |
12 | @include('conferences.form')
13 |
14 |
19 | Create
20 |
21 |
22 |
23 | @endsection
24 |
--------------------------------------------------------------------------------
/app/Http/Controllers/RejectionController.php:
--------------------------------------------------------------------------------
1 | user()->id != $rejection->submission->talkRevision->talk->author_id) {
12 | return response('', 401);
13 | }
14 |
15 | $rejection->delete();
16 |
17 | return response()->json(['status' => 'success', 'message' => 'Talk un-marked as rejected.']);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/resources/svg/check-circle.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/app/Http/Controllers/SubmissionReactionsController.php:
--------------------------------------------------------------------------------
1 | validate([
13 | 'url' => 'required|url',
14 | ]);
15 |
16 | $submission->addReaction(request('url'));
17 |
18 | return redirect()->route('submission.edit', $submission);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/Http/Middleware/Social.php:
--------------------------------------------------------------------------------
1 | service), array_keys(config('social.services')))) {
17 | return redirect()->back();
18 | }
19 |
20 | return $next($request);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/Http/Controllers/AcceptancesController.php:
--------------------------------------------------------------------------------
1 | user()->id != $acceptance->submission->talkRevision->talk->author_id) {
12 | return response('', 401);
13 | }
14 |
15 | $acceptance->delete();
16 |
17 | return response()->json(['status' => 'success', 'message' => 'Talk un-marked as accepted.']);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/resources/views/bios/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Add Bio'])
2 |
3 | @section('content')
4 |
5 |
6 | @foreach ($errors->all() as $message)
7 | - {{ $message }}
8 | @endforeach
9 |
10 |
11 |
12 |
13 | @include('bios.form')
14 |
15 |
16 |
21 | Create
22 |
23 |
24 |
25 | @endsection
26 |
--------------------------------------------------------------------------------
/resources/views/talks/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Add Talk'])
2 |
3 | @section('content')
4 |
5 |
6 | @foreach ($errors->all() as $message)
7 | - {{ $message }}
8 | @endforeach
9 |
10 |
11 |
12 |
13 | @include('talks.form')
14 |
15 |
16 |
21 | Create
22 |
23 |
24 |
25 | @endsection
26 |
--------------------------------------------------------------------------------
/resources/css/app.css:
--------------------------------------------------------------------------------
1 | @import "./calendar";
2 | @import "./mobile-menu-button";
3 |
4 | @tailwind base;
5 | @tailwind components;
6 | @tailwind utilities;
7 |
8 | [v-cloak] {
9 | display: none;
10 | }
11 |
12 | .caret {
13 | border-top: 4px solid;
14 | border-right: 4px solid transparent;
15 | border-left: 4px solid transparent;
16 | }
17 |
18 | @keyframes spin {
19 | from { transform: scale(1) rotate(0deg);}
20 | to { transform: scale(1) rotate(360deg);}
21 | }
22 |
23 | .toggle-checkbox:checked + .toggle-label {
24 | @apply text-indigo-900 bg-indigo-900;
25 | }
26 |
--------------------------------------------------------------------------------
/resources/svg/user-group.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/tests/Api/ApiTestCase.php:
--------------------------------------------------------------------------------
1 | user = User::first();
24 | Passport::actingAs($this->user);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/Providers/CaptchaServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->bind(Captcha::class, function () {
13 | $captcha = new Captcha;
14 | $captcha->setPublicKey(config('services.google.captcha.public'));
15 | $captcha->setPrivateKey(config('services.google.captcha.private'));
16 |
17 | return $captcha;
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/resources/views/bios/edit.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Edit Bio'])
2 |
3 | @section('content')
4 |
5 |
6 | @foreach ($errors->all() as $message)
7 | - {{ $message }}
8 | @endforeach
9 |
10 |
11 |
12 |
13 | @include('bios.form')
14 |
15 |
16 |
21 | Update
22 |
23 |
24 |
25 | @endsection
26 |
--------------------------------------------------------------------------------
/app/Providers/BusServiceProvider.php:
--------------------------------------------------------------------------------
1 | mapUsing(function ($command) {
13 | return Dispatcher::simpleMapping(
14 | $command,
15 | 'App\Commands',
16 | 'App\Handlers\Commands'
17 | );
18 | });
19 | }
20 |
21 | public function register(): void {}
22 | }
23 |
--------------------------------------------------------------------------------
/resources/svg/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/views/auth/login.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 |
6 | Log in
7 |
17 | @include('partials.log-in-form')
18 |
19 |
20 | @endsection
21 |
--------------------------------------------------------------------------------
/resources/views/talks/edit.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Edit Talk'])
2 |
3 | @section('content')
4 |
5 |
6 | @foreach ($errors->all() as $message)
7 | - {{ $message }}
8 | @endforeach
9 |
10 |
11 |
12 |
13 | @include('talks.form')
14 |
15 |
16 |
21 | Update
22 |
23 |
24 |
25 | @endsection
26 |
--------------------------------------------------------------------------------
/app/Casts/Url.php:
--------------------------------------------------------------------------------
1 | comment(Inspiring::quote());
9 | })->purpose('Display an inspiring quote')->hourly();
10 |
11 | Schedule::command('callingallpapers:sync')
12 | ->hourly();
13 |
14 | Schedule::command('symposium:notifyCfps')
15 | ->dailyAt('08:00')
16 | ->environments('production');
17 |
18 | Schedule::command('verify-conference-importer-heartbeat')
19 | ->dailyAt('10:00')
20 | ->environments('production');
21 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | handleRequest(Request::capture());
21 |
--------------------------------------------------------------------------------
/app/CallingAllPapers/Client.php:
--------------------------------------------------------------------------------
1 | get())->cfps)->map(function ($cfpFromApi) {
12 | return Event::createFromApiObject($cfpFromApi);
13 | });
14 | }
15 |
16 | private function get()
17 | {
18 | return Http::withHeaders(['User-Agent' => 'Symposium CLI'])
19 | ->get('https://api.callingallpapers.com/v1/cfp')
20 | ->getBody()
21 | ->getContents();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_password_resets_table.php:
--------------------------------------------------------------------------------
1 | string('email')->index();
12 | $table->string('token')->index();
13 | $table->dateTime('created_at')->nullable();
14 | });
15 | }
16 |
17 | public function down(): void
18 | {
19 | Schema::drop('password_resets');
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/app/Providers/ConfigServiceProvider.php:
--------------------------------------------------------------------------------
1 | 'usd',
16 | 'food' => 1000,
17 | 'travel' => 0,
18 | ]);
19 |
20 | $this->assertEquals('10.00', $speakerPackage->toDecimal('food'));
21 | $this->assertEquals(null, $speakerPackage->toDecimal('travel'));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/Services/Currency.php:
--------------------------------------------------------------------------------
1 | filter(function ($item) {
14 | return Money::isValidCurrency($item);
15 | })
16 | ->map(function ($code) {
17 | return [
18 | 'code' => $code,
19 | 'symbol' => Currencies::getSymbol($code),
20 | ];
21 | })
22 | ->toArray();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_oauth_personal_access_clients_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
12 | $table->integer('client_id')->index();
13 | $table->timestamps();
14 | });
15 | }
16 |
17 | public function down(): void
18 | {
19 | Schema::drop('oauth_personal_access_clients');
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/resources/views/partials/footer.blade.php:
--------------------------------------------------------------------------------
1 | @php
2 | $styles = $is_home ? 'bg-black text-gray-500' : 'text-gray-600 bg-white border-t border-gray-300';
3 | @endphp
4 |
5 |
16 |
17 |
--------------------------------------------------------------------------------
/app/Models/Bio.php:
--------------------------------------------------------------------------------
1 | belongsTo(User::class);
24 | }
25 |
26 | public function scopePublic($query)
27 | {
28 | return $query->where('public', true);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/Models/UuidBase.php:
--------------------------------------------------------------------------------
1 | {$model->getKeyName()} = Uuid::uuid4()->toString();
26 | });
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/resources/views/components/mobile-nav-item.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'url',
3 | 'route',
4 | 'show' => true,
5 | ])
6 |
7 | @if ($show)
8 | @php
9 | $isActive = isset($url)
10 | ? request()->is(ltrim(parse_url($url, PHP_URL_PATH), '/'))
11 | : request()->isContainedBy($route);
12 | @endphp
13 |
22 | {{ $slot }}
23 |
24 | @endif
25 |
--------------------------------------------------------------------------------
/database/migrations/2022_08_25_164159_add_soft_deletes_to_conferences_table.php:
--------------------------------------------------------------------------------
1 | softDeletes()->after('updated_at');
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('conferences', function (Blueprint $table) {
19 | $table->dropSoftDeletes();
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/resources/views/components/modal/add-talk-reaction.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'submission',
3 | ])
4 |
5 |
6 |
7 |
12 | Add Talk Reaction
13 |
14 |
15 |
16 |
17 |
18 | Save
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tests/Unit/UserTest.php:
--------------------------------------------------------------------------------
1 | admin()->create();
19 | $user = User::factory()->nonAdmin()->create();
20 |
21 | $this->assertTrue($admin->canAccessPanel(new Panel));
22 | $this->assertFalse($user->canAccessPanel(new Panel));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/database/migrations/2021_11_10_115054_add_reason_to_rejections_table.php:
--------------------------------------------------------------------------------
1 | text('reason')->after('conference_id')->nullable();
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('rejections', function (Blueprint $table) {
19 | $table->dropColumn('reason');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_favorites_table.php:
--------------------------------------------------------------------------------
1 | integer('user_id')->unsigned()->index('favorites_user_id_foreign');
12 | $table->string('conference_id', 36)->index('favorites_conference_id_foreign');
13 | $table->timestamps();
14 | });
15 | }
16 |
17 | public function down(): void
18 | {
19 | Schema::drop('favorites');
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_bios_table.php:
--------------------------------------------------------------------------------
1 | foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
12 | });
13 | }
14 |
15 | public function down(): void
16 | {
17 | Schema::table('bios', function (Blueprint $table) {
18 | $table->dropForeign('bios_user_id_foreign');
19 | });
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/database/migrations/2021_11_10_115106_add_reason_to_acceptances_table.php:
--------------------------------------------------------------------------------
1 | text('reason')->after('conference_id')->nullable();
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('acceptances', function (Blueprint $table) {
19 | $table->dropColumn('reason');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_talks_table.php:
--------------------------------------------------------------------------------
1 | foreign('author_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
12 | });
13 | }
14 |
15 | public function down(): void
16 | {
17 | Schema::table('talks', function (Blueprint $table) {
18 | $table->dropForeign('talks_author_id_foreign');
19 | });
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/database/migrations/2020_01_09_104729_add_featured_column_to_users_table.php:
--------------------------------------------------------------------------------
1 | boolean('featured')->after('allow_profile_contact')->default(0);
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('users', function (Blueprint $table) {
19 | $table->dropColumn('featured');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/migrations/2021_03_29_153621_add_provider_to_oauth_clients_table.php:
--------------------------------------------------------------------------------
1 | string('provider')->after('secret')->nullable();
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('oauth_clients', function (Blueprint $table) {
19 | $table->dropColumn('provider');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/resources/js/directives/Dismiss.js:
--------------------------------------------------------------------------------
1 | function hideElement(el) {
2 | el.style.visibility = 'hidden';
3 | }
4 |
5 | function fadeElement(el, duration) {
6 | el.animate([{ opacity: 1 }, { opacity: 0 }], duration)
7 | .onfinish = () => hideElement(el);
8 | }
9 |
10 | function hideElementOnClick(el) {
11 | const listener = function clickHandler() {
12 | hideElement(el);
13 | el.removeEventListener('click', clickHandler);
14 | };
15 |
16 | el.addEventListener('click', listener);
17 | }
18 |
19 | export default {
20 | bind(el, binding) {
21 | setTimeout(() => fadeElement(el, 1000), binding.value);
22 | hideElementOnClick(el);
23 | },
24 | }
25 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import laravel from 'laravel-vite-plugin';
3 | import vue from '@vitejs/plugin-vue2';
4 |
5 | export default defineConfig({
6 | plugins: [
7 | laravel({
8 | input: ['resources/css/app.css', 'resources/js/app.js'],
9 | refresh: true,
10 | }),
11 | vue({
12 | template: {
13 | transformAssetUrls: {
14 | base: null,
15 | includeAbsolute: false,
16 | },
17 | },
18 | }),
19 | ],
20 | resolve: {
21 | alias: {
22 | vue: 'vue/dist/vue.js',
23 | },
24 | },
25 | });
26 |
--------------------------------------------------------------------------------
/database/migrations/2020_01_09_122305_add_featured_column_to_conferences_table.php:
--------------------------------------------------------------------------------
1 | boolean('featured')->after('author_id')->default(0);
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('conferences', function (Blueprint $table) {
19 | $table->dropColumn('featured');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/migrations/2022_07_21_193843_add_speaker_packages_column_to_conferences_table.php:
--------------------------------------------------------------------------------
1 | json('speaker_package')->nullable();
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('conferences', function (Blueprint $table) {
19 | $table->dropColumn('speaker_package');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/migrations/2024_12_20_115249_add_location_name_to_conferences_table.php:
--------------------------------------------------------------------------------
1 | string('location_name')->nullable()->after('location');
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('conferences', function (Blueprint $table) {
19 | $table->dropColumn('location_name');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/resources/views/auth/passwords/email.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Reset Password'])
2 |
3 | @section('content')
4 |
5 | @include('partials.authentication-errors')
6 |
7 |
27 |
28 | @endsection
29 |
--------------------------------------------------------------------------------
/database/migrations/2022_11_11_132039_add_rejected_at_column_to_conferences_table.php:
--------------------------------------------------------------------------------
1 | dateTime('rejected_at')->after('cfp_ends_at')->nullable();
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('conferences', function (Blueprint $table) {
19 | $table->dropColumn('rejected_at');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/resources/views/components/input/date.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'name',
3 | 'label',
4 | 'value' => null,
5 | ])
6 |
7 | only('v-model') }}
12 | >
13 |
14 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/BiosController.php:
--------------------------------------------------------------------------------
1 | guard('api')->user()->bios()->findOrFail($id);
17 | } catch (Exception $e) {
18 | App::abort(404);
19 | }
20 |
21 | $bio = new Bio($bio);
22 |
23 | return response()->jsonApi([
24 | 'data' => $bio->toArray(),
25 | ]);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_oauth_refresh_tokens_table.php:
--------------------------------------------------------------------------------
1 | string('id', 100)->primary();
12 | $table->string('access_token_id', 100)->index();
13 | $table->boolean('revoked');
14 | $table->dateTime('expires_at')->nullable();
15 | });
16 | }
17 |
18 | public function down(): void
19 | {
20 | Schema::drop('oauth_refresh_tokens');
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_conferences_table.php:
--------------------------------------------------------------------------------
1 | foreign('author_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
12 | });
13 | }
14 |
15 | public function down(): void
16 | {
17 | Schema::table('conferences', function (Blueprint $table) {
18 | $table->dropForeign('conferences_author_id_foreign');
19 | });
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_users_social_table.php:
--------------------------------------------------------------------------------
1 | foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('CASCADE');
12 | });
13 | }
14 |
15 | public function down(): void
16 | {
17 | Schema::table('users_social', function (Blueprint $table) {
18 | $table->dropForeign('users_social_user_id_foreign');
19 | });
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/resources/views/conferences/show.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('headerScripts')
4 |
7 | @endsection
8 |
9 | @section('content')
10 |
11 | @if ($conference->isFlagged())
12 | An issue has been reported for this conference.
13 | @endif
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | @endsection
25 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_talk_revisions_table.php:
--------------------------------------------------------------------------------
1 | foreign('talk_id')->references('id')->on('talks')->onUpdate('RESTRICT')->onDelete('CASCADE');
12 | });
13 | }
14 |
15 | public function down(): void
16 | {
17 | Schema::table('talk_revisions', function (Blueprint $table) {
18 | $table->dropForeign('talk_revisions_talk_id_foreign');
19 | });
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/resources/views/components/input/group.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'name' => null,
3 | 'label' => null,
4 | 'labelClass' => null,
5 | ])
6 |
7 | except('v-text')->class('flex items-center') }}
9 | >
10 | @if (isset($name) && isset($label))
11 |
17 | @endif
18 |
19 |
only('v-text') }}
22 | >
23 |
24 | {{ $slot }}
25 |
26 |
27 |
--------------------------------------------------------------------------------
/database/migrations/2021_10_13_143629_add_rejection_id_to_submissions_table.php:
--------------------------------------------------------------------------------
1 | string('rejection_id', 36)->nullable()->index('submissions_rejection_id_foreign');
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('submissions', function (Blueprint $table) {
19 | $table->dropColumn('rejection_id');
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/seeders/AcceptanceSeeder.php:
--------------------------------------------------------------------------------
1 | each(function ($submission) {
14 | if (mt_rand(0, 1)) {
15 | $acceptance = Acceptance::factory()->create([
16 | 'talk_revision_id' => $submission->talk_revision_id,
17 | 'conference_id' => $submission->conference_id,
18 | ]);
19 | $submission->recordAcceptance($acceptance);
20 | }
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_users_social_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
12 | $table->integer('user_id')->unsigned()->index('users_social_user_id_foreign');
13 | $table->string('social_id');
14 | $table->string('service');
15 | $table->timestamps();
16 | });
17 | }
18 |
19 | public function down(): void
20 | {
21 | Schema::drop('users_social');
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/resources/views/auth/no-signups.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 |
6 | No new signups
7 |
8 |
9 | This project is being closed down. Please try Eventy instead!
10 |
11 |
Return Home
12 |
13 |
14 |
15 | @endsection
16 |
--------------------------------------------------------------------------------
/database/migrations/2021_11_22_161401_add_has_cfp_column_to_conferences_table.php:
--------------------------------------------------------------------------------
1 | boolean('has_cfp')
13 | ->default(true)
14 | ->after('ends_at');
15 | });
16 | }
17 |
18 | public function down(): void
19 | {
20 | Schema::table('conferences', function (Blueprint $table) {
21 | $table->dropColumn('has_cfp');
22 | });
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/database/migrations/2022_05_25_101856_create_talk_reactions_table.php:
--------------------------------------------------------------------------------
1 | id();
14 | $table->foreignIdFor(Submission::class)->constrained();
15 | $table->string('url');
16 | $table->timestamps();
17 | });
18 | }
19 |
20 | public function down(): void
21 | {
22 | Schema::dropIfExists('talk_reactions');
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/resources/js/components/CfpFields.vue:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_dismissed_conferences_table.php:
--------------------------------------------------------------------------------
1 | integer('user_id')->unsigned()->index('dismissed_conferences_user_id_foreign');
12 | $table->string('conference_id', 36)->index('dismissed_conferences_conference_id_foreign');
13 | $table->timestamps();
14 | });
15 | }
16 |
17 | public function down(): void
18 | {
19 | Schema::drop('dismissed_conferences');
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/resources/css/mobile-menu-button.css:
--------------------------------------------------------------------------------
1 | .mobileMenuBtn {
2 | @apply relative flex justify-center items-center p-4;
3 | }
4 |
5 | .mobileMenuBtn:before, .mobileMenuBtn:after {
6 | @apply absolute block w-6 h-0.5 bg-white transition duration-75 ease-in-out;
7 | content: '';
8 | }
9 |
10 | .mobileMenuBtn:before {
11 | top: calc(50% - 6px);
12 | transform: translateY(-50%) rotate(0deg);
13 | }
14 |
15 | .mobileMenuBtn:after {
16 | bottom: calc(50% - 8px);
17 | transform: translateY(-50%) rotate(0deg);
18 | }
19 |
20 | .mobileMenuBtn.isActive:before {
21 | transform: translateY(calc(-50% + 8px)) rotate(45deg);
22 | }
23 |
24 | .mobileMenuBtn.isActive:after {
25 | transform: translateY(calc(-50% - 4px)) rotate(-45deg);
26 | }
27 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/TalksController.php:
--------------------------------------------------------------------------------
1 | guard('api')->user()->talks()->withCurrentRevision()->findOrFail($id);
17 | } catch (Exception $e) {
18 | App::abort(404);
19 | }
20 |
21 | $talk = new Talk($talk);
22 |
23 | return response()->jsonApi([
24 | 'data' => $talk->toArray(),
25 | ]);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | 'America/Detroit',
8 |
9 | 'slack_endpoint' => env('SLACK_ENDPOINT'),
10 |
11 | 'aliases' => Facade::defaultAliases()->merge([
12 | 'Gravatar' => Creativeorange\Gravatar\Facades\Gravatar::class,
13 | 'Image' => Intervention\Image\Facades\Image::class,
14 | 'Input' => Illuminate\Support\Facades\Input::class,
15 | 'Inspiring' => Illuminate\Foundation\Inspiring::class,
16 | 'Paginator' => Illuminate\Support\Facades\Paginator::class,
17 | 'Redis' => Illuminate\Support\Facades\Redis::class,
18 | 'Socialite' => Laravel\Socialite\Facades\Socialite::class,
19 | ])->toArray(),
20 |
21 | ];
22 |
--------------------------------------------------------------------------------
/database/migrations/2019_08_20_094313_extend_cap_id_field_by_four_characters_for_the_year.php:
--------------------------------------------------------------------------------
1 | string('calling_all_papers_id', 44)->nullable()->change();
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('conferences', function (Blueprint $table) {
19 | $table->string('calling_all_papers_id', 40)->nullable()->change();
20 | });
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/database/factories/BioFactory.php:
--------------------------------------------------------------------------------
1 | User::factory(),
14 | 'nickname' => $this->faker->word(),
15 | 'body' => $this->faker->sentence(),
16 | ];
17 | }
18 |
19 | public function public()
20 | {
21 | return $this->state([
22 | 'public' => true,
23 | ]);
24 | }
25 |
26 | public function private()
27 | {
28 | return $this->state([
29 | 'public' => false,
30 | ]);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/Http/Requests/SpeakerSearchRequest.php:
--------------------------------------------------------------------------------
1 | query('query')), function ($value) {
25 | $this->merge([
26 | 'query' => $value,
27 | 'original' => $this->query('query'),
28 | ]);
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_talks_table.php:
--------------------------------------------------------------------------------
1 | string('id', 36)->default('0')->unique();
12 | $table->integer('author_id')->unsigned()->index('talks_author_id_foreign');
13 | $table->timestamps();
14 | $table->boolean('public')->default(0);
15 | $table->boolean('is_archived')->default(0);
16 | });
17 | }
18 |
19 | public function down(): void
20 | {
21 | Schema::drop('talks');
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/resources/svg/circle.svg:
--------------------------------------------------------------------------------
1 |
2 |
13 |
--------------------------------------------------------------------------------
/resources/views/components/menu/index.blade.php:
--------------------------------------------------------------------------------
1 | merge(['class' => 'relative']) }}>
2 |
3 |
4 |
10 |
17 | {{ $items }}
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_bios_table.php:
--------------------------------------------------------------------------------
1 | string('id', 36)->unique();
12 | $table->string('nickname');
13 | $table->text('body', 65535);
14 | $table->integer('user_id')->unsigned()->index('bios_user_id_foreign');
15 | $table->timestamps();
16 | $table->boolean('public')->default(0);
17 | });
18 | }
19 |
20 | public function down(): void
21 | {
22 | Schema::drop('bios');
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/resources/js/components/CurrencySelection.vue:
--------------------------------------------------------------------------------
1 |
28 |
--------------------------------------------------------------------------------
/resources/js/components/LoadingSpinner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
28 |
--------------------------------------------------------------------------------
/resources/views/layouts/index.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 | @isset($title)
6 | {{ $title }}
7 | @endisset
8 |
9 |
10 |
11 | @hasSection('sidebar')
12 |
13 | @yield('sidebar')
14 |
15 | @endif
16 | @yield('actions')
17 |
18 |
19 |
20 | @yield('list')
21 |
22 |
23 |
24 |
25 | @endsection
26 |
--------------------------------------------------------------------------------
/app/macros.php:
--------------------------------------------------------------------------------
1 | map(fn ($default, $key) => array_merge(
11 | $defaults,
12 | $queryParams,
13 | $linkParams,
14 | )[$key])->toArray();
15 |
16 | return $this->route($name, $outputParameters, $absolute);
17 | });
18 |
19 | Response::macro('jsonApi', function ($value) {
20 | $response = Response::json($value);
21 | $response->headers->set('Content-Type', 'application/vnd.api+json');
22 |
23 | return $response;
24 | });
25 |
--------------------------------------------------------------------------------
/tests/Unit/TalkRevisionTest.php:
--------------------------------------------------------------------------------
1 | create([
18 | 'description' => '',
19 | 'organizer_notes' => '',
20 | ]);
21 |
22 | $this->assertEquals('(empty)', $revision->getDescription());
23 | $this->assertEquals('(empty)', $revision->getHtmledOrganizerNotes());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/Http/Controllers/DashboardController.php:
--------------------------------------------------------------------------------
1 | user()->load([
12 | 'favoritedConferences' => fn ($query) => $query->future(),
13 | 'submissions' => function ($query) {
14 | $query->whereNotRejected()->whereFuture();
15 | },
16 | 'submissions.conference',
17 | 'submissions.acceptance',
18 | ]);
19 |
20 | return view('dashboard', [
21 | 'conferences' => auth()->user()->favoritedConferences,
22 | 'submissions' => auth()->user()->submissions,
23 | ]);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_failed_jobs_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
12 | $table->text('connection', 65535);
13 | $table->text('queue', 65535);
14 | $table->text('payload');
15 | $table->text('exception');
16 | $table->timestamp('failed_at')->default(DB::raw('CURRENT_TIMESTAMP'));
17 | });
18 | }
19 |
20 | public function down(): void
21 | {
22 | Schema::drop('failed_jobs');
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/resources/views/components/button/base.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'href',
3 | 'icon',
4 | 'size' => 'sm',
5 | ])
6 |
7 | @php
8 | $element = isset($href) ? 'a' : 'button';
9 | @endphp
10 |
11 | <{{ $element }}
12 | @isset($href) href="{{ $href }}" @endisset
13 | {{ $attributes->class([
14 | "py-2 rounded inline-flex items-center justify-center space-x-2",
15 | 'px-2' => $size === 'sm' && $slot->isEmpty(),
16 | 'px-4' => $size === 'sm' && $slot->isNotEmpty(),
17 | 'font-semibold px-8 text-lg' => $size === 'md',
18 | ]) }}
19 | >
20 | @isset($icon)
21 | @svg($icon, 'w-3 h-3 fill-current inline')
22 | @endisset
23 | @if ($slot->isNotEmpty())
24 | {{ $slot }}
25 | @endif
26 | {{ $element }}>
27 |
--------------------------------------------------------------------------------
/tests/Unit/ContactRequestTest.php:
--------------------------------------------------------------------------------
1 | render();
21 |
22 | $this->assertStringContainsString('vader@empire.com', $message);
23 | $this->assertStringContainsString('Darth Vader', $message);
24 | $this->assertStringContainsString('I am your father', $message);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/ForgotPasswordController.php:
--------------------------------------------------------------------------------
1 | string('id', 100)->primary();
12 | $table->integer('user_id');
13 | $table->integer('client_id');
14 | $table->text('scopes', 65535)->nullable();
15 | $table->boolean('revoked');
16 | $table->dateTime('expires_at')->nullable();
17 | });
18 | }
19 |
20 | public function down(): void
21 | {
22 | Schema::drop('oauth_auth_codes');
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/resources/views/talks/show-public.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 |
6 |
11 | Return to profile for {{ $user->name }}
12 |
13 |
14 | {{ $talk->currentRevision->title }}
15 |
16 |
17 | {{ $talk->currentRevision->length }} minute {{ $talk->currentRevision->level }} {{ $talk->currentRevision->type }}
18 |
19 |
20 | Description/Proposal
21 |
22 | {!! markdown($talk->currentRevision->getDescription()) !!}
23 |
24 |
25 | @endsection
26 |
--------------------------------------------------------------------------------
/database/seeders/SubmissionsSeeder.php:
--------------------------------------------------------------------------------
1 | each(function ($conference) {
15 | $talkRevisions = TalkRevision::inRandomOrder()->limit(mt_rand(1, 5))->get();
16 | $talkRevisions->each(function ($talkRevision) use ($conference) {
17 | Submission::factory()->create([
18 | 'talk_revision_id' => $talkRevision->id,
19 | 'conference_id' => $conference->id,
20 | ]);
21 | });
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/UserBiosController.php:
--------------------------------------------------------------------------------
1 | guard('api')->user()->id) {
18 | App::abort(404);
19 | }
20 |
21 | $return = auth()->guard('api')->user()->bios->map(function ($bio) {
22 | return new Bio($bio);
23 | });
24 |
25 | return response()->jsonApi([
26 | 'data' => $return,
27 | ]);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/ResetPasswordController.php:
--------------------------------------------------------------------------------
1 |
6 | Are you sure?
7 |
8 | Are you sure you want to delete your account?
9 |
10 |
11 |
12 |
16 | Yes
17 |
18 |
23 | No
24 |
25 |
26 |
27 |
28 |
29 | @endsection
30 |
--------------------------------------------------------------------------------
/database/seeders/RejectionSeeder.php:
--------------------------------------------------------------------------------
1 | filter(function ($submission) {
14 | return ! $submission->isAccepted();
15 | })->each(function ($submission) {
16 | if (mt_rand(0, 1)) {
17 | $rejection = Rejection::factory()->create([
18 | 'talk_revision_id' => $submission->talk_revision_id,
19 | 'conference_id' => $submission->conference_id,
20 | ]);
21 | $submission->recordRejection($rejection);
22 | }
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/database/factories/TalkRevisionFactory.php:
--------------------------------------------------------------------------------
1 | 'My Awesome Title',
15 | 'type' => 'lightning',
16 | 'length' => '9',
17 | 'level' => 'beginner',
18 | 'slides' => 'http://speakerdeck.com/mattstauffer/the-best-talk-ever',
19 | 'description' => 'The best talk ever!',
20 | 'organizer_notes' => 'No really.',
21 | 'talk_id' => Talk::factory(),
22 | 'created_at' => Carbon::now()->subMinutes(1),
23 | ];
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_acceptances_table.php:
--------------------------------------------------------------------------------
1 | char('id', 36)->primary();
12 | $table->string('talk_revision_id', 36);
13 | $table->string('conference_id', 36)->index('acceptances_conference_id_foreign');
14 | $table->timestamps();
15 | $table->unique(['talk_revision_id', 'conference_id'], 'acceptances_talk_revision_conference_unique');
16 | });
17 | }
18 |
19 | public function down(): void
20 | {
21 | Schema::drop('acceptances');
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/tests/Unit/Notifications/ConferenceImporterErrorTest.php:
--------------------------------------------------------------------------------
1 | toSlack(new TightenSlack);
18 |
19 | tap(collect($notification->attachments)->first(), function ($attachment) {
20 | $this->assertNotNull($attachment);
21 | $this->assertStringContainsString('Test exception', $attachment->content);
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 |
3 | Options -MultiViews -Indexes
4 |
5 |
6 | RewriteEngine On
7 |
8 | # Handle Authorization Header
9 | RewriteCond %{HTTP:Authorization} .
10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
11 |
12 | # Handle X-XSRF-Token Header
13 | RewriteCond %{HTTP:x-xsrf-token} .
14 | RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}]
15 |
16 | # Redirect Trailing Slashes If Not A Folder...
17 | RewriteCond %{REQUEST_FILENAME} !-d
18 | RewriteCond %{REQUEST_URI} (.+)/$
19 | RewriteRule ^ %1 [L,R=301]
20 |
21 | # Send Requests To Front Controller...
22 | RewriteCond %{REQUEST_FILENAME} !-d
23 | RewriteCond %{REQUEST_FILENAME} !-f
24 | RewriteRule ^ index.php [L]
25 |
26 |
--------------------------------------------------------------------------------
/tests/Api/MeApiTest.php:
--------------------------------------------------------------------------------
1 | create());
16 |
17 | $response = $this->call('GET', 'api/me');
18 | $data = json_decode($response->getContent());
19 |
20 | $this->assertEquals(200, $response->getStatusCode());
21 | $this->assertIsObject($data->data);
22 | }
23 |
24 | #[Test]
25 | public function only_authenticated_users_can_fetch_user_data(): void
26 | {
27 | $response = $this->getJson('api/me');
28 |
29 | $response->assertUnauthorized();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/Mail/ContactRequest.php:
--------------------------------------------------------------------------------
1 | email = $email;
23 | $this->name = $name;
24 | $this->userMessage = $userMessage;
25 | }
26 |
27 | /**
28 | * Build the message.
29 | */
30 | public function build(): static
31 | {
32 | return $this->subject('Contact from your Symposium public profile page')
33 | ->view('emails.public-profile-contact');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/database/migrations/2019_10_25_152352_add_conference_location.php:
--------------------------------------------------------------------------------
1 | string('location')->nullable();
13 | $table->double('latitude')->nullable();
14 | $table->double('longitude')->nullable();
15 | });
16 | }
17 |
18 | public function down(): void
19 | {
20 | Schema::table('conferences', function (Blueprint $table) {
21 | $table->dropColumn('location');
22 | $table->dropColumn('latitude');
23 | $table->dropColumn('longitude');
24 | });
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/tests/Unit/Notifications/ConferenceImporterInactiveTest.php:
--------------------------------------------------------------------------------
1 | '2024-05-04 11:11:11']);
16 |
17 | $notification = (new ConferenceImporterInactive)
18 | ->toSlack(new TightenSlack);
19 |
20 | tap(collect($notification->attachments)->first(), function ($attachment) {
21 | $this->assertNotNull($attachment);
22 | $this->assertStringContainsString('2024-05-04 11:11:11', $attachment->content);
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/resources/svg/dots.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
--------------------------------------------------------------------------------
/tests/Unit/Notifications/CFPsAreOpenTest.php:
--------------------------------------------------------------------------------
1 | create(['title' => 'JediCon']);
20 | $user = User::factory()->create();
21 |
22 | $notification = (new CFPsAreOpen([$conference]))
23 | ->toMail($user);
24 |
25 | $this->assertEquals('New Open CFPs', $notification->subject);
26 | $this->assertStringContainsString('JediCon', $notification->render());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/resources/views/conferences/issues/create.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 |
6 |
7 |
15 |
16 |
21 |
22 |
23 |
24 |
29 | Report Issue
30 |
31 |
32 |
33 | @endsection
34 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_favorites_table.php:
--------------------------------------------------------------------------------
1 | foreign('conference_id')->references('id')->on('conferences')->onUpdate('RESTRICT')->onDelete('CASCADE');
12 | $table->foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('CASCADE');
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('favorites', function (Blueprint $table) {
19 | $table->dropForeign('favorites_conference_id_foreign');
20 | $table->dropForeign('favorites_user_id_foreign');
21 | });
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/app/Http/Requests/SaveTalkRequest.php:
--------------------------------------------------------------------------------
1 | 'required',
18 | 'type' => 'required',
19 | 'level' => 'required',
20 | 'length' => 'required|integer|min:0',
21 | 'slides' => 'nullable|url',
22 | 'organizer_notes' => 'required',
23 | 'description' => 'required',
24 | 'public' => 'required',
25 | ];
26 | }
27 |
28 | public function messages(): array
29 | {
30 | return [
31 | 'slides.url' => 'Slides URL must contain a valid URL',
32 | ];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_oauth_access_tokens_table.php:
--------------------------------------------------------------------------------
1 | string('id', 100)->primary();
12 | $table->integer('user_id')->nullable()->index();
13 | $table->integer('client_id');
14 | $table->string('name')->nullable();
15 | $table->text('scopes', 65535)->nullable();
16 | $table->boolean('revoked');
17 | $table->timestamps();
18 | $table->dateTime('expires_at')->nullable();
19 | });
20 | }
21 |
22 | public function down(): void
23 | {
24 | Schema::drop('oauth_access_tokens');
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_oauth_clients_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
12 | $table->integer('user_id')->nullable()->index();
13 | $table->string('name');
14 | $table->string('secret', 100);
15 | $table->text('redirect', 65535);
16 | $table->boolean('personal_access_client');
17 | $table->boolean('password_client');
18 | $table->boolean('revoked');
19 | $table->timestamps();
20 | });
21 | }
22 |
23 | public function down(): void
24 | {
25 | Schema::drop('oauth_clients');
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/app/Providers/EventServiceProvider.php:
--------------------------------------------------------------------------------
1 | >
14 | */
15 | protected $listen = [];
16 |
17 | protected $subscribe = [
18 | SlackSubscriber::class,
19 | ];
20 |
21 | /**
22 | * Register any events for your application.
23 | */
24 | public function boot(): void
25 | {
26 | //
27 | }
28 |
29 | /**
30 | * Determine if events and listeners should be automatically discovered.
31 | */
32 | public function shouldDiscoverEvents(): bool
33 | {
34 | return false;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_submissions_table.php:
--------------------------------------------------------------------------------
1 | char('id', 36)->primary();
12 | $table->string('talk_revision_id', 36);
13 | $table->string('conference_id', 36)->index('submissions_conference_id_foreign');
14 | $table->timestamps();
15 | $table->string('acceptance_id', 36)->nullable()->index('submissions_acceptance_id_foreign');
16 | $table->unique(['talk_revision_id', 'conference_id'], 'submissions_talk_revision_conference_unique');
17 | });
18 | }
19 |
20 | public function down(): void
21 | {
22 | Schema::drop('submissions');
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_acceptances_table.php:
--------------------------------------------------------------------------------
1 | foreign('conference_id')->references('id')->on('conferences')->onUpdate('RESTRICT')->onDelete('CASCADE');
12 | $table->foreign('talk_revision_id')->references('id')->on('talk_revisions')->onUpdate('RESTRICT')->onDelete('CASCADE');
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('acceptances', function (Blueprint $table) {
19 | $table->dropForeign('acceptances_conference_id_foreign');
20 | $table->dropForeign('acceptances_talk_revision_id_foreign');
21 | });
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/routes/api.php:
--------------------------------------------------------------------------------
1 | group(function () {
12 | Route::get('me', [MeController::class, 'index']);
13 | Route::get('bios/{bioId}', [BiosController::class, 'show']);
14 | Route::get('user/{userId}/bios', [UserBiosController::class, 'index']);
15 | Route::get('talks/{talkId}', [TalksController::class, 'show']);
16 | Route::get('user/{userId}/talks', [UserTalksController::class, 'index']);
17 | Route::get('conferences/{id}', [ConferencesController::class, 'show']);
18 | Route::get('conferences', [ConferencesController::class, 'index']);
19 | });
20 |
--------------------------------------------------------------------------------
/tests/Unit/Notifications/NewConferenceTest.php:
--------------------------------------------------------------------------------
1 | create(['title' => 'JediCon']);
20 |
21 | $notification = (new NewConference($conference))
22 | ->toSlack(new TightenSlack);
23 |
24 | tap(collect($notification->attachments)->first(), function ($attachment) {
25 | $this->assertNotNull($attachment);
26 | $this->assertStringContainsString('JediCon', $attachment->content);
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/Console/Commands/VerifyConferenceImporterHeartbeat.php:
--------------------------------------------------------------------------------
1 | importerAppearsInactive()) {
19 | (new TightenSlack)->notify(new ConferenceImporterInactive);
20 | }
21 |
22 | return Command::SUCCESS;
23 | }
24 |
25 | private function importerAppearsInactive()
26 | {
27 | return Carbon::parse(cache('conference_importer_last_ran_at'))
28 | ->isBefore(now()->subHours(24));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/resources/svg/icon_find.svg:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/resources/views/components/input/textarea.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'name',
3 | 'label',
4 | 'help',
5 | 'value' => null,
6 | 'cols' => 50,
7 | 'rows' => 10,
8 | 'hideLabel' => false,
9 | ])
10 |
11 | only(['class']) }}>
12 |
18 |
19 |
29 |
30 | @isset($help)
31 | {{ $help }}
32 | @endisset
33 |
34 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_dismissed_conferences_table.php:
--------------------------------------------------------------------------------
1 | foreign('conference_id')->references('id')->on('conferences')->onUpdate('RESTRICT')->onDelete('CASCADE');
12 | $table->foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('CASCADE');
13 | });
14 | }
15 |
16 | public function down(): void
17 | {
18 | Schema::table('dismissed_conferences', function (Blueprint $table) {
19 | $table->dropForeign('dismissed_conferences_conference_id_foreign');
20 | $table->dropForeign('dismissed_conferences_user_id_foreign');
21 | });
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/app/Http/Requests/Auth/LoginFormRequest.php:
--------------------------------------------------------------------------------
1 | 'required|string',
26 | 'password' => 'required|string',
27 | ];
28 | }
29 |
30 | public function messages(): array
31 | {
32 | return [
33 | 'email.required' => 'The email field is required',
34 | 'password.required' => 'The password field is required',
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/Notifications/ConferenceImporterInactive.php:
--------------------------------------------------------------------------------
1 | attachment(function ($attachment) {
23 | $attachment
24 | ->title('Conference importer may be inactive')
25 | ->content(
26 | 'The last successful run was at '.cache('conference_importer_last_ran_at')
27 | )
28 | ->timestamp(Carbon::now());
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/Handlers/Events/SlackSubscriber.php:
--------------------------------------------------------------------------------
1 | slack = $slack;
16 | }
17 |
18 | public function subscribe($events)
19 | {
20 | $events->listen('new-signup', [$this, 'onNewSignup']); // @codeCoverageIgnore
21 | $events->listen('new-conference', [$this, 'onNewConference']);
22 | }
23 |
24 | /**
25 | * @codeCoverageIgnore
26 | */
27 | public function onNewSignup($user, $request)
28 | {
29 | $this->slack->notify(new NewUser($user, $request->getClientIp()));
30 | }
31 |
32 | public function onNewConference($conference)
33 | {
34 | $this->slack->notify(new NewConference($conference));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/database/seeders/ConferencesSeeder.php:
--------------------------------------------------------------------------------
1 | create([
30 | 'title' => $name,
31 | 'is_featured' => rand(0, 1),
32 | 'is_approved' => true,
33 | ]);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/resources/js/components/MenuToggle.vue:
--------------------------------------------------------------------------------
1 |
33 |
--------------------------------------------------------------------------------
/resources/views/components/input/radios.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'name',
3 | 'label',
4 | 'help',
5 | 'options' => [],
6 | 'value' => null,
7 | ])
8 |
9 | only(['class']) }}>
10 |
16 |
17 | @isset($help)
18 | {{ $help }}
19 | @endisset
20 |
21 | @foreach ($options as $label => $option)
22 |
32 | @endforeach
33 |
34 |
--------------------------------------------------------------------------------
/resources/views/components/listing.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 | @isset($header)
11 | {{ $header }}
12 | @endisset
13 |
14 |
15 | {{ $actions }}
16 |
17 |
18 | @isset($body)
19 |
20 | {{ $body }}
21 |
22 | @endisset
23 |
24 | @isset($footer)
25 |
26 | {{ $footer }}
27 |
28 | @endisset
29 |
30 |
--------------------------------------------------------------------------------
/database/migrations/2022_08_23_145646_create_conference_issues_table.php:
--------------------------------------------------------------------------------
1 | id();
14 | $table->foreignIdFor(Conference::class)->constrained();
15 | $table->unsignedInteger('user_id')->constrained();
16 | $table->string('reason');
17 | $table->text('note');
18 | $table->timestamp('closed_at')->nullable();
19 | $table->timestamps();
20 |
21 | $table->foreign('user_id')->references('id')->on('users');
22 | });
23 | }
24 |
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('conference_issues');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/database/seeders/DatabaseSeeder.php:
--------------------------------------------------------------------------------
1 | environment('testing')) {
19 | DB::statement('SET FOREIGN_KEY_CHECKS = 0');
20 | }
21 |
22 | $this->call([
23 | UsersSeeder::class,
24 | TalksSeeder::class,
25 | BiosSeeder::class,
26 | ConferencesSeeder::class,
27 | SubmissionsSeeder::class,
28 | AcceptanceSeeder::class,
29 | RejectionSeeder::class,
30 | ]);
31 |
32 | if (! app()->environment('testing')) {
33 | DB::statement('SET FOREIGN_KEY_CHECKS = 1');
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/google-guide.md:
--------------------------------------------------------------------------------
1 | ## Google API Key Guide
2 |
3 | ### Create a Key
4 |
5 | 1. Create an API Key from the [Google Places API Documentation](https://developers.google.com/places/web-service/get-api-key) by clicking on the "GET A KEY" button.
6 |
7 | 
8 |
9 | 1. Once you have a key, save it to your .env file using the environment key `GOOGLE_MAPS_API_KEY`.
10 | 1. Next, click on the `API Console` link just below the API Key. This will take you to your API Console where you can enable/disable APIs and manage credentials.
11 |
12 | > It is highly recommended to restrict your API Key, especially in production.
13 |
14 | ### Enable Javascript API
15 |
16 | 1. Click on Library
17 | 1. Click on the Google Maps Javascript API
18 | 1. Click on Enable
19 |
20 | 
21 |
22 | You're now ready to start using the API Key in your application!
23 |
--------------------------------------------------------------------------------
/database/migrations/2020_10_30_131213_rename_featured_columns_to_is_featured.php:
--------------------------------------------------------------------------------
1 | renameColumn('featured', 'is_featured');
13 | });
14 |
15 | Schema::table('conferences', function (Blueprint $table) {
16 | $table->renameColumn('featured', 'is_featured');
17 | });
18 | }
19 |
20 | public function down(): void
21 | {
22 | Schema::table('users', function (Blueprint $table) {
23 | $table->renameColumn('is_featured', 'featured');
24 | });
25 |
26 | Schema::table('conferences', function (Blueprint $table) {
27 | $table->renameColumn('is_featured', 'featured');
28 | });
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/resources/views/components/input/toggle.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'name',
3 | 'label',
4 | 'value' => null,
5 | ])
6 |
7 |
8 |
9 |
10 |
11 | except(['class']) }}
18 | />
19 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/database/migrations/2021_10_28_000000_add_uuid_to_failed_jobs_table.php:
--------------------------------------------------------------------------------
1 | string('uuid')->after('id')->nullable()->unique();
15 | });
16 |
17 | DB::table('failed_jobs')->whereNull('uuid')->cursor()->each(function ($job) {
18 | DB::table('failed_jobs')
19 | ->where('id', $job->id)
20 | ->update(['uuid' => (string) Str::uuid()]);
21 | });
22 | }
23 |
24 | public function down(): void
25 | {
26 | Schema::table('failed_jobs', function (Blueprint $table) {
27 | $table->dropColumn('uuid');
28 | });
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | withoutVite();
22 |
23 | NotificationFake::macro('assertSentToTightenSlack', function ($notification) {
24 | $this->assertSentTo(new TightenSlack, $notification);
25 | });
26 |
27 | NotificationFake::macro('assertNotSentToTightenSlack', function ($notification) {
28 | $this->assertNotSentTo(new TightenSlack, $notification);
29 | });
30 |
31 | Notification::fake();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/Notifications/NewConference.php:
--------------------------------------------------------------------------------
1 | conference = $conference;
17 | }
18 |
19 | public function via($notifiable): array
20 | {
21 | return ['slack'];
22 | }
23 |
24 | public function toSlack($notifiable)
25 | {
26 | return (new SlackMessage)
27 | ->attachment(function (SlackAttachment $attachment) {
28 | $attachment
29 | ->title('New conference created')
30 | ->content("{$this->conference->title}\nAPPROVE HERE: {$this->conference->link}")
31 | ->timestamp(Carbon::now());
32 | });
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/database/seeders/BiosSeeder.php:
--------------------------------------------------------------------------------
1 | bios()->create(['nickname' => 'Short Bio', 'body' => 'I am short.']);
18 | $longBio = $author->bios()->create(['nickname' => 'Long Bio', 'body' => 'I am short and I love being short and this is very long.']);
19 |
20 | $author->bios()->saveMany([$shortBio, $longBio]);
21 |
22 | // Add a talk for user 2 for testing purposes
23 | $author = User::find(2);
24 |
25 | $trueBio = $author->bios()->create(['nickname' => 'True Bio', 'body' => 'I am a person.']);
26 | $falseBio = $author->bios()->create(['nickname' => 'False Bio', 'body' => 'I am an elephant.']);
27 |
28 | $author->bios()->saveMany([$trueBio, $falseBio]);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/Notifications/ConferenceImporterError.php:
--------------------------------------------------------------------------------
1 | message = $exception->getMessage();
20 | }
21 |
22 | public function via($notifiable): array
23 | {
24 | return ['slack'];
25 | }
26 |
27 | public function toSlack($notifiable)
28 | {
29 | return (new SlackMessage)
30 | ->attachment(function ($attachment) {
31 | $attachment
32 | ->title('Conference importer encountered an error')
33 | ->content("Message: {$this->message}")
34 | ->timestamp(Carbon::now());
35 | });
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/ApiResources/Me.php:
--------------------------------------------------------------------------------
1 | user = $user;
15 | }
16 |
17 | public function getId()
18 | {
19 | return $this->user->id;
20 | }
21 |
22 | public function getType()
23 | {
24 | return 'users';
25 | }
26 |
27 | public function attributes()
28 | {
29 | return [
30 | 'email' => $this->user->email,
31 | 'name' => $this->user->name,
32 | 'created_at' => (string) $this->user->created_at,
33 | 'updated_at' => (string) $this->user->updated_at,
34 | ];
35 | }
36 |
37 | public function toArray()
38 | {
39 | return [
40 | 'id' => $this->getId(),
41 | 'type' => $this->getType(),
42 | 'attributes' => $this->attributes(),
43 | ];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_talk_revisions_table.php:
--------------------------------------------------------------------------------
1 | string('id', 36)->unique('talk_version_revisions_id_unique');
12 | $table->string('title');
13 | $table->string('type', 50);
14 | $table->integer('length');
15 | $table->enum('level', ['beginner', 'intermediate', 'advanced']);
16 | $table->text('description', 65535);
17 | $table->string('slides')->nullable();
18 | $table->text('organizer_notes', 65535);
19 | $table->timestamps();
20 | $table->string('talk_id', 36)->default('')->index('talk_revisions_talk_id_foreign');
21 | });
22 | }
23 |
24 | public function down(): void
25 | {
26 | Schema::drop('talk_revisions');
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/resources/js/components/UpdateQueryString.vue:
--------------------------------------------------------------------------------
1 |
35 |
--------------------------------------------------------------------------------
/app/Notifications/NewUser.php:
--------------------------------------------------------------------------------
1 | user = $user;
22 | $this->ip = $ip;
23 | }
24 |
25 | public function via($notifiable): array
26 | {
27 | return ['slack'];
28 | }
29 |
30 | public function toSlack($notifiable)
31 | {
32 | return (new SlackMessage)
33 | ->attachment(function (SlackAttachment $attachment) {
34 | $attachment
35 | ->title('New user signup')
36 | ->content("{$this->user->username}\n{$this->user->email}\n{$this->ip}")
37 | ->timestamp(Carbon::now());
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/resources/views/conferences/edit.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Edit Conference'])
2 |
3 | @section('content')
4 |
5 |
6 | @foreach ($errors->all() as $message)
7 | - {{ $message }}
8 | @endforeach
9 |
10 |
11 |
12 |
13 | @include('conferences.form')
14 |
15 | @if (auth()->user()->isAdmin())
16 |
26 | @endif
27 |
28 |
29 |
30 |
35 | Update
36 |
37 |
38 |
39 | @endsection
40 |
--------------------------------------------------------------------------------
/database/factories/ConferenceIssueFactory.php:
--------------------------------------------------------------------------------
1 | User::factory(),
17 | 'conference_id' => Conference::factory(),
18 | 'reason' => Arr::random(ConferenceIssue::REASONS),
19 | 'note' => $this->faker->sentence(),
20 | ];
21 | }
22 |
23 | public function open()
24 | {
25 | return $this->state(function () {
26 | return [
27 | 'closed_at' => null,
28 | ];
29 | });
30 | }
31 |
32 | public function closed()
33 | {
34 | return $this->state(function () {
35 | return [
36 | 'closed_at' => $this->faker->dateTime(),
37 | ];
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/database/migrations/2023_03_31_000348_add_admin_note_column_to_conference_issues_table.php:
--------------------------------------------------------------------------------
1 | text('admin_note')
13 | ->after('note')
14 | ->nullable();
15 | $table->unsignedInteger('closed_by')
16 | ->constrained()
17 | ->after('user_id')
18 | ->nullable();
19 |
20 | $table->foreign('closed_by')->references('id')->on('users');
21 | });
22 | }
23 |
24 | public function down(): void
25 | {
26 | Schema::table('conference_issues', function (Blueprint $table) {
27 | $table->dropColumn('admin_note');
28 | $table->dropForeign('conference_issues_closed_by_foreign');
29 | $table->dropColumn('closed_by');
30 | });
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/app/ApiResources/Bio.php:
--------------------------------------------------------------------------------
1 | bio = $bio;
15 | }
16 |
17 | public function getId()
18 | {
19 | return $this->bio->id;
20 | }
21 |
22 | public function getType()
23 | {
24 | return 'bios';
25 | }
26 |
27 | public function attributes()
28 | {
29 | return [
30 | 'nickname' => $this->bio->nickname,
31 | 'public' => $this->bio->public,
32 | 'body' => $this->bio->body,
33 | 'created_at' => (string) $this->bio->created_at,
34 | 'updated_at' => (string) $this->bio->updated_at,
35 | ];
36 | }
37 |
38 | public function toArray()
39 | {
40 | return [
41 | 'id' => $this->getId(),
42 | 'type' => $this->getType(),
43 | 'attributes' => $this->attributes(),
44 | ];
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/database/migrations/2019_05_09_222406_drop_joindin_add_cap.php:
--------------------------------------------------------------------------------
1 | dropColumn('joindin_id');
17 | });
18 | Schema::table('conferences', function (Blueprint $table) {
19 | $table->string('calling_all_papers_id', 40)->nullable();
20 | });
21 | }
22 |
23 | public function down(): void
24 | {
25 | Schema::table('conferences', function (Blueprint $table) {
26 | $table->dropColumn('calling_all_papers_id');
27 | });
28 | Schema::table('conferences', function (Blueprint $table) {
29 | $table->integer('joindin_id')->nullable();
30 | });
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Eventy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/Filament/Resources/ConferenceResource/Pages/EditConference.php:
--------------------------------------------------------------------------------
1 | record->isRejected()) {
16 | return parent::getHeading();
17 | }
18 |
19 | return parent::getHeading().' (rejected)';
20 | }
21 |
22 | protected function getHeaderActions(): array
23 | {
24 | return [
25 | Action::make('Reject')
26 | ->color('danger')
27 | ->action(fn () => $this->record->reject())
28 | ->visible(fn () => ! $this->record->isRejected()),
29 | Action::make('Restore')
30 | ->action(fn () => $this->record->restore())
31 | ->visible(fn () => $this->record->isRejected()),
32 | ];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/Notifications/ConferenceIssueReported.php:
--------------------------------------------------------------------------------
1 | issue = $issue;
21 | }
22 |
23 | public function via($notifiable): array
24 | {
25 | return ['slack'];
26 | }
27 |
28 | public function toSlack($notifiable)
29 | {
30 | return (new SlackMessage)
31 | ->attachment(function ($attachment) {
32 | $attachment
33 | ->title("Issue reported: {$this->issue->conference->title}")
34 | ->content("View issue: {$this->issue->link}")
35 | ->timestamp(Carbon::now());
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142915_add_foreign_keys_to_submissions_table.php:
--------------------------------------------------------------------------------
1 | foreign('acceptance_id')->references('id')->on('acceptances')->onUpdate('RESTRICT')->onDelete('RESTRICT');
12 | $table->foreign('conference_id')->references('id')->on('conferences')->onUpdate('RESTRICT')->onDelete('CASCADE');
13 | $table->foreign('talk_revision_id')->references('id')->on('talk_revisions')->onUpdate('RESTRICT')->onDelete('CASCADE');
14 | });
15 | }
16 |
17 | public function down(): void
18 | {
19 | Schema::table('submissions', function (Blueprint $table) {
20 | $table->dropForeign('submissions_acceptance_id_foreign');
21 | $table->dropForeign('submissions_conference_id_foreign');
22 | $table->dropForeign('submissions_talk_revision_id_foreign');
23 | });
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Api/UserTalksController.php:
--------------------------------------------------------------------------------
1 | guard('api')->user()->id) {
18 | App::abort(404);
19 | }
20 |
21 | $talks = auth()->guard('api')
22 | ->user()
23 | ->talks()
24 | ->withCurrentRevision()
25 | ->when((bool) request()->query('include-archived'), function ($query) {
26 | $query->withoutGlobalScope('active');
27 | })
28 | ->get()
29 | ->sortByTitle()
30 | ->map(function ($talk) {
31 | return new Talk($talk);
32 | })->values();
33 |
34 | return response()->jsonApi([
35 | 'data' => $talks,
36 | ]);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/resources/views/components/input/text.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'name',
3 | 'label' => '',
4 | 'help',
5 | 'value' => null,
6 | 'type' => 'text',
7 | 'inline' => false,
8 | 'hideLabel' => false,
9 | 'roundedClass' => 'rounded',
10 | ])
11 |
12 | only(['class']) }}>
13 |
19 |
20 | @php
21 | $valueName = str($name)->replace('[', '.')->replace(']', '');
22 | @endphp
23 |
24 | except('class') }}
29 | class="
30 | bg-white border-form-200 form-input placeholder-form-400 {{ $roundedClass }}
31 | @unless ($inline) w-full @endunless
32 | @unless ($hideLabel) mt-1 @endunless
33 | "
34 | >
35 |
36 | @isset($help)
37 | {{ $help }}
38 | @endisset
39 |
40 |
--------------------------------------------------------------------------------
/app/Http/Requests/Auth/RegisterFormRequest.php:
--------------------------------------------------------------------------------
1 | 'required|max:255',
29 | 'email' => 'required|email|max:255|unique:users|emailblacklist',
30 | 'password' => 'required|min:6',
31 | ];
32 | }
33 |
34 | public function messages(): array
35 | {
36 | return [
37 | 'name.required' => 'The name field is required',
38 | 'email.required' => 'The email field is required',
39 | 'password.required' => 'The password field is required',
40 | ];
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/Transformers/TalkForConferenceTransformer.php:
--------------------------------------------------------------------------------
1 | currentRevision;
13 | $currentRevision->setRelation('talk', $talk);
14 |
15 | $submission = $talk->getMySubmissionForConference($conference);
16 | $acceptance = $submission ? $submission->acceptance : null;
17 | $rejection = $submission ? $submission->rejection : null;
18 |
19 | return [
20 | 'id' => $talk->id,
21 | 'title' => $currentRevision->title,
22 | 'url' => $currentRevision->getUrl(),
23 | 'submitted' => (bool) $submission,
24 | 'submissionId' => $submission ? $submission->id : null,
25 | 'accepted' => (bool) $acceptance,
26 | 'acceptanceId' => $acceptance ? $acceptance->id : null,
27 | 'rejected' => (bool) $rejection,
28 | 'rejectionId' => $rejection ? $rejection->id : null,
29 | ];
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/resources/views/bios/show.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app')
2 |
3 | @section('content')
4 |
5 |
6 |
7 |
15 |
16 |
17 |
18 | {!! str_replace("\n", "
", $bio->body) !!}
19 |
20 |
21 |
22 |
Created
23 |
{{ $bio->created_at->toFormattedDateString() }}
24 |
25 |
26 |
Updated
27 |
{{ $bio->updated_at->toFormattedDateString() }}
28 |
29 |
30 |
31 |
32 | @endsection
33 |
--------------------------------------------------------------------------------
/tests/Unit/Notifications/ConferenceIssueReportedTest.php:
--------------------------------------------------------------------------------
1 | for(Conference::factory()->create(['title' => 'JediCon']))
22 | ->create();
23 |
24 | $notification = (new ConferenceIssueReported($issue))
25 | ->toSlack(new TightenSlack);
26 |
27 | tap(collect($notification->attachments)->first(), function ($attachment) use ($issue) {
28 | $this->assertNotNull($attachment);
29 | $this->assertStringContainsString('JediCon', $attachment->title);
30 | $this->assertStringContainsString("admin/issues/{$issue->id}", $attachment->content);
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Feature/VerifyConferenceImporterHeartbeatTest.php:
--------------------------------------------------------------------------------
1 | now()->subHours(25)->toDateTimeString()]);
17 |
18 | $this->artisan('verify-conference-importer-heartbeat');
19 |
20 | Notification::assertSentToTightenSlack(ConferenceImporterInactive::class);
21 | }
22 |
23 | #[Test]
24 | public function slack_is_not_notified_when_the_importer_has_run_within_24_hours(): void
25 | {
26 | Notification::fake();
27 | cache(['conference_importer_last_ran_at' => now()->subHours(23)->toDateTimeString()]);
28 |
29 | $this->artisan('verify-conference-importer-heartbeat');
30 |
31 | Notification::assertNotSentToTightenSlack(ConferenceImporterInactive::class);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | APP_ENV=local
2 | APP_DEBUG=true
3 | APP_KEY=SomeRandomString
4 | APP_URL=http://symposium.test/
5 | APP_NAME=Symposium
6 |
7 | APP_LOCALE=en
8 | APP_FALLBACK_LOCALE=en
9 | APP_FAKER_LOCALE=en_US
10 | APP_MAINTENANCE_DRIVER=file
11 | APP_MAINTENANCE_STORE=database
12 | PHP_CLI_SERVER_WORKERS=4
13 |
14 | BCRYPT_ROUNDS=12
15 |
16 | DB_CONNECTION=mysql
17 | DB_HOST=localhost
18 | DB_DATABASE=symposium
19 | DB_USERNAME=root
20 | DB_PASSWORD=
21 |
22 | CACHE_STORE=file
23 | SESSION_DRIVER=file
24 | SCOUT_DRIVER=database
25 | QUEUE_CONNECTION=redis
26 |
27 | REDIS_CLIENT=predis
28 | REDIS_CLUSTER=predis
29 | REDIS_PREFIX="symposium_"
30 |
31 | FILESYSTEM_DISK=local
32 |
33 | MAIL_HOST=
34 | MAIL_USERNAME=
35 | MAIL_PASSWORD=
36 | ADMIN_EMAIL=email
37 |
38 | SLACK_ENDPOINT=
39 |
40 | CAPTCHA_PUBLIC=
41 | CAPTCHA_PRIVATE=
42 |
43 | FLARE_KEY=
44 |
45 | VITE_DISABLE_LOCATION_LOOKUP=false
46 | GOOGLE_MAPS_API_KEY=
47 | GOOGLE_MAPS_API_FRONTEND_KEY=
48 |
49 | ALGOLIA_APP_ID=
50 | ALGOLIA_SECRET=
51 |
52 | GITHUB_CLIENT_ID=
53 | GITHUB_CLIENT_SECRET=
54 | GITHUB_REDIRECT_URL="${APP_URL}login/github/callback"
55 |
56 | LOG_STACK="daily"
57 |
58 | SESSION_ENCRYPT=false
59 | SESSION_PATH=/
60 | SESSION_DOMAIN=null
61 |
--------------------------------------------------------------------------------
/database/migrations/2021_10_13_142431_create_rejections_table.php:
--------------------------------------------------------------------------------
1 | char('id', 36)->primary();
13 | $table->string('talk_revision_id', 36);
14 | $table->string('conference_id', 36)->index('rejections_conference_id_foreign');
15 | $table->timestamps();
16 | $table->unique(['talk_revision_id', 'conference_id'], 'rejections_talk_revision_conference_unique');
17 | });
18 |
19 | Schema::table('rejections', function (Blueprint $table) {
20 | $table->foreign('conference_id')->references('id')->on('conferences')->onUpdate('RESTRICT')->onDelete('CASCADE');
21 | $table->foreign('talk_revision_id')->references('id')->on('talk_revisions')->onUpdate('RESTRICT')->onDelete('CASCADE');
22 | });
23 | }
24 |
25 | public function down(): void
26 | {
27 | Schema::dropIfExists('rejections');
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/resources/views/auth/passwords/reset.blade.php:
--------------------------------------------------------------------------------
1 | @extends('app', ['title' => 'Reset Password'])
2 |
3 | @section('content')
4 |
5 | @include('partials.authentication-errors')
6 |
7 |
46 |
47 | @endsection
48 |
--------------------------------------------------------------------------------
/app/Console/Commands/SendNotificationForOpenCFPs.php:
--------------------------------------------------------------------------------
1 | conferencesToShare()->get();
29 |
30 | if ($conferences->isEmpty()) {
31 | return;
32 | }
33 |
34 | $this->conferencesToShare()->update(['is_shared' => true]);
35 |
36 | Notification::send(User::wantsNotifications()->get(), new CFPsAreOpen($conferences));
37 | }
38 |
39 | protected function conferencesToShare()
40 | {
41 | return Conference::approved()->notShared()->whereCfpIsOpen();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/database/migrations/2019_04_19_142914_create_conferences_table.php:
--------------------------------------------------------------------------------
1 | string('id', 36)->unique();
12 | $table->string('title');
13 | $table->text('description', 65535);
14 | $table->string('url');
15 | $table->integer('author_id')->unsigned()->index('conferences_author_id_foreign');
16 | $table->dateTime('starts_at')->nullable();
17 | $table->dateTime('ends_at')->nullable();
18 | $table->dateTime('cfp_starts_at')->nullable();
19 | $table->dateTime('cfp_ends_at')->nullable();
20 | $table->integer('joindin_id')->nullable();
21 | $table->timestamps();
22 | $table->string('cfp_url')->nullable();
23 | $table->boolean('is_approved')->default(0);
24 | $table->boolean('is_shared')->default(0);
25 | });
26 | }
27 |
28 | public function down(): void
29 | {
30 | Schema::drop('conferences');
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/resources/svg/icon_versioncontrol.svg:
--------------------------------------------------------------------------------
1 |
2 |
17 |
--------------------------------------------------------------------------------
/app/Notifications/CFPsAreOpen.php:
--------------------------------------------------------------------------------
1 | conferences = $conferences;
23 | }
24 |
25 | /**
26 | * Get the notification's delivery channels.
27 | *
28 | * @param mixed $notifiable
29 | */
30 | public function via($notifiable): array
31 | {
32 | return ['mail'];
33 | }
34 |
35 | /**
36 | * Get the mail representation of the notification.
37 | *
38 | * @param mixed $notifiable
39 | */
40 | public function toMail($notifiable): MailMessage
41 | {
42 | return (new MailMessage)
43 | ->subject('New Open CFPs')
44 | ->markdown('emails.open-cfps', [
45 | 'conferences' => $this->conferences,
46 | ]);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/config/services.php:
--------------------------------------------------------------------------------
1 | [
6 | 'domain' => env('MAILGUN_DOMAIN'),
7 | 'secret' => env('MAILGUN_SECRET'),
8 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
9 | 'scheme' => 'https',
10 | ],
11 |
12 | 'sparkpost' => [
13 | 'secret' => env('SPARKPOST_SECRET'),
14 | ],
15 |
16 | 'stripe' => [
17 | 'model' => App\Models\User::class,
18 | 'key' => env('STRIPE_KEY'),
19 | 'secret' => env('STRIPE_SECRET'),
20 | 'webhook' => [
21 | 'secret' => env('STRIPE_WEBHOOK_SECRET'),
22 | 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300),
23 | ],
24 | ],
25 |
26 | 'google' => [
27 | 'maps' => [
28 | 'key' => env('GOOGLE_MAPS_API_KEY'),
29 | 'frontend_key' => env('GOOGLE_MAPS_API_FRONTEND_KEY'),
30 | ],
31 | 'captcha' => [
32 | 'public' => env('CAPTCHA_PUBLIC'),
33 | 'private' => env('CAPTCHA_PRIVATE'),
34 | ],
35 | ],
36 |
37 | 'github' => [
38 | 'client_id' => env('GITHUB_CLIENT_ID'),
39 | 'client_secret' => env('GITHUB_CLIENT_SECRET'),
40 | 'redirect' => env('GITHUB_REDIRECT_URL'),
41 | ],
42 |
43 | ];
44 |
--------------------------------------------------------------------------------
/tests/Feature/HomeTest.php:
--------------------------------------------------------------------------------
1 | featured()->create(['name' => 'Luke Skywalker']);
19 | User::factory()->notFeatured()->create(['name' => 'Han Solo']);
20 |
21 | $response = $this->get(route('home'));
22 |
23 | $response->assertSuccessful();
24 | $response->assertSee('Luke Skywalker');
25 | $response->assertDontSee('Han Solo');
26 | }
27 |
28 | #[Test]
29 | public function including_featured_conferences()
30 | {
31 | Conference::factory()->featured()->create(['title' => 'Awesome Conference']);
32 | Conference::factory()->notFeatured()->create(['title' => 'Boring Conference']);
33 |
34 | $response = $this->get(route('home'));
35 |
36 | $response->assertSuccessful();
37 | $response->assertSee('Awesome Conference');
38 | $response->assertDontSee('Boring Conference');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/config/database.php:
--------------------------------------------------------------------------------
1 | [
6 | 'testing' => [
7 | 'driver' => 'sqlite',
8 | 'database' => ':memory:',
9 | 'prefix' => '',
10 | ],
11 |
12 | 'mysql' => [
13 | 'driver' => 'mysql',
14 | 'url' => env('DB_URL'),
15 | 'host' => env('DB_HOST', '127.0.0.1'),
16 | 'port' => env('DB_PORT', '3306'),
17 | 'database' => env('DB_DATABASE', 'forge'),
18 | 'username' => env('DB_USERNAME', 'forge'),
19 | 'password' => env('DB_PASSWORD', ''),
20 | 'unix_socket' => env('DB_SOCKET', ''),
21 | 'charset' => 'utf8mb4',
22 | 'collation' => 'utf8mb4_unicode_ci',
23 | 'prefix' => '',
24 | 'prefix_indexes' => true,
25 | 'strict' => false,
26 | 'engine' => null,
27 | 'options' => extension_loaded('pdo_mysql') ? array_filter([
28 | PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
29 | ]) : [],
30 | ],
31 | ],
32 |
33 | 'migrations' => [
34 | 'table' => 'migrations',
35 | 'update_date_on_publish' => false, // disable to preserve original behavior for existing applications
36 | ],
37 |
38 | ];
39 |
--------------------------------------------------------------------------------
/app/Services/Geocoder/Geocoder.php:
--------------------------------------------------------------------------------
1 | isInvalidAddress($address)) {
13 | throw new InvalidAddressGeocodingException;
14 | }
15 |
16 | return $this->requestGeocoding($address);
17 | }
18 |
19 | private function requestGeocoding($address)
20 | {
21 | $response = Http::acceptJson()
22 | ->withHeaders([
23 | 'User-Agent' => 'Symposium CLI',
24 | ])
25 | ->get('https://maps.googleapis.com/maps/api/geocode/json', [
26 | 'address' => $address,
27 | 'key' => config('services.google.maps.key'),
28 | ])
29 | ->json();
30 |
31 | if (! count($response['results'])) {
32 | cache()->set('invalid-address::'.md5($address), true);
33 | throw new InvalidAddressGeocodingException;
34 | }
35 |
36 | return new GeocoderResponse($response);
37 | }
38 |
39 | private function isInvalidAddress($address)
40 | {
41 | return cache('invalid-address::'.md5($address));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/resources/svg/icon_trackconferences.svg:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/app/Filament/Resources/ConferenceIssueResource/Pages/ViewConferenceIssue.php:
--------------------------------------------------------------------------------
1 | record->close(auth()->user(), $data['notes']);
18 |
19 | return $this->redirect($this->getResource()::getUrl('index'));
20 | }
21 |
22 | protected function getHeaderActions(): array
23 | {
24 | return [
25 | Action::make('View conference')
26 | ->color('gray')
27 | ->icon('heroicon-o-arrow-right-circle')
28 | ->url(ConferenceResource::getUrl('edit', [$this->record->conference])),
29 | Action::make('Close issue')
30 | ->icon('heroicon-o-adjustments-vertical')
31 | ->action('close')
32 | ->form([
33 | Textarea::make('notes')->required(),
34 | ]),
35 | ];
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/resources/svg/icon_tracktalks.svg:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/resources/views/talks/listing.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | @svg('compose', 'w-5 fill-current inline')
5 |
6 |
7 | @svg('trash', 'w-5 fill-current inline')
8 |
9 | @if ($talk->isArchived())
10 |
11 | @svg('folder-outline', 'w-5 fill-current inline')
12 |
13 | @else
14 |
15 | @svg('folder', 'w-5 fill-current inline')
16 |
17 | @endif
18 |
19 |
20 |
21 |
Created
22 |
{{ $talk->created_at->toFormattedDateString() }}
23 |
24 |
25 |
{{ $talk->currentRevision->length }}-minute {{ $talk->currentRevision->level }} {{ $talk->currentRevision->type }}
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/Http/Controllers/Auth/LoginController.php:
--------------------------------------------------------------------------------
1 | loginUser($request);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/Services/CreateBioForm.php:
--------------------------------------------------------------------------------
1 | ['required'],
13 | 'body' => ['required'],
14 | 'public' => [],
15 | ];
16 |
17 | private $input;
18 |
19 | private $user;
20 |
21 | private function __construct($input, $user)
22 | {
23 | $this->input = $this->removeEmptyFields($input);
24 |
25 | $this->input['public'] = array_key_exists('public', $this->input) &&
26 | $this->input['public'] == '1';
27 |
28 | $this->user = $user;
29 | }
30 |
31 | public static function fillOut($input, $user)
32 | {
33 | return new self($input, $user);
34 | }
35 |
36 | public function complete()
37 | {
38 | $validation = Validator::make($this->input, $this->rules);
39 |
40 | if ($validation->fails()) {
41 | throw new ValidationException('Invalid input provided, see errors', $validation->errors());
42 | }
43 |
44 | return Bio::create(array_merge($this->input, [
45 | 'user_id' => $this->user->id,
46 | ]));
47 | }
48 |
49 | private function removeEmptyFields($input)
50 | {
51 | return array_filter($input);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tests/Feature/ConferenceIssuesTest.php:
--------------------------------------------------------------------------------
1 | create([
19 | 'closed_at' => null,
20 | ]);
21 | $closedIssue = ConferenceIssue::factory()->create([
22 | 'closed_at' => now(),
23 | ]);
24 |
25 | $this->assertTrue($openIssue->isOpen());
26 | $this->assertFalse($closedIssue->isOpen());
27 | }
28 |
29 | #[Test]
30 | public function closing_an_issue(): void
31 | {
32 | $user = User::factory()->create();
33 | $issue = ConferenceIssue::factory()->create();
34 | $this->assertTrue($issue->isOpen());
35 |
36 | $issue->close($user, 'This conference is spam');
37 |
38 | tap($issue->fresh(), function ($issue) use ($user) {
39 | $this->assertEquals($user->id, $issue->closed_by);
40 | $this->assertEquals('This conference is spam', $issue->admin_note);
41 | $this->assertNotNull($issue->closed_at);
42 | });
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/resources/views/components/panel/index.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'size' => 'lg',
3 | 'padding' => true,
4 | 'title',
5 | ])
6 |
7 | @php
8 | $styles = [
9 | 'sm' => 'p-0',
10 | 'md' => 'p-0',
11 | 'lg' => 'max-w-md mx-auto sm:max-w-3xl',
12 | 'xl' => 'w-full'
13 | ];
14 | @endphp
15 |
16 |
19 |
20 | @isset($title)
21 |
22 |
23 |
24 | {{ $title }}
25 |
26 |
27 | @isset($subtitle)
28 | {{ $subtitle }}
29 | @endisset
30 |
31 |
32 | @isset($actions)
33 | {{ $actions }}
34 | @endisset
35 |
36 | @endisset
37 |
38 |
39 |
40 | {{ $slot }}
41 |
42 |
43 | @isset($body)
44 | {{ $body }}
45 | @endisset
46 |
47 | @isset($footer)
48 |
49 | {{ $footer }}
50 |
51 | @endisset
52 |
53 |
54 |
--------------------------------------------------------------------------------
/resources/views/components/side-menu.blade.php:
--------------------------------------------------------------------------------
1 | @props([
2 | 'title',
3 | 'links' => [],
4 | 'defaults' => [],
5 | ])
6 |
7 |
8 | {{ $title }}
9 |
10 | @isset($body)
11 | {{ $body }}
12 | @endisset
13 |
14 | @foreach ($links as $key => $link)
15 | @php
16 | if (isset($link['query'])) {
17 | $key = key($link['query']);
18 | $isActive = request($key) === $link['query'][$key] ||
19 | ! request()->has($key) && $link['query'][$key] === $defaults[$key];
20 | } else {
21 | $isActive = false;
22 | }
23 | @endphp
24 |
{{ $link['label'] }}
35 | @endforeach
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/Feature/SyncCallingAllPapersEventsTest.php:
--------------------------------------------------------------------------------
1 | stubEvent();
27 | $this->mockClient();
28 |
29 | Artisan::call('callingallpapers:sync');
30 |
31 | $this->assertEquals(
32 | '2022-05-04 11:11:11',
33 | cache('conference_importer_last_ran_at'),
34 | );
35 | }
36 |
37 | #[Test]
38 | public function notifying_slack_when_command_errors(): void
39 | {
40 | Notification::fake();
41 | $this->stubEvent();
42 | $this->mockClientWithError();
43 |
44 | Artisan::call('callingallpapers:sync');
45 |
46 | Notification::assertSentToTightenSlack(ConferenceImporterError::class);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/ApiResources/Conference.php:
--------------------------------------------------------------------------------
1 | conference = $conference;
15 | }
16 |
17 | public function getId()
18 | {
19 | return $this->conference->id;
20 | }
21 |
22 | public function getType()
23 | {
24 | return 'conferences';
25 | }
26 |
27 | public function attributes()
28 | {
29 | return [
30 | 'title' => $this->conference->title,
31 | 'description' => $this->conference->description,
32 | 'url' => $this->conference->url,
33 | 'cfp_url' => $this->conference->cfp_url,
34 | 'starts_at' => (string) $this->conference->starts_at,
35 | 'ends_at' => (string) $this->conference->ends_at,
36 | 'cfp_starts_at' => (string) $this->conference->cfp_starts_at,
37 | 'cfp_ends_at' => (string) $this->conference->cfp_ends_at,
38 | ];
39 | }
40 |
41 | public function toArray()
42 | {
43 | return [
44 | 'id' => $this->getId(),
45 | 'type' => $this->getType(),
46 | 'attributes' => $this->attributes(),
47 | ];
48 | }
49 | }
50 |
--------------------------------------------------------------------------------