|
|
@ -0,0 +1,21 @@
|
||||||
|
image: node:14.17.1
|
||||||
|
|
||||||
|
pipelines:
|
||||||
|
branches:
|
||||||
|
VRFS-5232-new_react_frontend:
|
||||||
|
- step:
|
||||||
|
name: Build Production
|
||||||
|
script:
|
||||||
|
- cd jam-ui
|
||||||
|
- npm install
|
||||||
|
- CI=false npm run build
|
||||||
|
artifacts:
|
||||||
|
- jam-ui/build/**
|
||||||
|
- step:
|
||||||
|
name: Deploy to S3
|
||||||
|
deployment: production
|
||||||
|
script:
|
||||||
|
- pipe: atlassian/aws-s3-deploy:1.1.0
|
||||||
|
variables:
|
||||||
|
S3_BUCKET: "jamkazam-ui/prd"
|
||||||
|
LOCAL_PATH: "jam-ui/build"
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Browsers that we support
|
||||||
|
|
||||||
|
last 1 version
|
||||||
|
> 0.2%
|
||||||
|
not op_mini all
|
||||||
|
not dead
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
HOST=beta.jamkazam.local
|
||||||
|
PORT=4000
|
||||||
|
REACT_APP_ORIGIN=jamkazam.local
|
||||||
|
REACT_APP_LEGACY_BASE_URL=http://www.jamkazam.local:3000
|
||||||
|
REACT_APP_API_BASE_URL=http://www.jamkazam.local:3000/api
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
HOST=beta.jamkazam.com
|
||||||
|
PORT=4000
|
||||||
|
REACT_APP_ORIGIN=jamkazam.com
|
||||||
|
REACT_APP_LEGACY_BASE_URL=https://www.jamkazam.com
|
||||||
|
REACT_APP_API_BASE_URL=https://www.jamkazam.com/api
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"extends": ["react-app", "prettier", "plugin:react/recommended"],
|
||||||
|
"plugins": ["prettier"],
|
||||||
|
"rules": {
|
||||||
|
"prettier/prettier": "error",
|
||||||
|
"react/no-unescaped-entities": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
.cypress.env.json
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
/test-results
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Using the node alpine image to build the React app
|
||||||
|
image: node:alpine
|
||||||
|
|
||||||
|
# Announce the URL as per CRA docs
|
||||||
|
# https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#advanced-configuration
|
||||||
|
variables:
|
||||||
|
PUBLIC_URL: /react-falcon
|
||||||
|
# Cache node modules - speeds up future builds
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- node_modules
|
||||||
|
|
||||||
|
# Name the stages involved in the pipeline
|
||||||
|
stages:
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
# Job name for gitlab to recognise this results in assets for Gitlab Pages
|
||||||
|
# https://docs.gitlab.com/ee/user/project/pages/introduction.html#gitlab-pages-requirements
|
||||||
|
pages:
|
||||||
|
stage: deploy
|
||||||
|
script:
|
||||||
|
- npm install # Install all dependencies
|
||||||
|
- npm run build --prod # Build for prod
|
||||||
|
- mv public _public # CRA and gitlab pages both use the public folder. Only do this in a build pipeline.
|
||||||
|
- mv build public # Move build files to public dir for Gitlab Pages
|
||||||
|
- cp public/index.html public/404.html # Required for react router browser history, but helps with https://blog.pshrmn.com/how-single-page-applications-work/
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public # The built files for Gitlab Pages to serve
|
||||||
|
only:
|
||||||
|
- master # Only run on master branch
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 120
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
# JamKazam new react frontend UI/UX
|
||||||
|
|
||||||
|
## Running react app
|
||||||
|
|
||||||
|
In production this React app is supposed to run on beta.jamkazam.com subdomain which is same origin domain to the production Rails app (www.jamkazam.com). This way we utilize same session based user authentication of Rails web app for authenticating users. (It looks for remember_token session cookie in headers and if it is not availale redirect the user to Rails web app sign in page)
|
||||||
|
|
||||||
|
The DOMAIN and PORT running this app is defined in env.production file. This file also has env variables for connecting with Rails app. (When setting up in development you can copy the content of env.development.example in to env.development.local and change them according to your host setup)
|
||||||
|
|
||||||
|
HOST=beta.jamkazam.local
|
||||||
|
PORT=4000
|
||||||
|
REACT_APP_LEGACY_BASE_URL=http://www.jamkazam.local:3000
|
||||||
|
REACT_APP_API_BASE_URL=http://www.jamkazam.local:3000/api
|
||||||
|
|
||||||
|
## Subdomains setup (development)
|
||||||
|
|
||||||
|
You need 2 host records created for React and and Rails app. For example
|
||||||
|
|
||||||
|
127.0.0.1 www.jamkazam.local #for Rails app
|
||||||
|
127.0.0.1 beta.jamkazam.local #for React app
|
||||||
|
|
||||||
|
## Installing npm dependencies
|
||||||
|
cd jam-ui
|
||||||
|
npm install
|
||||||
|
|
||||||
|
## Running the app
|
||||||
|
|
||||||
|
cd jam-ui
|
||||||
|
npm run start
|
||||||
|
|
||||||
|
This will open it in a borwser window at http://beta.jamkazam.local:3000. Of course for it to work you also need Rails (web) app and websocket app (websocket-gateway) running.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"baseUrl": "http://beta.jamkazam.local:4000",
|
||||||
|
"legacyBaseUrl": "http://www.jamkazam.local:3000",
|
||||||
|
"apiBaseUrl": "http://www.jamkazam.local:3000/api"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"baseUrl": "http://beta.jamkazam.local:4000",
|
||||||
|
"env": {
|
||||||
|
"legacyBaseUrl": "http://www.jamkazam.local:3000",
|
||||||
|
"apiBaseUrl": "http://www.jamkazam.local:3000/api"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User1",
|
||||||
|
"name": "Test User1",
|
||||||
|
"city": "Denver",
|
||||||
|
"state": "CO",
|
||||||
|
"country": "US",
|
||||||
|
"location": "Denver, CO",
|
||||||
|
"online": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"musician": true,
|
||||||
|
"gender": "M",
|
||||||
|
"birth_date": null,
|
||||||
|
"friend_count": 1,
|
||||||
|
"liker_count": 0,
|
||||||
|
"follower_count": 0,
|
||||||
|
"following_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"biography": "Biography of Test User1",
|
||||||
|
"favorite_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"upcoming_session_count": 0,
|
||||||
|
"age": null,
|
||||||
|
"website": "www.testuser1.com",
|
||||||
|
"skill_level": 2,
|
||||||
|
"concert_count": 4,
|
||||||
|
"studio_session_count": 4,
|
||||||
|
"virtual_band": true,
|
||||||
|
"virtual_band_commitment": 2,
|
||||||
|
"traditional_band": true,
|
||||||
|
"traditional_band_commitment": 4,
|
||||||
|
"traditional_band_touring": true,
|
||||||
|
"paid_sessions": true,
|
||||||
|
"paid_sessions_hourly_rate": 10000,
|
||||||
|
"paid_sessions_daily_rate": 200000,
|
||||||
|
"free_sessions": true,
|
||||||
|
"cowriting": true,
|
||||||
|
"cowriting_purpose": 2,
|
||||||
|
"subscribe_email": true,
|
||||||
|
"is_a_teacher": false,
|
||||||
|
"is_a_student": false,
|
||||||
|
"online_presences": [
|
||||||
|
{ "id": "e1962204-f652-41b0-84d6-1afd7e9172be", "service_type": "soundcloud", "username": "testuser" },
|
||||||
|
{ "id": "005a7c78-db8b-4f72-a51f-d64d579c22b0", "service_type": "reverbnation", "username": "testuser" },
|
||||||
|
{ "id": "2dd22eef-03ba-4743-b65b-5a194591dc86", "service_type": "bandcamp", "username": "testuser" },
|
||||||
|
{ "id": "d6ae62b4-e1ce-4cf0-90b7-c64033533261", "service_type": "fandalism", "username": "testuser" },
|
||||||
|
{ "id": "c6e85453-0fa9-40d0-9754-8f372d6e0ed3", "service_type": "youtube", "username": "testuser" },
|
||||||
|
{ "id": "480ec1ad-ea1d-4990-9c68-d7f9c0174441", "service_type": "facebook", "username": "testuser" },
|
||||||
|
{ "id": "232b26d5-c75a-4d65-9013-a07b73c8a7ae", "service_type": "twitter", "username": "testuser" }
|
||||||
|
],
|
||||||
|
"performance_samples": [],
|
||||||
|
"genres": [
|
||||||
|
{ "genre_id": "asian", "player_type": "JamRuby::User", "genre_type": "profile" },
|
||||||
|
{ "genre_id": "classical", "player_type": "JamRuby::User", "genre_type": "profile" },
|
||||||
|
{ "genre_id": "african", "player_type": "JamRuby::User", "genre_type": "virtual_band" },
|
||||||
|
{ "genre_id": "classical", "player_type": "JamRuby::User", "genre_type": "virtual_band" },
|
||||||
|
{ "genre_id": "classical", "player_type": "JamRuby::User", "genre_type": "traditional_band" },
|
||||||
|
{ "genre_id": "blues", "player_type": "JamRuby::User", "genre_type": "free_sessions" },
|
||||||
|
{ "genre_id": "soft rock", "player_type": "JamRuby::User", "genre_type": "free_sessions" },
|
||||||
|
{ "genre_id": "celtic", "player_type": "JamRuby::User", "genre_type": "cowriting" },
|
||||||
|
{ "genre_id": "tv & movie soundtrack", "player_type": "JamRuby::User", "genre_type": "cowriting" }
|
||||||
|
],
|
||||||
|
"bands": [],
|
||||||
|
"instruments": [
|
||||||
|
{ "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1, "instrument_id": "acoustic guitar" },
|
||||||
|
{ "description": "Keyboard", "proficiency_level": 3, "priority": 8, "instrument_id": "keyboard" },
|
||||||
|
{ "description": "Ukulele", "proficiency_level": 3, "priority": 11, "instrument_id": "ukulele" },
|
||||||
|
{ "description": "Voice", "proficiency_level": 3, "priority": 13, "instrument_id": "voice" },
|
||||||
|
{ "description": "Piano", "proficiency_level": 2, "priority": 10, "instrument_id": "piano" }
|
||||||
|
],
|
||||||
|
"is_friend": true,
|
||||||
|
"is_following": false,
|
||||||
|
"is_liking": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"my_audio_latency": 5,
|
||||||
|
"internet_score": null
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description": "TEXT_MESSAGE",
|
||||||
|
"source_user_id": "27bd4a30-d1b8-4eea-8454-01a104d59381",
|
||||||
|
"target_user_id": "a09f9a7e-afb7-489d-870d-e13a336e0b97",
|
||||||
|
"session_id": null,
|
||||||
|
"recording_id": null,
|
||||||
|
"invitation_id": null,
|
||||||
|
"join_request_id": null,
|
||||||
|
"friend_request_id": null,
|
||||||
|
"band_id": null,
|
||||||
|
"band_invitation_id": null,
|
||||||
|
"formatted_msg": "TEXT_MESSAGE",
|
||||||
|
"message": "Hello",
|
||||||
|
"created_at": "2021-10-07T00:09:57.704Z",
|
||||||
|
"lesson_session_id": null,
|
||||||
|
"purpose": null,
|
||||||
|
"source_user": {
|
||||||
|
"name": "Nuwan Chaturanga"
|
||||||
|
},
|
||||||
|
"notification_id": "63fcd878-9a22-4419-9cee-8a51a615da97",
|
||||||
|
"fan_access": null,
|
||||||
|
"musician_access": null,
|
||||||
|
"approval_required": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "FRIEND_REQUEST",
|
||||||
|
"source_user_id": "a09f9a7e-afb7-489d-870d-e13a336e0b97",
|
||||||
|
"target_user_id": "b1ddadd0-0263-47c4-bf91-e7767f386970",
|
||||||
|
"session_id": null,
|
||||||
|
"recording_id": null,
|
||||||
|
"invitation_id": null,
|
||||||
|
"join_request_id": null,
|
||||||
|
"friend_request_id": "7c842904-24f5-4515-8886-0c3d25ee641b",
|
||||||
|
"band_id": null,
|
||||||
|
"band_invitation_id": null,
|
||||||
|
"formatted_msg": "Seth Call has sent you a friend request.",
|
||||||
|
"message": null,
|
||||||
|
"created_at": "2021-10-15T05:36:48.527Z",
|
||||||
|
"lesson_session_id": null,
|
||||||
|
"purpose": null,
|
||||||
|
"source_user": {
|
||||||
|
"name": "Seth Call"
|
||||||
|
},
|
||||||
|
"notification_id": "3364b5f1-8946-46a3-b635-86d89d237849",
|
||||||
|
"fan_access": null,
|
||||||
|
"musician_access": null,
|
||||||
|
"approval_required": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "FRIEND_REQUEST_ACCEPTED",
|
||||||
|
"source_user_id": "29becbf4-8be5-4078-9405-0edadc9fa42d",
|
||||||
|
"target_user_id": "b1ddadd0-0263-47c4-bf91-e7767f386970",
|
||||||
|
"session_id": null,
|
||||||
|
"recording_id": null,
|
||||||
|
"invitation_id": null,
|
||||||
|
"join_request_id": null,
|
||||||
|
"friend_request_id": null,
|
||||||
|
"band_id": null,
|
||||||
|
"band_invitation_id": null,
|
||||||
|
"formatted_msg": "Peter Walker has accepted your friend request.",
|
||||||
|
"message": null,
|
||||||
|
"created_at": "2021-10-05T12:38:53.134Z",
|
||||||
|
"lesson_session_id": null,
|
||||||
|
"purpose": null,
|
||||||
|
"source_user": {
|
||||||
|
"name": "Peter Walker"
|
||||||
|
},
|
||||||
|
"notification_id": "bb9269f3-721c-48cd-9bf6-bcff72877198",
|
||||||
|
"fan_access": null,
|
||||||
|
"musician_access": null,
|
||||||
|
"approval_required": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,558 @@
|
||||||
|
{
|
||||||
|
"musicians": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User1",
|
||||||
|
"name": "Test User1",
|
||||||
|
"city": "Denver",
|
||||||
|
"state": "CO",
|
||||||
|
"country": "US",
|
||||||
|
"online": true,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "Biography of Test User1. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 },
|
||||||
|
{ "instrument_id": "keyboard", "description": "Keyboard", "proficiency_level": 3, "priority": 8 },
|
||||||
|
{ "instrument_id": "ukulele", "description": "Ukulele", "proficiency_level": 3, "priority": 11 },
|
||||||
|
{ "instrument_id": "voice", "description": "Voice", "proficiency_level": 3, "priority": 13 },
|
||||||
|
{ "instrument_id": "piano", "description": "Piano", "proficiency_level": 2, "priority": 10 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": true,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 1,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 10,
|
||||||
|
"audio_latency": 5,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User2",
|
||||||
|
"name": "Test User2",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "Biography of Test User2.",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User3",
|
||||||
|
"name": "Test User3",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User4",
|
||||||
|
"name": "Test User4",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User5",
|
||||||
|
"name": "Test User5",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User6",
|
||||||
|
"name": "Test User6",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User7",
|
||||||
|
"name": "Test User7",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User8",
|
||||||
|
"name": "Test User8",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User9",
|
||||||
|
"name": "Test User9",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User10",
|
||||||
|
"name": "Test User10",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "11",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User11",
|
||||||
|
"name": "Test User11",
|
||||||
|
"city": "Denver",
|
||||||
|
"state": "CO",
|
||||||
|
"country": "US",
|
||||||
|
"online": true,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "Biography of Test User1",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 },
|
||||||
|
{ "instrument_id": "keyboard", "description": "Keyboard", "proficiency_level": 3, "priority": 8 },
|
||||||
|
{ "instrument_id": "ukulele", "description": "Ukulele", "proficiency_level": 3, "priority": 11 },
|
||||||
|
{ "instrument_id": "voice", "description": "Voice", "proficiency_level": 3, "priority": 13 },
|
||||||
|
{ "instrument_id": "piano", "description": "Piano", "proficiency_level": 2, "priority": 10 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": true,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 1,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 10,
|
||||||
|
"audio_latency": 5,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "12",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User12",
|
||||||
|
"name": "Test User12",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User13",
|
||||||
|
"name": "Test User13",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "14",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User14",
|
||||||
|
"name": "Test User14",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "15",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User15",
|
||||||
|
"name": "Test User15",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "16",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User16",
|
||||||
|
"name": "Test User16",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "17",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User17",
|
||||||
|
"name": "Test User17",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "18",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User18",
|
||||||
|
"name": "Test User18",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "19",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User19",
|
||||||
|
"name": "Test User19",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "20",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User20",
|
||||||
|
"name": "Test User20",
|
||||||
|
"city": "Austin",
|
||||||
|
"state": "TX",
|
||||||
|
"country": "US",
|
||||||
|
"online": false,
|
||||||
|
"musician": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"biography": "",
|
||||||
|
"full_score": null,
|
||||||
|
"instruments": [
|
||||||
|
{ "instrument_id": "acoustic guitar", "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1 }
|
||||||
|
],
|
||||||
|
"followings": [],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"friend_count": 0,
|
||||||
|
"follow_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"page_count": 2,
|
||||||
|
"my_audio_latency": 5,
|
||||||
|
"filter_json": "{\"id\":\"68dcc055-cb5d-40d6-8ed4-66772d1a1a31\",\"user_id\":\"27bd4a30-d1b8-4eea-8454-01a104d59381\",\"foreign_key1_id\":null,\"data_blob\":{\"sort_order\":\"latency\",\"instruments\":[],\"genres\":[],\"concert_gigs\":\"-1\",\"interests\":\"any\",\"studio_sessions\":\"-1\",\"ages\":[],\"skill_level\":\"-1\"}}",
|
||||||
|
"description": "Current Search: Sort = Latency to Me",
|
||||||
|
"is_blank_filter": false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "User1",
|
||||||
|
"name": "Test User1",
|
||||||
|
"city": "Denver",
|
||||||
|
"state": "CO",
|
||||||
|
"country": "US",
|
||||||
|
"location": "Denver, CO",
|
||||||
|
"online": true,
|
||||||
|
"photo_url": null,
|
||||||
|
"musician": true,
|
||||||
|
"gender": "M",
|
||||||
|
"birth_date": null,
|
||||||
|
"friend_count": 1,
|
||||||
|
"liker_count": 0,
|
||||||
|
"follower_count": 0,
|
||||||
|
"following_count": 0,
|
||||||
|
"recording_count": 0,
|
||||||
|
"session_count": 0,
|
||||||
|
"biography": "Biography of Test User1",
|
||||||
|
"favorite_count": 0,
|
||||||
|
"audio_latency": null,
|
||||||
|
"upcoming_session_count": 0,
|
||||||
|
"age": null,
|
||||||
|
"website": "www.testuser1.com",
|
||||||
|
"skill_level": 2,
|
||||||
|
"concert_count": 4,
|
||||||
|
"studio_session_count": 4,
|
||||||
|
"virtual_band": true,
|
||||||
|
"virtual_band_commitment": 2,
|
||||||
|
"traditional_band": true,
|
||||||
|
"traditional_band_commitment": 4,
|
||||||
|
"traditional_band_touring": true,
|
||||||
|
"paid_sessions": true,
|
||||||
|
"paid_sessions_hourly_rate": 10000,
|
||||||
|
"paid_sessions_daily_rate": 200000,
|
||||||
|
"free_sessions": true,
|
||||||
|
"cowriting": true,
|
||||||
|
"cowriting_purpose": 2,
|
||||||
|
"subscribe_email": true,
|
||||||
|
"is_a_teacher": false,
|
||||||
|
"is_a_student": false,
|
||||||
|
"online_presences": [
|
||||||
|
{ "id": "e1962204-f652-41b0-84d6-1afd7e9172be", "service_type": "soundcloud", "username": "testuser" },
|
||||||
|
{ "id": "005a7c78-db8b-4f72-a51f-d64d579c22b0", "service_type": "reverbnation", "username": "testuser" },
|
||||||
|
{ "id": "2dd22eef-03ba-4743-b65b-5a194591dc86", "service_type": "bandcamp", "username": "testuser" }
|
||||||
|
],
|
||||||
|
"performance_samples": [],
|
||||||
|
"genres": [
|
||||||
|
{ "genre_id": "classical", "player_type": "JamRuby::User", "genre_type": "profile" },
|
||||||
|
{ "genre_id": "blues", "player_type": "JamRuby::User", "genre_type": "free_sessions" }
|
||||||
|
],
|
||||||
|
"bands": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"name": "The Band",
|
||||||
|
"admin": true,
|
||||||
|
"photo_url": "",
|
||||||
|
"logo_url": "",
|
||||||
|
"genres": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "pop"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"instruments": [
|
||||||
|
{ "description": "Acoustic Guitar", "proficiency_level": 3, "priority": 1, "instrument_id": "acoustic guitar" },
|
||||||
|
{ "description": "Keyboard", "proficiency_level": 3, "priority": 8, "instrument_id": "keyboard" }
|
||||||
|
],
|
||||||
|
"is_friend": false,
|
||||||
|
"is_following": false,
|
||||||
|
"is_liking": false,
|
||||||
|
"pending_friend_request": false,
|
||||||
|
"my_audio_latency": 5,
|
||||||
|
"internet_score": null,
|
||||||
|
"created_at_timestamp": 1629917088,
|
||||||
|
"last_active_timestamp": 1629916641
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 1",
|
||||||
|
"created_at": "2021-09-20T15:15:15.970Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 2",
|
||||||
|
"created_at": "2021-09-20T15:14:48.821Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 3",
|
||||||
|
"created_at": "2021-09-20T15:13:02.367Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 4",
|
||||||
|
"created_at": "2021-09-18T21:39:58.493Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 5",
|
||||||
|
"created_at": "2021-09-18T21:37:29.752Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 6",
|
||||||
|
"created_at": "2021-09-18T21:37:22.319Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 7",
|
||||||
|
"created_at": "2021-09-18T21:37:12.366Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 8",
|
||||||
|
"created_at": "2021-09-18T21:23:50.070Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 9",
|
||||||
|
"created_at": "2021-09-18T21:23:45.271Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 10",
|
||||||
|
"created_at": "2021-09-18T21:23:07.918Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "11",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 11",
|
||||||
|
"created_at": "2021-09-17T15:15:15.970Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "12",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 12",
|
||||||
|
"created_at": "2021-09-17T15:14:48.821Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 13",
|
||||||
|
"created_at": "2021-09-17T15:13:02.367Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "14",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 14",
|
||||||
|
"created_at": "2021-09-15T21:39:58.493Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "15",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 15",
|
||||||
|
"created_at": "2021-09-15T21:37:29.752Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "16",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 16",
|
||||||
|
"created_at": "2021-09-15T21:37:22.319Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "17",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 17",
|
||||||
|
"created_at": "2021-09-15T21:37:12.366Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "18",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 18",
|
||||||
|
"created_at": "2021-09-15T21:23:50.070Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "19",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 19",
|
||||||
|
"created_at": "2021-09-15T21:23:45.271Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "20",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 20",
|
||||||
|
"created_at": "2021-09-15T21:23:07.918Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "21",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 21",
|
||||||
|
"created_at": "2021-09-14T15:15:15.970Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "22",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 22",
|
||||||
|
"created_at": "2021-09-14T15:14:48.821Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "23",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 23",
|
||||||
|
"created_at": "2021-09-17T12:13:02.367Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "24",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 24",
|
||||||
|
"created_at": "2021-09-12T21:39:58.493Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "25",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 25",
|
||||||
|
"created_at": "2021-09-12T21:37:29.752Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "26",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 26",
|
||||||
|
"created_at": "2021-09-12T21:37:22.319Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "27",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 27",
|
||||||
|
"created_at": "2021-09-12T21:37:12.366Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "28",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 28",
|
||||||
|
"created_at": "2021-09-12T21:23:50.070Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "29",
|
||||||
|
"source_user_id": "2",
|
||||||
|
"target_user_id": "1",
|
||||||
|
"message": "Test Message 29",
|
||||||
|
"created_at": "2021-09-12T21:23:45.271Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "30",
|
||||||
|
"source_user_id": "1",
|
||||||
|
"target_user_id": "2",
|
||||||
|
"message": "Test Message 30",
|
||||||
|
"created_at": "2021-09-12T21:23:07.918Z",
|
||||||
|
"source_user": {
|
||||||
|
"id": "1",
|
||||||
|
"name": "Test User1"
|
||||||
|
},
|
||||||
|
"target_user": {
|
||||||
|
"id": "2",
|
||||||
|
"name": "Test User2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,367 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
describe('Friends page without data', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.stubAuthenticate();
|
||||||
|
cy.intercept('POST', /\S+\/filter/, {
|
||||||
|
musicians: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows no records alert', () => {
|
||||||
|
cy.visit('/friends');
|
||||||
|
cy.contains('No Records!');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Friends page with data', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.stubAuthenticate({ id: '2' }); //currentUser id is 2 - people.yaml fixture
|
||||||
|
cy.intercept('POST', /\S+\/filter/, { fixture: 'people' }).as('getPeople');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('listing users', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('/friends');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lists musician users', () => {
|
||||||
|
cy.contains('Find New Friends').should('exist');
|
||||||
|
cy.contains('Update Search').should('exist');
|
||||||
|
cy.contains('Reset Filters').should('exist');
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.should('have.length', 20)
|
||||||
|
.first()
|
||||||
|
.contains('Test User1');
|
||||||
|
});
|
||||||
|
|
||||||
|
//TODO: paginate
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('user details side panel', () => {
|
||||||
|
const showSidePanelContent = () => {
|
||||||
|
cy.get('[data-testid=profileSidePanel] h4').should('have.text', 'Test User1');
|
||||||
|
cy.get('[data-testid=profileSidePanel] .modal-body p').within(() => {
|
||||||
|
cy.contains('Location: Denver, US')
|
||||||
|
.and('contain', 'Location: Denver, US')
|
||||||
|
.and('contain', 'Skill Level: Professional')
|
||||||
|
.and('contain', 'Joined JamKazam: 08-26-2021')
|
||||||
|
.and('contain', 'Last Active:')
|
||||||
|
.and('contain', 'Latency to Me:');
|
||||||
|
cy.get('.latency-badge').contains('UNKNOWN');
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-testid=profileSidePanel] .modal-body').within(() => {
|
||||||
|
cy.get('[data-testid=biography]').contains('Biography of Test User1');
|
||||||
|
|
||||||
|
//instruments
|
||||||
|
cy.get('[data-testid=instruments]').contains('Acoustic Guitar: Expert');
|
||||||
|
cy.get('[data-testid=instruments]').contains('Keyboard: Expert');
|
||||||
|
|
||||||
|
//genres
|
||||||
|
cy.get('[data-testid=genres]').contains('classical, blues');
|
||||||
|
|
||||||
|
//bands
|
||||||
|
cy.get('[data-testid=bands]').contains('The Band');
|
||||||
|
|
||||||
|
//performance_samples
|
||||||
|
//cy.get('[data-testid=performance_samples]').contains('The Band')
|
||||||
|
|
||||||
|
//online presence
|
||||||
|
cy.get('[data-testid=online_presences]').contains('Soundcloud');
|
||||||
|
cy.get('[data-testid=online_presences]').contains('Reverbnation');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeSidePanel = () => {
|
||||||
|
cy.get('[data-testid=profileSidePanel] .modal-header button.close').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' });
|
||||||
|
cy.visit('/friends');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows profile side panel', () => {
|
||||||
|
//open side panel by clicking name
|
||||||
|
cy.contains('Test User1').click();
|
||||||
|
showSidePanelContent();
|
||||||
|
closeSidePanel();
|
||||||
|
|
||||||
|
//open side panel by clicking more button
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.first()
|
||||||
|
.find('[data-testid=btnMore]')
|
||||||
|
.click();
|
||||||
|
showSidePanelContent();
|
||||||
|
closeSidePanel();
|
||||||
|
|
||||||
|
//open side panel by clicking more link
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.first()
|
||||||
|
.find('[data-testid=linkMore]')
|
||||||
|
.click();
|
||||||
|
showSidePanelContent();
|
||||||
|
closeSidePanel();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('making friendship', () => {
|
||||||
|
it('add friend', () => {
|
||||||
|
cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' });
|
||||||
|
cy.intercept('POST', /\S+\/friend_requests/, { statusCode: 201, body: { ok: true } });
|
||||||
|
|
||||||
|
cy.visit('/friends');
|
||||||
|
cy.contains('Test User1').click();
|
||||||
|
|
||||||
|
cy.get('[data-testid=profileSidePanel]')
|
||||||
|
.find('[data-testid=connect]')
|
||||||
|
.should('not.be.disabled')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-testid=profileSidePanel]')
|
||||||
|
.find('[data-testid=connect]')
|
||||||
|
.should('be.disabled');
|
||||||
|
cy.contains('Friend request was sent');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove friend', () => {
|
||||||
|
cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'friend' });
|
||||||
|
cy.intercept('DELETE', /\S+\/friends\S+/, { statusCode: 204, body: { ok: true } });
|
||||||
|
|
||||||
|
cy.visit('/friends');
|
||||||
|
cy.contains('Test User1').click();
|
||||||
|
|
||||||
|
cy.get('[data-testid=profileSidePanel]')
|
||||||
|
.find('[data-testid=disconnect]')
|
||||||
|
.should('exist')
|
||||||
|
.should('not.be.disabled')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-testid=profileSidePanel]')
|
||||||
|
.find('[data-testid=disconnect]')
|
||||||
|
.should('not.exist');
|
||||||
|
|
||||||
|
cy.get('[data-testid=profileSidePanel]')
|
||||||
|
.find('[data-testid=connect]')
|
||||||
|
.should('be.exist')
|
||||||
|
.should('not.be.disabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('chat window', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('/friends');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('is not disabled for friends', () => {
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.eq(0)
|
||||||
|
.find('[data-testid=message]')
|
||||||
|
.should('not.be.disabled')
|
||||||
|
.trigger('mouseover');
|
||||||
|
cy.contains('Send a message').should('exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('is disabled for non friends', () => {
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.eq(1)
|
||||||
|
.find('[data-testid=message]')
|
||||||
|
.should('be.disabled');
|
||||||
|
//cy.contains('You can message this user once you are friends').should('exist')
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lists text messages', () => {
|
||||||
|
//initially show the most recent messages on openning chat window modal
|
||||||
|
let numberOfMessages = 10;
|
||||||
|
cy.fixture('text_messages_page1').then(json => {
|
||||||
|
cy.intercept('GET', /\S+\/text_messages\S+/, json).as('getTextMessages');
|
||||||
|
});
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.eq(0)
|
||||||
|
.find('[data-testid=message]')
|
||||||
|
.click();
|
||||||
|
cy.wait('@getTextMessages');
|
||||||
|
cy.get('[data-testid=textMessageModal]')
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get('.text-message-row').should('have.length', numberOfMessages);
|
||||||
|
|
||||||
|
//display previous messages by scrolling up
|
||||||
|
const messageFixtures = ['text_messages_page2', 'text_messages_page3'];
|
||||||
|
messageFixtures.forEach(fixture => {
|
||||||
|
cy.fixture(fixture).then(json => {
|
||||||
|
cy.intercept('GET', /\S+\/text_messages\S+/, json);
|
||||||
|
cy.get('.modal-body .ScrollbarsCustom')
|
||||||
|
.trigger('mouseover')
|
||||||
|
.scrollTo('bottom');
|
||||||
|
cy.get('.modal-body .ScrollbarsCustom')
|
||||||
|
.trigger('mouseover')
|
||||||
|
.scrollTo('top');
|
||||||
|
numberOfMessages = numberOfMessages + 10;
|
||||||
|
cy.get('.text-message-row').should('have.length', numberOfMessages);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains('Close')
|
||||||
|
.should('not.be.disabled')
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
cy.get('[data-testid=textMessageModal]').should('not.be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends message by clicking send button', () => {
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.eq(0)
|
||||||
|
.find('[data-testid=message]')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-testid=textMessageModal]').within(() => {
|
||||||
|
cy.get('button')
|
||||||
|
.contains('Send')
|
||||||
|
.should('be.disabled');
|
||||||
|
cy.get('textarea').type('Hello');
|
||||||
|
cy.get('button')
|
||||||
|
.contains('Send')
|
||||||
|
.should('not.be.disabled')
|
||||||
|
.click();
|
||||||
|
cy.get('textarea').should('have.value', '');
|
||||||
|
cy.get('button')
|
||||||
|
.contains('Send')
|
||||||
|
.should('be.disabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends message by pressing enter key', () => {
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.eq(0)
|
||||||
|
.find('[data-testid=message]')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-testid=textMessageModal]').within(() => {
|
||||||
|
cy.get('button')
|
||||||
|
.contains('Send')
|
||||||
|
.should('be.disabled');
|
||||||
|
cy.get('textarea').type('Hello{enter}');
|
||||||
|
cy.get('textarea').should('have.value', '');
|
||||||
|
cy.get('button')
|
||||||
|
.contains('Send')
|
||||||
|
.should('be.disabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('goes away by clicking close button', () => {
|
||||||
|
cy.get('[data-testid=peopleListTable] > tbody tr')
|
||||||
|
.eq(0)
|
||||||
|
.find('[data-testid=message]')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-testid=textMessageModal]').within(() => {
|
||||||
|
cy.get('button')
|
||||||
|
.contains('Close')
|
||||||
|
.should('not.be.disabled')
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
cy.get('[data-testid=textMessageModal]').should('not.be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('shows received message by other user', () => {
|
||||||
|
//TODO: this should be test in e2e test
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('filter', () => {
|
||||||
|
const fillFilterForm = () => {
|
||||||
|
//cy.get('[data-testid=btnUpdateSearch]').click();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=latency_good]').uncheck();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=latency_fair]').uncheck();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=latency_high]').uncheck();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_beginner]').uncheck();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_intermediate]').uncheck();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_expert]').uncheck();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=proficiency_expert]').uncheck();
|
||||||
|
cy.get('#selInstruments')
|
||||||
|
.type('Drums{enter}')
|
||||||
|
.click();
|
||||||
|
cy.get('#selGenres')
|
||||||
|
.type('Pop{enter}')
|
||||||
|
.click();
|
||||||
|
cy.get('#selLastActive').type('Within last 1 Day{enter}');
|
||||||
|
cy.get('#selJoinedWithin').type('Within last 7 Day{enter}');
|
||||||
|
}
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('/friends');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('open and close filter modal', () => {
|
||||||
|
cy.get('[data-testid=btnUpdateSearch]').click();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch]').should('be.visible');
|
||||||
|
cy.get('[data-testid=modalUpdateSearch]')
|
||||||
|
.contains('Cancel')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch]').should('not.be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reset filters', () => {
|
||||||
|
cy.get('[data-testid=btnUpdateSearch]').click();
|
||||||
|
fillFilterForm()
|
||||||
|
cy.get('[data-testid=modalUpdateSearch]')
|
||||||
|
.contains('Cancel')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-testid=btnUpdateSearch]').click();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=latency_good]').should('not.be.checked')
|
||||||
|
cy.get('[data-testid=modalUpdateSearch]')
|
||||||
|
.contains('Cancel')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-testid=btnResetSearch]').click() //click reset button
|
||||||
|
cy.get('[data-testid=btnUpdateSearch]').click();
|
||||||
|
cy.get('[data-testid=modalUpdateSearch] input[name=latency_good]').should('be.checked')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('submit filter form with params', () => {
|
||||||
|
//wait for stubbed request sent to fetch data for initial page load
|
||||||
|
cy.wait('@getPeople').then(interception => {
|
||||||
|
assert.isNotNull(interception.response.body, '1st API call has data');
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-testid=btnUpdateSearch]').click();
|
||||||
|
cy.get('[data-testid=btnSubmitSearch]').click();
|
||||||
|
//wait for stubbed request sent by submitting search form without filling any form field
|
||||||
|
cy.wait('@getPeople')
|
||||||
|
.then(interception => {
|
||||||
|
assert.isNotNull(interception.response.body, '2nd API call has data');
|
||||||
|
})
|
||||||
|
.its('request.body')
|
||||||
|
.should('deep.equal', {
|
||||||
|
latency_good: true,
|
||||||
|
latency_fair: true,
|
||||||
|
latency_high: true,
|
||||||
|
proficiency_beginner: true,
|
||||||
|
proficiency_intermediate: true,
|
||||||
|
proficiency_expert: true,
|
||||||
|
instruments: [],
|
||||||
|
genres: []
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-testid=btnUpdateSearch]').click();
|
||||||
|
fillFilterForm()
|
||||||
|
cy.get('[data-testid=btnSubmitSearch]').click();
|
||||||
|
|
||||||
|
//wait for stubbed request sent by submitting search form again. but this time fill form fields
|
||||||
|
cy.wait('@getPeople')
|
||||||
|
.then(interception => {
|
||||||
|
assert.isNotNull(interception.response.body, '3rd API call has data');
|
||||||
|
})
|
||||||
|
.its('request.body')
|
||||||
|
.should('deep.equal', {
|
||||||
|
latency_good: false,
|
||||||
|
latency_fair: false,
|
||||||
|
latency_high: false,
|
||||||
|
proficiency_beginner: false,
|
||||||
|
proficiency_intermediate: false,
|
||||||
|
proficiency_expert: false,
|
||||||
|
instruments: [{ value: 'drums', label: 'Drums' }],
|
||||||
|
genres: ['pop'],
|
||||||
|
active_within_days: '1',
|
||||||
|
joined_within_days: '7'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
describe("Top Navigation", () => {
|
||||||
|
|
||||||
|
const showSubscribeToUpdates = () => {
|
||||||
|
cy.contains('Keep JamKazam Improving').should('exist')
|
||||||
|
cy.contains('Subscribe').should('exist')
|
||||||
|
}
|
||||||
|
|
||||||
|
const showProfileDropdown = () => {
|
||||||
|
cy.get('[data-testid=navbarTopProfileDropdown]').should('exist')
|
||||||
|
cy.contains("Peter Pan").should('exist')
|
||||||
|
//cy.contains("My Profile").should('exist')
|
||||||
|
cy.contains("Sign out").should('exist')
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("when user has not logged in", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.stubUnauthenticate()
|
||||||
|
cy.visit('/')
|
||||||
|
});
|
||||||
|
|
||||||
|
it("does not show user dropdown", () => {
|
||||||
|
cy.contains("Sign in to begin")
|
||||||
|
cy.get('a.btn').should('have.text', 'Sign in')
|
||||||
|
cy.get('[data-testid=navbarTopProfileDropdown]').should('not.exist')
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("when user has logged in", () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.stubAuthenticate()
|
||||||
|
cy.visit('/')
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows user dropdown", () => {
|
||||||
|
showSubscribeToUpdates()
|
||||||
|
showProfileDropdown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sign out', () => {
|
||||||
|
|
||||||
|
cy.get('[data-testid=navbarTopProfileDropdown]').contains('Peter Pan').trigger('mouseover')
|
||||||
|
cy.stubUnauthenticate()
|
||||||
|
cy.get('[data-testid=navbarTopProfileDropdown]').contains('Sign out').click()
|
||||||
|
cy.get('[data-testid=navbarTopProfileDropdown]').should('not.exist')
|
||||||
|
cy.contains("Sign in to begin")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('header notifications', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.stubAuthenticate()
|
||||||
|
cy.intercept('GET', /\S+\/notifications/, { fixture: 'notifications'} )
|
||||||
|
cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' });
|
||||||
|
cy.visit('/')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows notifications', () => {
|
||||||
|
cy.get('[data-testid=notificationDropdown]').should('not.be.visible')
|
||||||
|
cy.get('.notification-indicator').trigger('mouseover')
|
||||||
|
cy.get('[data-testid=notificationDropdown]').should('be.visible')
|
||||||
|
cy.get('[data-testid=notificationDropdown] .list-group-item').should('have.length', 3)
|
||||||
|
cy.get('[data-testid=notificationDropdown]').contains('View all').click() //view all notifications
|
||||||
|
cy.url().should('include', '/notifications')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
// ***********************************************************
|
||||||
|
// This example plugins/index.js can be used to load plugins
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off loading
|
||||||
|
// the plugins file with the 'pluginsFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/plugins-guide
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// This function is called when a project is opened or re-opened (e.g. due to
|
||||||
|
// the project's config changing)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Cypress.PluginConfig}
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
module.exports = (on, config) => {
|
||||||
|
// `on` is used to hook into various events Cypress emits
|
||||||
|
// `config` is the resolved Cypress config
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
|
@ -0,0 +1,49 @@
|
||||||
|
// ***********************************************
|
||||||
|
// This example commands.js shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||||
|
|
||||||
|
|
||||||
|
Cypress.Commands.add('stubAuthenticate', (attrs = {}) => {
|
||||||
|
const defaultAttrs = {
|
||||||
|
id: '1',
|
||||||
|
first_name: 'Peter',
|
||||||
|
last_name: 'Pan',
|
||||||
|
name: 'Peter Pan',
|
||||||
|
photo_url: ''
|
||||||
|
}
|
||||||
|
const currentUserAtrs = {...defaultAttrs, ...attrs}
|
||||||
|
cy.intercept('GET', `${Cypress.env('apiBaseUrl')}/me`, {
|
||||||
|
statusCode: 200,
|
||||||
|
body: currentUserAtrs
|
||||||
|
}).as('getCurrentUser')
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('stubUnauthenticate', () => {
|
||||||
|
cy.intercept('GET', `${Cypress.env('apiBaseUrl')}/me`, {
|
||||||
|
statusCode: 401,
|
||||||
|
body: {}
|
||||||
|
}).as('getUnauthenticateCurrentUser')
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// ***********************************************************
|
||||||
|
// This example support/index.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands'
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
const gulp = require('gulp');
|
||||||
|
const plumber = require('gulp-plumber');
|
||||||
|
const sass = require('gulp-sass');
|
||||||
|
const autoprefixer = require('gulp-autoprefixer');
|
||||||
|
const rtlcss = require('gulp-rtlcss');
|
||||||
|
const rename = require('gulp-rename');
|
||||||
|
const sourcemaps = require('gulp-sourcemaps');
|
||||||
|
const browserSync = require('browser-sync');
|
||||||
|
const cleanCSS = require('gulp-clean-css');
|
||||||
|
|
||||||
|
/*-----------------------------------------------
|
||||||
|
| SCSS
|
||||||
|
-----------------------------------------------*/
|
||||||
|
gulp.task('scss', () =>
|
||||||
|
gulp
|
||||||
|
.src('src/assets/scss/*.scss')
|
||||||
|
.pipe(plumber())
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(
|
||||||
|
sass({
|
||||||
|
outputStyle: 'expanded'
|
||||||
|
}).on('error', sass.logError)
|
||||||
|
)
|
||||||
|
.pipe(autoprefixer({ cascade: false }))
|
||||||
|
.pipe(cleanCSS({ compatibility: 'ie9' }))
|
||||||
|
.pipe(sourcemaps.write('.'))
|
||||||
|
.pipe(plumber.stop())
|
||||||
|
.pipe(gulp.dest('public/css'))
|
||||||
|
.pipe(browserSync.stream())
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('scss:dark', () =>
|
||||||
|
gulp
|
||||||
|
.src('src/assets/scss/theme-dark.scss')
|
||||||
|
.pipe(plumber())
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(
|
||||||
|
sass({
|
||||||
|
outputStyle: 'expanded'
|
||||||
|
}).on('error', sass.logError)
|
||||||
|
)
|
||||||
|
.pipe(autoprefixer({ cascade: false }))
|
||||||
|
.pipe(cleanCSS({ compatibility: 'ie9' }))
|
||||||
|
.pipe(sourcemaps.write('.'))
|
||||||
|
.pipe(plumber.stop())
|
||||||
|
.pipe(gulp.dest('public/css'))
|
||||||
|
.pipe(browserSync.stream())
|
||||||
|
);
|
||||||
|
|
||||||
|
gulp.task('scss:rtl', () =>
|
||||||
|
gulp
|
||||||
|
.src('src/assets/scss/*.scss')
|
||||||
|
.pipe(plumber())
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(
|
||||||
|
sass({
|
||||||
|
outputStyle: 'expanded'
|
||||||
|
}).on('error', sass.logError)
|
||||||
|
)
|
||||||
|
.pipe(autoprefixer({ cascade: false }))
|
||||||
|
.pipe(cleanCSS({ compatibility: 'ie9' }))
|
||||||
|
.pipe(rtlcss()) // Convert to RTL.
|
||||||
|
.pipe(rename({ suffix: '-rtl' })) // Append "-rtl" to the filename.
|
||||||
|
.pipe(sourcemaps.write('.'))
|
||||||
|
.pipe(plumber.stop())
|
||||||
|
.pipe(gulp.dest('public/css'))
|
||||||
|
.pipe(browserSync.stream())
|
||||||
|
);
|
||||||
|
|
||||||
|
/*-----------------------------------------------
|
||||||
|
| Watching
|
||||||
|
-----------------------------------------------*/
|
||||||
|
gulp.task('watch', () => {
|
||||||
|
gulp.watch('src/assets/scss/**/*.scss', gulp.parallel('scss', 'scss:rtl'));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('default', gulp.parallel('scss', 'scss:rtl', 'watch', 'scss:dark'));
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
{
|
||||||
|
"name": "falcon-react",
|
||||||
|
"version": "2.10.2",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-free": "^5.15.1",
|
||||||
|
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
||||||
|
"@fortawesome/free-brands-svg-icons": "^5.14.0",
|
||||||
|
"@fortawesome/free-regular-svg-icons": "^5.14.0",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
||||||
|
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||||
|
"@fullcalendar/bootstrap": "^5.3.1",
|
||||||
|
"@fullcalendar/core": "^5.3.1",
|
||||||
|
"@fullcalendar/daygrid": "^5.3.2",
|
||||||
|
"@fullcalendar/interaction": "^5.3.1",
|
||||||
|
"@fullcalendar/list": "^5.3.1",
|
||||||
|
"@fullcalendar/react": "^5.3.1",
|
||||||
|
"@fullcalendar/timegrid": "^5.3.1",
|
||||||
|
"@loadable/component": "^5.13.2",
|
||||||
|
"@reduxjs/toolkit": "^1.6.1",
|
||||||
|
"attr-accept": "^2.2.2",
|
||||||
|
"bootstrap": "^4.5.3",
|
||||||
|
"chance": "^1.1.8",
|
||||||
|
"chart.js": "^2.9.3",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
|
"echarts": "^4.9.0",
|
||||||
|
"echarts-for-react": "^2.0.16",
|
||||||
|
"element-resize-event": "^3.0.3",
|
||||||
|
"emoji-mart": "^3.0.0",
|
||||||
|
"fuse.js": "^6.4.3",
|
||||||
|
"google-maps-react": "^2.0.6",
|
||||||
|
"is_js": "^0.9.0",
|
||||||
|
"leaflet": "^1.7.1",
|
||||||
|
"leaflet.markercluster": "^1.4.1",
|
||||||
|
"leaflet.tilelayer.colorfilter": "^1.2.5",
|
||||||
|
"lodash": "^4.17.20",
|
||||||
|
"moment": "^2.28.0",
|
||||||
|
"plyr": "3.6.2",
|
||||||
|
"prism-react-renderer": "^0.1.7",
|
||||||
|
"prism-themes": "^1.4.0",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"react": "^16.13.1",
|
||||||
|
"react-app-polyfill": "^1.0.6",
|
||||||
|
"react-beautiful-dnd": "^13.0.0",
|
||||||
|
"react-bootstrap-table-next": "^3.3.5",
|
||||||
|
"react-bootstrap-table2-paginator": "^2.1.2",
|
||||||
|
"react-chartjs-2": "^2.10.0",
|
||||||
|
"react-cookie": "^4.0.3",
|
||||||
|
"react-countup": "^4.3.3",
|
||||||
|
"react-datetime": "^2.16.3",
|
||||||
|
"react-dom": "^16.13.1",
|
||||||
|
"react-dropzone": "^10.2.2",
|
||||||
|
"react-es6-progressbar.js": "^1.1.0",
|
||||||
|
"react-flatpickr": "^3.10.6",
|
||||||
|
"react-hook-form": "^7.11.1",
|
||||||
|
"react-image-lightbox": "^5.1.1",
|
||||||
|
"react-image-video-lightbox": "^2.0.1",
|
||||||
|
"react-leaflet": "^2.7.0",
|
||||||
|
"react-live": "^2.2.2",
|
||||||
|
"react-lottie": "^1.2.3",
|
||||||
|
"react-quill": "^1.3.5",
|
||||||
|
"react-rating": "^2.0.5",
|
||||||
|
"react-router-bootstrap": "^0.25.0",
|
||||||
|
"react-router-dom": "^5.2.0",
|
||||||
|
"react-scripts": "^3.4.3",
|
||||||
|
"react-scroll": "^1.8.1",
|
||||||
|
"react-scrollbars-custom": "^4.0.25",
|
||||||
|
"react-select": "^3.1.0",
|
||||||
|
"react-simple-code-editor": "^0.9.15",
|
||||||
|
"react-slick": "^0.25.2",
|
||||||
|
"react-timeago": "^6.2.1",
|
||||||
|
"react-toastify": "^5.5.0",
|
||||||
|
"react-typed": "^1.2.0",
|
||||||
|
"reactstrap": "^8.6.0",
|
||||||
|
"slick-carousel": "^1.8.1",
|
||||||
|
"uuid": "^3.4.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "react-scripts start",
|
||||||
|
"build": "react-scripts build",
|
||||||
|
"eject": "react-scripts eject",
|
||||||
|
"scss": "gulp",
|
||||||
|
"analyze": "npx source-map-explorer 'build/static/js/*.js'",
|
||||||
|
"test": "playwright test"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": "react-app"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.15.2",
|
||||||
|
"browser-sync": "^2.26.12",
|
||||||
|
"eslint-config-prettier": "^4.2.0",
|
||||||
|
"eslint-plugin-prettier": "^3.1.4",
|
||||||
|
"eslint-plugin-react": "^7.20.6",
|
||||||
|
"gulp": "^4.0.2",
|
||||||
|
"gulp-autoprefixer": "^6.1.0",
|
||||||
|
"gulp-clean-css": "^4.3.0",
|
||||||
|
"gulp-plumber": "^1.2.1",
|
||||||
|
"gulp-rename": "^1.4.0",
|
||||||
|
"gulp-rtlcss": "^1.4.1",
|
||||||
|
"gulp-sass": "^4.1.0",
|
||||||
|
"gulp-sourcemaps": "^2.6.5",
|
||||||
|
"prettier": "1.17.1",
|
||||||
|
"swiper": "^6.8.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { PlaywrightTestConfig } from '@playwright/test';
|
||||||
|
|
||||||
|
const config: PlaywrightTestConfig = {
|
||||||
|
globalSetup: require.resolve('./test/config/global-setup'),
|
||||||
|
use: {
|
||||||
|
baseURL: 'http://beta.jamkazam.local:4000',
|
||||||
|
actionTimeout: 5000,
|
||||||
|
headless: true,
|
||||||
|
viewport: { width: 1280, height: 720},
|
||||||
|
ignoreHTTPSErrors: true,
|
||||||
|
video: 'on-first-retry',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
|
|
||||||
|
|
||||||
|
// const { devices } = require('@playwright/test');
|
||||||
|
|
||||||
|
// /** @type {import('@playwright/test').PlaywrightTestConfig} */
|
||||||
|
// const config = {
|
||||||
|
// testDir: './test',
|
||||||
|
// workers: 2,
|
||||||
|
// retries: 2,
|
||||||
|
// use: {
|
||||||
|
// headless: false,
|
||||||
|
// viewport: { width: 1280, height: 720 },
|
||||||
|
// launchOptions: {
|
||||||
|
// slowMo: 1000,
|
||||||
|
// },
|
||||||
|
// video:"on",
|
||||||
|
// },
|
||||||
|
// projects: [
|
||||||
|
// {
|
||||||
|
// name: 'Desktop Chromium',
|
||||||
|
// use: {
|
||||||
|
// browserName: 'chromium',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// { name: 'Desktop Safari',
|
||||||
|
// use: {
|
||||||
|
// browserName: 'webkit',
|
||||||
|
// viewport: { width: 1200, height: 750 },
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// // Test against mobile viewports.
|
||||||
|
// { name: 'Mobile Chrome',
|
||||||
|
// use: devices['Pixel 5'],
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Safari',
|
||||||
|
// use: devices['iPhone 12'],
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// };
|
||||||
|
|
||||||
|
// module.exports = config;
|
||||||
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="theme-color" content="#2c7be5" />
|
||||||
|
|
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Poppins:100,200,300,400,500,600,700,800,900&display=swap"
|
||||||
|
/>
|
||||||
|
<title>JamKazam</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<main class="main" id="main"></main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"short_name": "Falcon React",
|
||||||
|
"name": "Falcon React | ReactJS Dashboard & WebApp Template",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "favicon.ico",
|
||||||
|
"sizes": "64x64 32x32 24x24 16x16",
|
||||||
|
"type": "image/x-icon"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#2c7be5",
|
||||||
|
"background_color": "#edf2f9"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
const compression = require('compression');
|
||||||
|
const express = require('express');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const path = require('path');
|
||||||
|
const app = express();
|
||||||
|
app.use(compression());
|
||||||
|
app.disable('x-powered-by');
|
||||||
|
app.use(express.static(path.join(__dirname, 'build')));
|
||||||
|
// need to declare a "catch all" route on your express server
|
||||||
|
// that captures all page requests and directs them to the client
|
||||||
|
// the react-router do the route part
|
||||||
|
app.get('*', function(req, res) {
|
||||||
|
res.sendFile(path.join(__dirname, 'build', 'index.html'));
|
||||||
|
});
|
||||||
|
app.listen(process.env.PORT || 5000, function() {
|
||||||
|
console.log(`Frontend start on http://localhost:5000`);
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import Layout from './layouts/JKLayout';
|
||||||
|
|
||||||
|
import 'react-toastify/dist/ReactToastify.min.css';
|
||||||
|
import 'react-datetime/css/react-datetime.css';
|
||||||
|
import 'react-image-lightbox/style.css';
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Router basename={process.env.PUBLIC_URL}>
|
||||||
|
<Layout />
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import AppContext from './context/Context';
|
||||||
|
import { AuthProvider } from "./context/AuthContext";
|
||||||
|
import { settings } from './config';
|
||||||
|
import toggleStylesheet from './helpers/toggleStylesheet';
|
||||||
|
import { getItemFromStore, setItemToStore, themeColors } from './helpers/utils';
|
||||||
|
import store from './store/store';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { CookiesProvider } from 'react-cookie';
|
||||||
|
|
||||||
|
const Main = props => {
|
||||||
|
const [isFluid, setIsFluid] = useState(getItemFromStore('isFluid', settings.isFluid));
|
||||||
|
const [isRTL, setIsRTL] = useState(getItemFromStore('isRTL', settings.isRTL));
|
||||||
|
const [isDark, setIsDark] = useState(getItemFromStore('isDark', settings.isDark));
|
||||||
|
const [isTopNav, setIsTopNav] = useState(getItemFromStore('isTopNav', settings.isTopNav));
|
||||||
|
const [isCombo, setIsCombo] = useState(getItemFromStore('isCombo', settings.isCombo));
|
||||||
|
const [isVertical, setIsVertical] = useState(getItemFromStore('isVertical', settings.isVertical));
|
||||||
|
const [isNavbarVerticalCollapsed, setIsNavbarVerticalCollapsed] = useState(
|
||||||
|
getItemFromStore('isNavbarVerticalCollapsed', settings.isNavbarVerticalCollapsed)
|
||||||
|
);
|
||||||
|
const [currency, setCurrency] = useState(settings.currency);
|
||||||
|
const [showBurgerMenu, setShowBurgerMenu] = useState(settings.showBurgerMenu);
|
||||||
|
const [isLoaded, setIsLoaded] = useState(false);
|
||||||
|
const [isOpenSidePanel, setIsOpenSidePanel] = useState(false);
|
||||||
|
const [navbarCollapsed, setNavbarCollapsed] = useState(false);
|
||||||
|
|
||||||
|
const [navbarStyle, setNavbarStyle] = useState(getItemFromStore('navbarStyle', settings.navbarStyle));
|
||||||
|
|
||||||
|
const toggleModal = () => setIsOpenSidePanel(prevIsOpenSidePanel => !prevIsOpenSidePanel);
|
||||||
|
const value = {
|
||||||
|
isRTL,
|
||||||
|
isDark,
|
||||||
|
isCombo,
|
||||||
|
isFluid,
|
||||||
|
setIsRTL,
|
||||||
|
isTopNav,
|
||||||
|
currency,
|
||||||
|
setIsDark,
|
||||||
|
setIsCombo,
|
||||||
|
setIsFluid,
|
||||||
|
isVertical,
|
||||||
|
toggleModal,
|
||||||
|
setIsTopNav,
|
||||||
|
navbarStyle,
|
||||||
|
setCurrency,
|
||||||
|
setIsVertical,
|
||||||
|
showBurgerMenu,
|
||||||
|
setNavbarStyle,
|
||||||
|
isOpenSidePanel,
|
||||||
|
navbarCollapsed,
|
||||||
|
setShowBurgerMenu,
|
||||||
|
setIsOpenSidePanel,
|
||||||
|
setNavbarCollapsed,
|
||||||
|
isNavbarVerticalCollapsed,
|
||||||
|
setIsNavbarVerticalCollapsed
|
||||||
|
};
|
||||||
|
|
||||||
|
const setStylesheetMode = mode => {
|
||||||
|
setIsLoaded(false);
|
||||||
|
setItemToStore(mode, value[mode]);
|
||||||
|
toggleStylesheet({ isRTL, isDark }, () => setIsLoaded(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setStylesheetMode('isFluid');
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isFluid]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setStylesheetMode('isRTL');
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isRTL]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setStylesheetMode('isDark');
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isDark]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setItemToStore('isNavbarVerticalCollapsed', isNavbarVerticalCollapsed);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isNavbarVerticalCollapsed]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setItemToStore('isTopNav', isTopNav);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isTopNav]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setItemToStore('isCombo', isCombo);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isCombo]);
|
||||||
|
useEffect(() => {
|
||||||
|
setItemToStore('isVertical', isVertical);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [isVertical]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setItemToStore('navbarStyle', navbarStyle);
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [navbarStyle]);
|
||||||
|
|
||||||
|
if (!isLoaded) {
|
||||||
|
toggleStylesheet({ isRTL, isDark }, () => setIsLoaded(true));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
backgroundColor: isDark ? themeColors.dark : themeColors.light
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <AppContext.Provider value={value}>
|
||||||
|
<CookiesProvider>
|
||||||
|
<AuthProvider>
|
||||||
|
<Provider store={store}>
|
||||||
|
{props.children}
|
||||||
|
</Provider>
|
||||||
|
</AuthProvider>
|
||||||
|
</CookiesProvider>
|
||||||
|
</AppContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Main.propTypes = { children: PropTypes.node };
|
||||||
|
|
||||||
|
export default Main;
|
||||||
|
After Width: | Height: | Size: 249 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 319 KiB |
|
After Width: | Height: | Size: 333 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 137 KiB |
|
After Width: | Height: | Size: 794 KiB |
|
After Width: | Height: | Size: 245 KiB |
|
After Width: | Height: | Size: 263 KiB |
|
After Width: | Height: | Size: 275 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig>
|
||||||
|
<msapplication>
|
||||||
|
<tile>
|
||||||
|
<square150x150logo src="/mstile-150x150.png"/>
|
||||||
|
<TileColor>#da532c</TileColor>
|
||||||
|
</tile>
|
||||||
|
</msapplication>
|
||||||
|
</browserconfig>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#ffffff",
|
||||||
|
"background_color": "#ffffff",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 7.6 KiB |
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"short_name": "",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#ffffff",
|
||||||
|
"background_color": "#ffffff",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 161 KiB |
|
After Width: | Height: | Size: 278 KiB |
|
After Width: | Height: | Size: 300 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 380 KiB |
|
After Width: | Height: | Size: 243 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 183 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 182 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 210 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 376 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 264 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 923 B |