diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e8088e1c..0eb6d340 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -42,7 +42,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0 + uses: github/codeql-action/init@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -53,7 +53,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0 + uses: github/codeql-action/autobuild@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -67,4 +67,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0 + uses: github/codeql-action/analyze@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1 diff --git a/background.svg b/background.svg deleted file mode 100644 index b6d2a7e4..00000000 --- a/background.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/curtains.png b/curtains.png new file mode 100644 index 00000000..535ac74a Binary files /dev/null and b/curtains.png differ diff --git a/darker-gradient.svg b/darker-gradient.svg new file mode 100644 index 00000000..2027e998 --- /dev/null +++ b/darker-gradient.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html index 6c3b83fb..cbc19ecf 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,6 @@ content="width=device-width, initial-scale=1, shrink-to-fit=no" /> - Brave Ads diff --git a/microwave.png b/microwave.png new file mode 100644 index 00000000..c1e06120 Binary files /dev/null and b/microwave.png differ diff --git a/package-lock.json b/package-lock.json index 6fa3f887..4b88db93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,16 +8,16 @@ "name": "ads-ui", "version": "0.1.0", "dependencies": { - "@apollo/client": "3.8.9", + "@apollo/client": "3.8.10", "@date-io/moment": "2.17.0", "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", "@fontsource/mulish": "5.0.16", "@fontsource/poppins": "5.0.8", - "@mui/icons-material": "5.15.4", - "@mui/lab": "5.0.0-alpha.160", - "@mui/material": "5.15.4", - "@mui/x-data-grid": "6.18.7", + "@mui/icons-material": "5.15.5", + "@mui/lab": "5.0.0-alpha.161", + "@mui/material": "5.15.5", + "@mui/x-data-grid": "6.19.1", "@mui/x-date-pickers": "5.0.20", "axios": "1.6.5", "base64url": "3.0.1", @@ -54,23 +54,23 @@ "@types/jwt-decode": "2.2.1", "@types/lodash": "4.14.202", "@types/papaparse": "5.3.14", - "@types/react": "18.2.47", + "@types/react": "18.2.48", "@types/react-dom": "18.2.18", "@types/react-router-dom": "5.3.3", - "@typescript-eslint/eslint-plugin": "6.18.1", - "@typescript-eslint/parser": "6.18.1", - "@vitejs/plugin-basic-ssl": "1.0.2", + "@typescript-eslint/eslint-plugin": "6.19.0", + "@typescript-eslint/parser": "6.19.0", + "@vitejs/plugin-basic-ssl": "1.1.0", "@vitejs/plugin-react": "4.2.1", "eslint": "8.56.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-react": "7.33.2", "husky": "8.0.3", - "prettier": "3.2.1", + "prettier": "3.2.4", "typescript": "5.3.3", - "vite": "5.0.11", + "vite": "5.0.12", "vite-plugin-checker": "0.6.2", - "vite-tsconfig-paths": "4.2.3", - "vitest": "1.2.0" + "vite-tsconfig-paths": "4.3.1", + "vitest": "1.2.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -96,9 +96,9 @@ } }, "node_modules/@apollo/client": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.8.9.tgz", - "integrity": "sha512-IcQDFEEPc9+PEQsxhxQvsoQ04BRarOzi/Ila5PcniRSDeKJWgY22dnp6+V1i1fWXRDVd1ybdvze4sFESDVQUCQ==", + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.8.10.tgz", + "integrity": "sha512-p/22RZ8ehHyvySnC20EHPPe0gdu8Xp6ZCiXOfdEe1ZORw5cUteD/TLc66tfKv8qu8NLIfbiWoa+6s70XnKvxqg==", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@wry/equality": "^0.5.6", @@ -3365,14 +3365,14 @@ "optional": true }, "node_modules/@mui/base": { - "version": "5.0.0-beta.31", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.31.tgz", - "integrity": "sha512-+uNbP3OHJuZVI00WyMg7xfLZotaEY7LgvYXDfONVJbrS+K9wyjCIPNfjy8r9XJn4fbHo/5ibiZqjWnU9LMNv+A==", + "version": "5.0.0-beta.32", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.32.tgz", + "integrity": "sha512-4VptvYeLUYMJhZapWBkD50GmKfOc0XT381KJcTK3ncZYIl8MdBhpR6l8jOyeP5cixUPBJhstjrnmQEAHjCLriw==", "dependencies": { - "@babel/runtime": "^7.23.7", + "@babel/runtime": "^7.23.8", "@floating-ui/react-dom": "^2.0.5", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.5", "@popperjs/core": "^2.11.8", "clsx": "^2.1.0", "prop-types": "^15.8.1" @@ -3396,20 +3396,20 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.4.tgz", - "integrity": "sha512-0OZN9O6hAtBpx70mMNFOPaAIol/ytwZYPY+z7Rf9dK3+1Xlzwvj5/IeShJKvtp76S1qJyhPuvZg0+BGqQaUnUw==", + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.5.tgz", + "integrity": "sha512-VhT8klyXy8GrWrARqLMoM6Nzz809Jc3Wn5wd7WOZfre2vFO1rBV1dBANAPBhBqpaQI0HCMRTWEYoSyOFgRnz4A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.4.tgz", - "integrity": "sha512-q/Yk7aokN8qGMpR7bwoDpBSeaNe6Bv7vaY9yHYodP37c64TM6ime05ueb/wgksOVszrKkNXC67E/XYbRWOoUFA==", + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.5.tgz", + "integrity": "sha512-qiql0fd1JY7TZ1wm1RldvU7sL8QUatE9OC12i/qm5rnm/caTFyAfOyTIR7qqxorsJvoZGyrzwoMkal6Ij9kM0A==", "dependencies": { - "@babel/runtime": "^7.23.7" + "@babel/runtime": "^7.23.8" }, "engines": { "node": ">=12.0.0" @@ -3430,15 +3430,15 @@ } }, "node_modules/@mui/lab": { - "version": "5.0.0-alpha.160", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.160.tgz", - "integrity": "sha512-hMCOyjfpCHrb/ELs45baCHXICaZf3ygKY0R/phBKxxCxAX6V6Y3O9hxu2fS/Uw3LflZqUuv9TFkwVEWzq3OUkQ==", + "version": "5.0.0-alpha.161", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.161.tgz", + "integrity": "sha512-dLWWZrJAi44av+iiqEHpZHfPhZ4DM42ItS31yqBwboroawumG2GUyYvHVTyEFXM1Zr8+kufiZ9t28rqHXVf5+w==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/base": "5.0.0-beta.31", - "@mui/system": "^5.15.4", + "@babel/runtime": "^7.23.8", + "@mui/base": "5.0.0-beta.32", + "@mui/system": "^5.15.5", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.5", "clsx": "^2.1.0", "prop-types": "^15.8.1" }, @@ -3452,7 +3452,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material": ">=5.10.11", + "@mui/material": ">=5.15.0", "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" @@ -3470,16 +3470,16 @@ } }, "node_modules/@mui/material": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.4.tgz", - "integrity": "sha512-T/LGRAC+M0c+D3+y67eHwIN5bSje0TxbcJCWR0esNvU11T0QwrX3jedXItPNBwMupF2F5VWCDHBVLlFnN3+ABA==", - "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/base": "5.0.0-beta.31", - "@mui/core-downloads-tracker": "^5.15.4", - "@mui/system": "^5.15.4", + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.5.tgz", + "integrity": "sha512-2KfA39f/UWeQl0O22UJs3x1nG3chYlyu9wnux5vTnxUTLzkgYIzQIHaH+ZOGpv5JiZBMKktAPNfhqyhSaQ49qQ==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "@mui/base": "5.0.0-beta.32", + "@mui/core-downloads-tracker": "^5.15.5", + "@mui/system": "^5.15.5", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.5", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.2", @@ -3514,12 +3514,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.4.tgz", - "integrity": "sha512-9N5myIMEEQTM5WYWPGvvYADzjFo12LgJ7S+2iTZkBNOcJpUxQYM1tvYjkHCDV+t1ocMOEgjR2EfJ9Dus30dBlg==", + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.5.tgz", + "integrity": "sha512-HU1KCyGNcJFsUamTbOM539ZDZJNI/XU7sZFdsN29glktUf+T6hNvDuO2ISinBiLTZy7Ab3R6DSSoYXRrLc4uwQ==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/utils": "^5.15.4", + "@babel/runtime": "^7.23.8", + "@mui/utils": "^5.15.5", "prop-types": "^15.8.1" }, "engines": { @@ -3540,11 +3540,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.4.tgz", - "integrity": "sha512-vtrZUXG5XI8CNiNLcxjIirW4dEbOloR+ikfm6ePBo7jXpJdpXjVzBWetrfE+5eI0cHkKWlTptnJ2voKV8pBRfw==", + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.5.tgz", + "integrity": "sha512-xoMUd8h270thNL7ZsOzmlluIAMsQg/HT7SCdRjPBVle+XHgTKaiWiRy1ekDOsrrF0rhjME3T7xeeUq2G269UUw==", "dependencies": { - "@babel/runtime": "^7.23.7", + "@babel/runtime": "^7.23.8", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -3571,15 +3571,15 @@ } }, "node_modules/@mui/system": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.4.tgz", - "integrity": "sha512-KCwkHajGBXPs2TK1HJjIyab4NDk0cZoBDYN/TTlXVo1qBAmCjY0vjqrlsjeoG+wrwwcezXMLs/e6OGP66fPCog==", + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.5.tgz", + "integrity": "sha512-DMv2vGjUKaDt/m0RlzvLjpKiS5V0LoBhiMUHf5pWdj6uoNlN4FuKUe4pFeYmQMIO5DnVZKybmpPepfkdfEH+Og==", "dependencies": { - "@babel/runtime": "^7.23.7", - "@mui/private-theming": "^5.15.4", - "@mui/styled-engine": "^5.15.4", + "@babel/runtime": "^7.23.8", + "@mui/private-theming": "^5.15.5", + "@mui/styled-engine": "^5.15.5", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.4", + "@mui/utils": "^5.15.5", "clsx": "^2.1.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -3623,11 +3623,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.4.tgz", - "integrity": "sha512-E2wLQGBcs3VR52CpMRjk46cGscC4cbf3Q2uyHNaAeL36yTTm+aVNbtsTCazXtjOP4BDd8lu6VtlTpVC8Rtl4mg==", + "version": "5.15.5", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.5.tgz", + "integrity": "sha512-jEywgaMGZWPSlVFO7ZZAyXxNeLmq5XBp5At9Ne/sGohRJdesUcdxvyi8TP3odJxwQuL5L6PJV+JQ4DyIDM849A==", "dependencies": { - "@babel/runtime": "^7.23.7", + "@babel/runtime": "^7.23.8", "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" @@ -3650,9 +3650,9 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "6.18.7", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.18.7.tgz", - "integrity": "sha512-K1A3pMUPxI4/Mt5A4vrK45fBBQK5rZvBVqRMrB5n8zX++Bj+WLWKvLTtfCmlriUtzuadr/Hl7Z+FDRXUJAx6qg==", + "version": "6.19.1", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.19.1.tgz", + "integrity": "sha512-qtmt+XAOdxwb7p3vjk4HcfncAOe+0HzpcC6o6G+rzk9Hqq6MgG3yODrN9mRc/ONg0fD0eVlqDogXxNtJhcFmTQ==", "dependencies": { "@babel/runtime": "^7.23.2", "@mui/utils": "^5.14.16", @@ -4173,9 +4173,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "18.2.47", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.47.tgz", - "integrity": "sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==", + "version": "18.2.48", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.48.tgz", + "integrity": "sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4262,16 +4262,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.1.tgz", - "integrity": "sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.0.tgz", + "integrity": "sha512-DUCUkQNklCQYnrBSSikjVChdc84/vMPDQSgJTHBZ64G9bA9w0Crc0rd2diujKbTdp6w2J47qkeHQLoi0rpLCdg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/type-utils": "6.18.1", - "@typescript-eslint/utils": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/type-utils": "6.19.0", + "@typescript-eslint/utils": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -4297,15 +4297,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.1.tgz", - "integrity": "sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.0.tgz", + "integrity": "sha512-1DyBLG5SH7PYCd00QlroiW60YJ4rWMuUGa/JBV0iZuqi4l4IK3twKPq5ZkEebmGqRjXWVgsUzfd3+nZveewgow==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/typescript-estree": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.0", "debug": "^4.3.4" }, "engines": { @@ -4325,13 +4325,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.1.tgz", - "integrity": "sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.0.tgz", + "integrity": "sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1" + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4342,13 +4342,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.1.tgz", - "integrity": "sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.0.tgz", + "integrity": "sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.18.1", - "@typescript-eslint/utils": "6.18.1", + "@typescript-eslint/typescript-estree": "6.19.0", + "@typescript-eslint/utils": "6.19.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -4369,9 +4369,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.1.tgz", - "integrity": "sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.0.tgz", + "integrity": "sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -4382,13 +4382,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.1.tgz", - "integrity": "sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.0.tgz", + "integrity": "sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/visitor-keys": "6.18.1", + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/visitor-keys": "6.19.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4434,17 +4434,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.1.tgz", - "integrity": "sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.0.tgz", + "integrity": "sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.18.1", - "@typescript-eslint/types": "6.18.1", - "@typescript-eslint/typescript-estree": "6.18.1", + "@typescript-eslint/scope-manager": "6.19.0", + "@typescript-eslint/types": "6.19.0", + "@typescript-eslint/typescript-estree": "6.19.0", "semver": "^7.5.4" }, "engines": { @@ -4459,12 +4459,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.1.tgz", - "integrity": "sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.0.tgz", + "integrity": "sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.18.1", + "@typescript-eslint/types": "6.19.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -4482,9 +4482,9 @@ "dev": true }, "node_modules/@vitejs/plugin-basic-ssl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.2.tgz", - "integrity": "sha512-DKHKVtpI+eA5fvObVgQ3QtTGU70CcCnedalzqmGSR050AzKZMdUzgC8KmlOneHWH8dF2hJ3wkC9+8FDVAaDRCw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", + "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", "dev": true, "engines": { "node": ">=14.6.0" @@ -4513,13 +4513,13 @@ } }, "node_modules/@vitest/expect": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.0.tgz", - "integrity": "sha512-H+2bHzhyvgp32o7Pgj2h9RTHN0pgYaoi26Oo3mE+dCi1PAqV31kIIVfTbqMO3Bvshd5mIrJLc73EwSRrbol9Lw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.1.tgz", + "integrity": "sha512-/bqGXcHfyKgFWYwIgFr1QYDaR9e64pRKxgBNWNXPefPFRhgm+K3+a/dS0cUGEreWngets3dlr8w8SBRw2fCfFQ==", "dev": true, "dependencies": { - "@vitest/spy": "1.2.0", - "@vitest/utils": "1.2.0", + "@vitest/spy": "1.2.1", + "@vitest/utils": "1.2.1", "chai": "^4.3.10" }, "funding": { @@ -4527,12 +4527,12 @@ } }, "node_modules/@vitest/runner": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.0.tgz", - "integrity": "sha512-vaJkDoQaNUTroT70OhM0NPznP7H3WyRwt4LvGwCVYs/llLaqhoSLnlIhUClZpbF5RgAee29KRcNz0FEhYcgxqA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.1.tgz", + "integrity": "sha512-zc2dP5LQpzNzbpaBt7OeYAvmIsRS1KpZQw4G3WM/yqSV1cQKNKwLGmnm79GyZZjMhQGlRcSFMImLjZaUQvNVZQ==", "dev": true, "dependencies": { - "@vitest/utils": "1.2.0", + "@vitest/utils": "1.2.1", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -4568,9 +4568,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.0.tgz", - "integrity": "sha512-P33EE7TrVgB3HDLllrjK/GG6WSnmUtWohbwcQqmm7TAk9AVHpdgf7M3F3qRHKm6vhr7x3eGIln7VH052Smo6Kw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.1.tgz", + "integrity": "sha512-Tmp/IcYEemKaqAYCS08sh0vORLJkMr0NRV76Gl8sHGxXT5151cITJCET20063wk0Yr/1koQ6dnmP6eEqezmd/Q==", "dev": true, "dependencies": { "magic-string": "^0.30.5", @@ -4582,9 +4582,9 @@ } }, "node_modules/@vitest/spy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.0.tgz", - "integrity": "sha512-MNxSAfxUaCeowqyyGwC293yZgk7cECZU9wGb8N1pYQ0yOn/SIr8t0l9XnGRdQZvNV/ZHBYu6GO/W3tj5K3VN1Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.1.tgz", + "integrity": "sha512-vG3a/b7INKH7L49Lbp0IWrG6sw9j4waWAucwnksPB1r1FTJgV7nkBByd9ufzu6VWya/QTvQW4V9FShZbZIB2UQ==", "dev": true, "dependencies": { "tinyspy": "^2.2.0" @@ -4594,9 +4594,9 @@ } }, "node_modules/@vitest/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-FyD5bpugsXlwVpTcGLDf3wSPYy8g541fQt14qtzo8mJ4LdEpDKZ9mQy2+qdJm2TZRpjY5JLXihXCgIxiRJgi5g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-bsH6WVZYe/J2v3+81M5LDU8kW76xWObKIURpPrOXm2pjBniBu2MERI/XP60GpS4PHU3jyK50LUutOwrx4CyHUg==", "dev": true, "dependencies": { "diff-sequences": "^29.6.3", @@ -4706,9 +4706,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" @@ -9244,9 +9244,9 @@ } }, "node_modules/prettier": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.1.tgz", - "integrity": "sha512-qSUWshj1IobVbKc226Gw2pync27t0Kf0EdufZa9j7uBSJay1CC+B3K5lAAZoqgX3ASiKuWsk6OmzKRetXNObWg==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", + "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -10419,18 +10419,18 @@ "dev": true }, "node_modules/tsconfck": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-2.1.2.tgz", - "integrity": "sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.1.tgz", + "integrity": "sha512-7ppiBlF3UEddCLeI1JRx5m2Ryq+xk4JrZuq4EuYXykipebaq1dV0Fhgr1hb7CkmHt32QSgOZlcqVLEtHBG4/mg==", "dev": true, "bin": { "tsconfck": "bin/tsconfck.js" }, "engines": { - "node": "^14.13.1 || ^16 || >=18" + "node": "^18 || >=20" }, "peerDependencies": { - "typescript": "^4.3.5 || ^5.0.0" + "typescript": "^5.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -10736,9 +10736,9 @@ } }, "node_modules/vite": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.11.tgz", - "integrity": "sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz", + "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==", "dev": true, "dependencies": { "esbuild": "^0.19.3", @@ -10791,9 +10791,9 @@ } }, "node_modules/vite-node": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.0.tgz", - "integrity": "sha512-ETnQTHeAbbOxl7/pyBck9oAPZZZo+kYnFt1uQDD+hPReOc+wCjXw4r4jHriBRuVDB5isHmPXxrfc1yJnfBERqg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.1.tgz", + "integrity": "sha512-fNzHmQUSOY+y30naohBvSW7pPn/xn3Ib/uqm+5wAJQJiqQsU0NBR78XdRJb04l4bOFKjpTWld0XAfkKlrDbySg==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -10890,14 +10890,14 @@ } }, "node_modules/vite-tsconfig-paths": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.3.tgz", - "integrity": "sha512-xVsA2xe6QSlzBujtWF8q2NYexh7PAUYfzJ4C8Axpe/7d2pcERYxuxGgph9F4f0iQO36g5tyGq6eBUYIssdUrVw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.1.tgz", + "integrity": "sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==", "dev": true, "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", - "tsconfck": "^2.1.0" + "tsconfck": "^3.0.1" }, "peerDependencies": { "vite": "*" @@ -10909,17 +10909,17 @@ } }, "node_modules/vitest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.0.tgz", - "integrity": "sha512-Ixs5m7BjqvLHXcibkzKRQUvD/XLw0E3rvqaCMlrm/0LMsA0309ZqYvTlPzkhh81VlEyVZXFlwWnkhb6/UMtcaQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.1.tgz", + "integrity": "sha512-TRph8N8rnSDa5M2wKWJCMnztCZS9cDcgVTQ6tsTFTG/odHJ4l5yNVqvbeDJYJRZ6is3uxaEpFs8LL6QM+YFSdA==", "dev": true, "dependencies": { - "@vitest/expect": "1.2.0", - "@vitest/runner": "1.2.0", - "@vitest/snapshot": "1.2.0", - "@vitest/spy": "1.2.0", - "@vitest/utils": "1.2.0", - "acorn-walk": "^8.3.1", + "@vitest/expect": "1.2.1", + "@vitest/runner": "1.2.1", + "@vitest/snapshot": "1.2.1", + "@vitest/spy": "1.2.1", + "@vitest/utils": "1.2.1", + "acorn-walk": "^8.3.2", "cac": "^6.7.14", "chai": "^4.3.10", "debug": "^4.3.4", @@ -10933,7 +10933,7 @@ "tinybench": "^2.5.1", "tinypool": "^0.8.1", "vite": "^5.0.0", - "vite-node": "1.2.0", + "vite-node": "1.2.1", "why-is-node-running": "^2.2.2" }, "bin": { diff --git a/package.json b/package.json index e1290ca6..bbb18bb6 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,16 @@ "version": "0.1.0", "private": true, "dependencies": { - "@apollo/client": "3.8.9", + "@apollo/client": "3.8.10", "@date-io/moment": "2.17.0", "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", "@fontsource/mulish": "5.0.16", "@fontsource/poppins": "5.0.8", - "@mui/icons-material": "5.15.4", - "@mui/lab": "5.0.0-alpha.160", - "@mui/material": "5.15.4", - "@mui/x-data-grid": "6.18.7", + "@mui/icons-material": "5.15.5", + "@mui/lab": "5.0.0-alpha.161", + "@mui/material": "5.15.5", + "@mui/x-data-grid": "6.19.1", "@mui/x-date-pickers": "5.0.20", "axios": "1.6.5", "base64url": "3.0.1", @@ -38,6 +38,7 @@ "scripts": { "start": "vite", "build": "NODE_OPTIONS='--max-old-space-size=4096' vite build", + "preview": "vite preview --port 8080", "test": "vitest", "codegen": "graphql-codegen", "format": "prettier --write .", @@ -63,23 +64,23 @@ "@types/jwt-decode": "2.2.1", "@types/lodash": "4.14.202", "@types/papaparse": "5.3.14", - "@types/react": "18.2.47", + "@types/react": "18.2.48", "@types/react-dom": "18.2.18", "@types/react-router-dom": "5.3.3", - "@typescript-eslint/eslint-plugin": "6.18.1", - "@typescript-eslint/parser": "6.18.1", - "@vitejs/plugin-basic-ssl": "1.0.2", + "@typescript-eslint/eslint-plugin": "6.19.0", + "@typescript-eslint/parser": "6.19.0", + "@vitejs/plugin-basic-ssl": "1.1.0", "@vitejs/plugin-react": "4.2.1", "eslint": "8.56.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-react": "7.33.2", "husky": "8.0.3", - "prettier": "3.2.1", + "prettier": "3.2.4", "typescript": "5.3.3", - "vite": "5.0.11", + "vite": "5.0.12", "vite-plugin-checker": "0.6.2", - "vite-tsconfig-paths": "4.2.3", - "vitest": "1.2.0" + "vite-tsconfig-paths": "4.3.1", + "vitest": "1.2.1" }, "overrides": { "semver": "7.5.4", diff --git a/search-preview.png b/search-preview.png new file mode 100644 index 00000000..b8367907 Binary files /dev/null and b/search-preview.png differ diff --git a/src/App.tsx b/src/App.tsx index 6c56ec9a..43b52441 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,6 +18,7 @@ import { MagicLink } from "auth/views/MagicLink"; import { Register } from "auth/registration/Register"; import { LandingPage } from "auth/views/LandingPage"; import { BraveAdsContactFrame } from "auth/registration/BraveAdsContactFrame"; +import { SearchLandingPage } from "search/SearchLandingPage"; const Protected = () => { return ; @@ -49,6 +50,7 @@ export function App() { + + {buttons.map((b) => ( ))} @@ -107,7 +109,7 @@ function AccountItemButton({ sx={{ backgroundColor: "background.default", height: 300, - width: 400, + width: { md: "300px", lg: "350px" }, borderRadius: "16px", border: meta.value === value diff --git a/src/auth/views/LandingPage.tsx b/src/auth/views/LandingPage.tsx index 67c6a8a1..c39444f3 100644 --- a/src/auth/views/LandingPage.tsx +++ b/src/auth/views/LandingPage.tsx @@ -6,13 +6,7 @@ import { useIsAuthenticated } from "auth/hooks/queries/useIsAuthenticated"; import { Link as RouterLink } from "react-router-dom"; import { useIsMobile } from "hooks/useIsMobile"; import { MobileAdsBenefits } from "auth/views/MobileAdsBenefits"; - -const GradientText = { - backgroundImage: - "linear-gradient(96.46deg, #FF2869 -4.13%, #930BFE 82.88%), linear-gradient(0deg, #111317, #111317);", - backgroundClip: "text", - color: "transparent", -}; +import { GradientText } from "components/Typography/GradientText"; export function LandingPage() { const isAuthenticated = useIsAuthenticated(); @@ -30,10 +24,7 @@ export function LandingPage() { > - - Privacy-forward - {" "} - advertising made simple + advertising made simple @@ -74,7 +65,11 @@ export function LandingPage() { {isMobile && } - {!isMobile && } + {!isMobile && ( + + + + )} ); diff --git a/src/auth/views/Login.tsx b/src/auth/views/Login.tsx index 8450b22b..0778bf09 100644 --- a/src/auth/views/Login.tsx +++ b/src/auth/views/Login.tsx @@ -18,7 +18,10 @@ export function Login() { return ( - + Log into your Brave Ads account - + Enter your email address to get a secure login link. Use this link to access your Brave Ads account. diff --git a/src/auth/views/MobileAdsBenefits.tsx b/src/auth/views/MobileAdsBenefits.tsx index 8c1763fc..49ad377b 100644 --- a/src/auth/views/MobileAdsBenefits.tsx +++ b/src/auth/views/MobileAdsBenefits.tsx @@ -38,7 +38,7 @@ const ItemCard = (props: { image: string; }) => { return ( - + ( , }, { - component: ( - - ), + component: !isSearch ? ( + + + Brave Search + + + ) : undefined, }, { component: , @@ -85,17 +82,6 @@ export function LandingPageAppBar() { {links.map((l) => l.component)} - {isMobile && !match.url.includes("auth") && ( - - Log in - - )}
{!isMobile && !match.url.includes("auth") && ( @@ -107,19 +93,6 @@ export function LandingPageAppBar() { ); } -interface HelpProps { - label: string; - props: LinkProps; -} - -function HelpLink({ label, props }: HelpProps) { - return ( - - {label} - - ); -} - function AuthedButton(props: { isAuthenticated?: boolean }) { const { signOut } = useSignOut(); diff --git a/src/components/Background/Background.tsx b/src/components/Background/Background.tsx index 795bb020..cec4ce2f 100644 --- a/src/components/Background/Background.tsx +++ b/src/components/Background/Background.tsx @@ -1,11 +1,14 @@ import { PropsWithChildren } from "react"; -import gradient from "../../../background.svg"; +import gradient from "../../../darker-gradient.svg"; import { Container } from "@mui/material"; +import { useIsMobile } from "hooks/useIsMobile"; export function Background({ children }: PropsWithChildren) { + const isMobile = useIsMobile(); + return ( uiTextForCreativeTypeCode(row.type), align: "left", width: 200, diff --git a/src/components/Creatives/CreativeType.tsx b/src/components/Creatives/CreativeType.tsx index 461297bd..4870ecdd 100644 --- a/src/components/Creatives/CreativeType.tsx +++ b/src/components/Creatives/CreativeType.tsx @@ -9,11 +9,11 @@ export function CreativeType(props: { allowTypeChange?: boolean }) { const supportedTypes = [ { value: "notification_all_v1", - label: "Push Notification", + label: "Notification ads", }, { value: "inline_content_all_v1", - label: "News Display", + label: "Newsfeed ads", }, ]; diff --git a/src/components/Drawer/MiniSideBar.tsx b/src/components/Drawer/MiniSideBar.tsx index f87a8331..8c6a61f1 100644 --- a/src/components/Drawer/MiniSideBar.tsx +++ b/src/components/Drawer/MiniSideBar.tsx @@ -214,6 +214,14 @@ export function SupportMenu({ usePlainLink }: SupportProps) { > Help Center + { + window.open("https://brave.com/brave-ads", "_blank", "noopener"); + setAnchorEl(null); + }} + > + About Brave Ads + { window.open("mailto:selfserve@brave.com", "_self", "noopener"); diff --git a/src/components/Typography/GradientText.tsx b/src/components/Typography/GradientText.tsx new file mode 100644 index 00000000..c67e30e1 --- /dev/null +++ b/src/components/Typography/GradientText.tsx @@ -0,0 +1,17 @@ +import { Typography } from "@mui/material"; + +export function GradientText(props: { text: string }) { + return ( + + {props.text} + + ); +} diff --git a/src/graphql/ad-set.generated.tsx b/src/graphql/ad-set.generated.tsx index a0963254..a65402c2 100644 --- a/src/graphql/ad-set.generated.tsx +++ b/src/graphql/ad-set.generated.tsx @@ -120,6 +120,65 @@ export type AdFragment = { }; }; +export type AdSetWithDeletedAdsFragment = { + id: string; + createdAt: any; + name: string; + state: string; + billingType?: string | null; + oses: Array<{ code: string; name: string }>; + segments: Array<{ code: string; name: string }>; + conversions: Array<{ id: string }>; + ads: Array<{ + id: string; + state: string; + price: string; + priceType: Types.ConfirmationType; + creative: { + id: string; + createdAt: any; + modifiedAt: any; + name: string; + state: string; + type: { code: string }; + payloadNotification?: { + body: string; + title: string; + targetUrl: string; + } | null; + payloadNewTabPage?: { + logo?: { + imageUrl: string; + alt: string; + companyName: string; + destinationUrl: string; + } | null; + wallpapers?: Array<{ + imageUrl: string; + focalPoint: { x: number; y: number }; + }> | null; + } | null; + payloadInlineContent?: { + title: string; + ctaText: string; + imageUrl: string; + targetUrl: string; + dimensions: string; + description: string; + } | null; + payloadSearch?: { body: string; title: string; targetUrl: string } | null; + payloadSearchHomepage?: { + body: string; + imageUrl: string; + imageDarkModeUrl?: string | null; + targetUrl: string; + title: string; + ctaText: string; + } | null; + }; + }>; +}; + export type CreateAdSetMutationVariables = Types.Exact<{ createAdSetInput: Types.CreateAdSetInput; }>; @@ -316,6 +375,30 @@ export const AdSetFragmentDoc = gql` } ${AdFragmentDoc} `; +export const AdSetWithDeletedAdsFragmentDoc = gql` + fragment AdSetWithDeletedAds on AdSet { + id + createdAt + name + state + billingType + oses { + code + name + } + segments { + code + name + } + conversions { + id + } + ads(includeDeleted: true) { + ...Ad + } + } + ${AdFragmentDoc} +`; export const CreateAdSetDocument = gql` mutation createAdSet($createAdSetInput: CreateAdSetInput!) { createAdSet(createAdSetInput: $createAdSetInput) { diff --git a/src/graphql/ad-set.graphql b/src/graphql/ad-set.graphql index 5da7f0ed..3fd62d09 100644 --- a/src/graphql/ad-set.graphql +++ b/src/graphql/ad-set.graphql @@ -36,6 +36,28 @@ fragment Ad on Ad { } } +fragment AdSetWithDeletedAds on AdSet { + id + createdAt + name + state + billingType + oses { + code + name + } + segments { + code + name + } + conversions { + id + } + ads(includeDeleted: true) { + ...Ad + } +} + mutation createAdSet($createAdSetInput: CreateAdSetInput!) { createAdSet(createAdSetInput: $createAdSetInput) { ...AdSet diff --git a/src/graphql/analytics-overview.generated.tsx b/src/graphql/analytics-overview.generated.tsx index 4e65134a..5719f678 100644 --- a/src/graphql/analytics-overview.generated.tsx +++ b/src/graphql/analytics-overview.generated.tsx @@ -117,7 +117,7 @@ export type EngagementOverviewQuery = { click: number; view: number; landed: number; - spend: number; + spend?: number | null; campaignId: string; }> | null; }; diff --git a/src/graphql/campaign.generated.tsx b/src/graphql/campaign.generated.tsx index 82425b8b..46058fc6 100644 --- a/src/graphql/campaign.generated.tsx +++ b/src/graphql/campaign.generated.tsx @@ -1,7 +1,10 @@ import * as Types from "./types"; import { gql } from "@apollo/client"; -import { AdSetFragmentDoc } from "./ad-set.generated"; +import { + AdSetFragmentDoc, + AdSetWithDeletedAdsFragmentDoc, +} from "./ad-set.generated"; import * as Apollo from "@apollo/client"; const defaultOptions = {} as const; export type CampaignFragment = { @@ -139,21 +142,13 @@ export type CampaignAdsFragment = { advertiser: { id: string }; adSets: Array<{ id: string; - price?: string | null; createdAt: any; - billingType?: string | null; name: string; - totalMax: number; - perDay: number; state: string; - segments: Array<{ code: string; name: string }>; + billingType?: string | null; oses: Array<{ code: string; name: string }>; - conversions: Array<{ - id: string; - type: string; - urlPattern: string; - observationWindow: number; - }>; + segments: Array<{ code: string; name: string }>; + conversions: Array<{ id: string }>; ads: Array<{ id: string; state: string; @@ -331,21 +326,13 @@ export type LoadCampaignAdsQuery = { advertiser: { id: string }; adSets: Array<{ id: string; - price?: string | null; createdAt: any; - billingType?: string | null; name: string; - totalMax: number; - perDay: number; state: string; - segments: Array<{ code: string; name: string }>; + billingType?: string | null; oses: Array<{ code: string; name: string }>; - conversions: Array<{ - id: string; - type: string; - urlPattern: string; - observationWindow: number; - }>; + segments: Array<{ code: string; name: string }>; + conversions: Array<{ id: string }>; ads: Array<{ id: string; state: string; @@ -506,10 +493,10 @@ export const CampaignAdsFragmentDoc = gql` id } adSets { - ...AdSet + ...AdSetWithDeletedAds } } - ${AdSetFragmentDoc} + ${AdSetWithDeletedAdsFragmentDoc} `; export const LoadCampaignDocument = gql` query LoadCampaign($id: String!) { diff --git a/src/graphql/campaign.graphql b/src/graphql/campaign.graphql index 4d7331bf..91be2039 100644 --- a/src/graphql/campaign.graphql +++ b/src/graphql/campaign.graphql @@ -78,7 +78,7 @@ fragment CampaignAds on Campaign { id } adSets { - ...AdSet + ...AdSetWithDeletedAds } } diff --git a/src/graphql/types.ts b/src/graphql/types.ts index eb1b71fe..44a1c70c 100644 --- a/src/graphql/types.ts +++ b/src/graphql/types.ts @@ -144,13 +144,18 @@ export type CreateAdSetInput = { ads?: InputMaybe>; bannedKeywords?: InputMaybe>; billingType: Scalars["String"]["input"]; + brandedDesktopPrice?: InputMaybe; + brandedMobilePrice?: InputMaybe; campaignId?: InputMaybe; conversions?: InputMaybe>; + externalId?: InputMaybe; keywordSimilarity?: InputMaybe; keywords?: InputMaybe>; name?: InputMaybe; negativeKeywords?: InputMaybe>; negativeTriggerUrls?: InputMaybe>; + nonBrandedDesktopPrice?: InputMaybe; + nonBrandedMobilePrice?: InputMaybe; oses?: InputMaybe>; perDay: Scalars["Float"]["input"]; /** The price in the owning campaign's currency for each single confirmation of the priceType specified. Note therefore that the caller is responsible for dividing cost-per-mille by 1000. */ @@ -425,14 +430,19 @@ export type UpdateAdSetInput = { ads?: InputMaybe>; bannedKeywords?: InputMaybe>; billingType?: InputMaybe; + brandedDesktopPrice?: InputMaybe; + brandedMobilePrice?: InputMaybe; campaignId?: InputMaybe; conversions?: InputMaybe>; + externalId?: InputMaybe; id?: InputMaybe; keywordSimilarity?: InputMaybe; keywords?: InputMaybe>; name?: InputMaybe; negativeKeywords?: InputMaybe>; negativeTriggerUrls?: InputMaybe>; + nonBrandedDesktopPrice?: InputMaybe; + nonBrandedMobilePrice?: InputMaybe; optimized?: InputMaybe; oses?: InputMaybe>; perDay?: InputMaybe; diff --git a/src/hooks/useIsMobile.ts b/src/hooks/useIsMobile.ts index dc674c0c..68519796 100644 --- a/src/hooks/useIsMobile.ts +++ b/src/hooks/useIsMobile.ts @@ -2,5 +2,5 @@ import { useMediaQuery, useTheme } from "@mui/material"; export const useIsMobile = () => { const muiTheme = useTheme(); - return useMediaQuery(muiTheme.breakpoints.down("sm")); + return useMediaQuery(muiTheme.breakpoints.down("md")); }; diff --git a/src/search/SearchLandingPage.tsx b/src/search/SearchLandingPage.tsx new file mode 100644 index 00000000..898e5392 --- /dev/null +++ b/src/search/SearchLandingPage.tsx @@ -0,0 +1,154 @@ +import { Box, Button, Link, Stack, Toolbar, Typography } from "@mui/material"; +import { LandingPageAppBar } from "components/AppBar/LandingPageAppBar"; +import { Background } from "components/Background/Background"; +import searchPreview from "../../search-preview.png"; +import tswift from "../../tswift.png"; +import microwave from "../../microwave.png"; +import curtains from "../../curtains.png"; +import { useIsMobile } from "hooks/useIsMobile"; +import { useEffect, useState } from "react"; + +export function SearchLandingPage() { + const isMobile = useIsMobile(); + + return ( + + + + + + + + Tap into over 9 billion annual Web searches + + + Book a 30-minute meeting with a Brave Search specialist to discuss + a free test campaign and see how Brave Ads can perform for your + business. + + + {isMobile && ( + + + + )} + + + + + + + {!isMobile && } + + + + ); +} + +function BookAMeetingButton() { + return ( + + + + Or email{" "} + + searchads@brave.com + + + + ); +} + +function SearchTalkingPoint(props: { title: string; description: string }) { + return ( + + {props.title} + {props.description} + + ); +} + +function SearchImageCarousel() { + const images = [tswift, microwave, curtains]; + + const [currentIndex, setCurrentIndex] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length); + }, 10_000); + + return () => clearInterval(interval); + }, []); + + return ( + + + + + + ); +} diff --git a/src/theme.tsx b/src/theme.tsx index 1be34837..e7b30eaa 100644 --- a/src/theme.tsx +++ b/src/theme.tsx @@ -3,10 +3,6 @@ import { createTheme, responsiveFontSizes, SxProps } from "@mui/material"; const appTheme = createTheme({ typography: { fontFamily: "Poppins", - h1: { - fontSize: "18px", - fontWeight: 400, - }, h2: { fontSize: "14px", fontWeight: 600, diff --git a/src/user/adSet/AdSetList.tsx b/src/user/adSet/AdSetList.tsx index dfc4fd4e..bdb2031e 100644 --- a/src/user/adSet/AdSetList.tsx +++ b/src/user/adSet/AdSetList.tsx @@ -8,7 +8,7 @@ import { import { CampaignAdsFragment } from "graphql/campaign.generated"; import { CampaignSource } from "graphql/types"; import { StatsMetric } from "user/analytics/analyticsOverview/types"; -import { AdSetFragment } from "graphql/ad-set.generated"; +import { AdSetWithDeletedAdsFragment } from "graphql/ad-set.generated"; import { AdDetailTable } from "user/views/user/AdDetailTable"; import { displayFromCampaignState } from "util/displayState"; import { uiLabelsForBillingType } from "util/billingType"; @@ -52,7 +52,7 @@ const ChipList = ({ items, max }: ChipListProps) => { ); }; -export type AdSetDetails = AdSetFragment & CampaignExtras; +export type AdSetDetails = AdSetWithDeletedAdsFragment & CampaignExtras; export type CampaignExtras = { campaignStart: string; diff --git a/src/user/ads/AdList.tsx b/src/user/ads/AdList.tsx index 06485a37..8b33c476 100644 --- a/src/user/ads/AdList.tsx +++ b/src/user/ads/AdList.tsx @@ -8,6 +8,7 @@ import { AdDetailTable } from "user/views/user/AdDetailTable"; import { GridColDef } from "@mui/x-data-grid"; import { CreativeFragment } from "graphql/creative.generated"; import { StandardRenderers } from "components/Datagrid/renderers"; +import { Box } from "@mui/material"; interface Props { campaign?: CampaignAdsFragment | null; @@ -17,6 +18,7 @@ interface Props { export type AdDetails = AdFragment & { adSetName: string; + adState: string; campaignName: string; campaignEnd: string; campaignSource: CampaignSource; @@ -26,22 +28,21 @@ export type AdDetails = AdFragment & { export function AdList({ campaign, loading, engagements }: Props) { const adSets = campaign?.adSets?.map((c) => ({ - ads: (c.ads ?? []) - .filter((ad) => ad.state !== "deleted") - .map((ad) => { - const detail: AdDetails = { - ...ad, - state: isAfterEndDate(campaign?.endAt) ? "completed" : c.state, - adSetName: c.name || c.id.substring(0, 8), - campaignId: campaign?.id, - campaignName: campaign?.name, - campaignEnd: campaign?.endAt, - campaignSource: campaign?.source, - advertiserId: campaign?.advertiser.id, - }; + ads: (c.ads ?? []).map((ad) => { + const detail: AdDetails = { + ...ad, + adState: ad.state, + state: isAfterEndDate(campaign?.endAt) ? "completed" : c.state, + adSetName: c.name || c.id.substring(0, 8), + campaignId: campaign?.id, + campaignName: campaign?.name, + campaignEnd: campaign?.endAt, + campaignSource: campaign?.source, + advertiserId: campaign?.advertiser.id, + }; - return detail; - }), + return detail; + }), })); const ads: AdDetails[] = _.flatMap(adSets, "ads"); @@ -57,6 +58,12 @@ export function AdList({ campaign, loading, engagements }: Props) { field: "name", headerName: "Ad Name", valueGetter: ({ row }) => row.creative.name, + renderCell: ({ row }) => ( + + {row.adState === "deleted" && (DELETED) } + {row.creative.name} + + ), flex: 1, }, { diff --git a/src/user/ads/AdsExistingAd.tsx b/src/user/ads/AdsExistingAd.tsx index c075d80b..815db0f7 100644 --- a/src/user/ads/AdsExistingAd.tsx +++ b/src/user/ads/AdsExistingAd.tsx @@ -79,7 +79,7 @@ export function AdsExistingAd() { return ( setIsShowingAds(false)}> - + Add an existing Ad diff --git a/src/user/analytics/renderers/index.tsx b/src/user/analytics/renderers/index.tsx index f23a8f65..6c4ce40d 100644 --- a/src/user/analytics/renderers/index.tsx +++ b/src/user/analytics/renderers/index.tsx @@ -9,14 +9,14 @@ export type EngagementOverview = { click: number; date: Date; landed: number; - spend: number; + spend?: number | null; view: number; }; export function engagementValue(e: EngagementOverview[]): EngagementOverview { return e.reduce((a, b) => ({ view: a.view + b.view, - spend: a.spend + b.spend, + spend: (a.spend ?? 0) + (b.spend ?? 0), click: a.click + b.click, landed: a.landed + b.landed, campaignId: a.campaignId, diff --git a/src/user/campaignList/CampaignList.tsx b/src/user/campaignList/CampaignList.tsx index 8badba39..75e68f03 100644 --- a/src/user/campaignList/CampaignList.tsx +++ b/src/user/campaignList/CampaignList.tsx @@ -17,7 +17,6 @@ import { renderStatsCell, } from "user/analytics/renderers"; import _ from "lodash"; -import { uiTextForCampaignFormat } from "user/library"; import { CampaignSummaryFragment } from "graphql/campaign.generated"; import { DataGrid, GridColDef } from "@mui/x-data-grid"; import { CustomToolbar } from "components/Datagrid/CustomToolbar"; @@ -25,6 +24,7 @@ import { CloneCampaign } from "components/Campaigns/CloneCampaign"; import { EditButton } from "user/campaignList/EditButton"; import { calculateMetric } from "user/analytics/analyticsOverview/lib/overview.library"; import { StatsMetric } from "user/analytics/analyticsOverview/types"; +import { uiLabelsForCampaignFormat } from "util/campaign"; interface Props { advertiser?: AdvertiserCampaignsFragment | null; @@ -82,8 +82,8 @@ export function CampaignList({ advertiser }: Props) { }, { field: "format", - headerName: "Format", - valueGetter: ({ row }) => uiTextForCampaignFormat(row.format), + headerName: "Ad Format", + valueGetter: ({ row }) => uiLabelsForCampaignFormat(row.format), align: "left", headerAlign: "left", width: 150, diff --git a/src/user/library/index.ts b/src/user/library/index.ts index 35a6b1c6..d8abc889 100644 --- a/src/user/library/index.ts +++ b/src/user/library/index.ts @@ -21,11 +21,11 @@ import { CreativeFragment } from "graphql/creative.generated"; import moment from "moment"; const TYPE_CODE_LOOKUP: Record = { - notification_all_v1: "Push Notification", - new_tab_page_all_v1: "New Tab Takeover", - inline_content_all_v1: "News Display Ad", - search_all_v1: "Search SERP", - search_homepage_all_v1: "Search Homepage", + notification_all_v1: "Notification", + new_tab_page_all_v1: "New tab takeover", + inline_content_all_v1: "Newsfeed", + search_all_v1: "Search keyword", + search_homepage_all_v1: "Search homepage", }; export function transformNewForm( @@ -261,18 +261,6 @@ export function uiTextForCreativeType(creativeType: string): string { return TYPE_CODE_LOOKUP[creativeType] ?? creativeType; } -export const CAMPAIGN_FORMATS = [ - { value: CampaignFormat.PushNotification, label: "Push Notification" }, - { value: CampaignFormat.NtpSi, label: "New Tab Takeover" }, - { value: CampaignFormat.NewsDisplayAd, label: "News Display" }, - { value: CampaignFormat.Search, label: "Search SERP" }, - { value: CampaignFormat.SearchHomepage, label: "Search Homepage" }, -]; - -export function uiTextForCampaignFormat(format: CampaignFormat): string { - return CAMPAIGN_FORMATS.find((f) => f.value === format)?.label ?? format; -} - export function uiTextForCreativeTypeCode(creativeTypeCode: { code: string; }): string { diff --git a/src/user/views/adsManager/views/advanced/components/campaign/fields/FormatField.tsx b/src/user/views/adsManager/views/advanced/components/campaign/fields/FormatField.tsx index 5f390101..9c6e982d 100644 --- a/src/user/views/adsManager/views/advanced/components/campaign/fields/FormatField.tsx +++ b/src/user/views/adsManager/views/advanced/components/campaign/fields/FormatField.tsx @@ -2,7 +2,6 @@ import { List, ListItemButton, Stack, Typography } from "@mui/material"; import { CardContainer } from "components/Card/CardContainer"; import { useField } from "formik"; import { CampaignFormat } from "graphql/types"; -import _ from "lodash"; import { useIsEdit } from "form/FormikHelpers"; import { Billing } from "user/views/adsManager/types"; import { FormatHelp } from "components/Button/FormatHelp"; @@ -25,17 +24,21 @@ export function FormatField({ prices }: PriceProps) { ); } -const FormatItemButton = (props: { format: CampaignFormat } & PriceProps) => { +const FormatItemButton = ( + props: { format: CampaignFormat; name: string } & PriceProps, +) => { const { isEdit } = useIsEdit(); const [, meta, format] = useField("format"); const [, , price] = useField("price"); @@ -57,7 +60,7 @@ const FormatItemButton = (props: { format: CampaignFormat } & PriceProps) => { border: "1px solid #7c91ff", }} > - {_.startCase(_.lowerCase(props.format))} + {props.name} ); }; diff --git a/src/user/views/user/AdDetailTable.tsx b/src/user/views/user/AdDetailTable.tsx index cd70f70d..c64e6c1c 100644 --- a/src/user/views/user/AdDetailTable.tsx +++ b/src/user/views/user/AdDetailTable.tsx @@ -98,7 +98,7 @@ export function AdDetailTable({ sx={{ borderStyle: "none" }} initialState={{ sorting: { - sortModel: [{ field: "startAt", sort: "desc" }], + sortModel: [{ field: "createdAt", sort: "desc" }], }, pagination: { paginationModel: { diff --git a/src/util/campaign.ts b/src/util/campaign.ts index 033d9f1d..079e0639 100644 --- a/src/util/campaign.ts +++ b/src/util/campaign.ts @@ -1,11 +1,11 @@ import { CampaignFormat } from "graphql/types"; export const CAMPAIGN_FORMATS = [ - { value: CampaignFormat.PushNotification, label: "Push Notification" }, - { value: CampaignFormat.NtpSi, label: "New Tab Takeover" }, - { value: CampaignFormat.NewsDisplayAd, label: "News Display" }, - { value: CampaignFormat.Search, label: "Search" }, - { value: CampaignFormat.SearchHomepage, label: "Search Homepage" }, + { value: CampaignFormat.PushNotification, label: "Notification" }, + { value: CampaignFormat.NtpSi, label: "New tab takeover" }, + { value: CampaignFormat.NewsDisplayAd, label: "Newsfeed" }, + { value: CampaignFormat.Search, label: "Search keyword" }, + { value: CampaignFormat.SearchHomepage, label: "Search homepage" }, ]; export function uiLabelsForCampaignFormat(format: CampaignFormat): string { diff --git a/src/validation/CampaignSchema.test.ts b/src/validation/CampaignSchema.test.ts index df8346bd..fd43c980 100644 --- a/src/validation/CampaignSchema.test.ts +++ b/src/validation/CampaignSchema.test.ts @@ -123,7 +123,7 @@ describe("pricing tests", () => { expect(() => CampaignSchema(prices).validateSync(nextState), ).toThrowErrorMatchingInlineSnapshot( - `[ValidationError: No cpc pricing available for News Display, contact selfserve@brave.com for help]`, + `[ValidationError: No cpc pricing available for Newsfeed, contact selfserve@brave.com for help]`, ); }); }); diff --git a/tsconfig.json b/tsconfig.json index c3cd729f..69e411f5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,7 @@ "lib": ["ESNext", "dom"], "isolatedModules": true, "types": ["vitest/globals"], - "baseUrl": "src" + "baseUrl": "src", }, - "include": ["src"] + "include": ["src"], } diff --git a/tswift.png b/tswift.png new file mode 100644 index 00000000..37ce141d Binary files /dev/null and b/tswift.png differ diff --git a/vite.config.mts b/vite.config.mts index 1412b37e..a3eac5c1 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -41,6 +41,8 @@ export default defineConfig(({ mode }) => { assetsDir: "static", chunkSizeWarningLimit: 3000, sourcemap: true, + // vite automagically decides whether to inline assets depending on their size. We are explicitly disabling this. + assetsInlineLimit: 0, }, test: { // see https://vitest.dev/config/#globals