🎨(front) global layout (#5)
* 🎨(front) global layout modify left panel, header and chat * 🎨(front) color dsfr v2 change color + left panel logic
@@ -8,6 +8,8 @@ and this project adheres to
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- ✨(front) global layout UI
|
||||
|
||||
### Changed
|
||||
|
||||
- ♻️(chat) rewrite backend using Pydantic AI SDK #4
|
||||
|
||||
|
Before Width: | Height: | Size: 4.3 KiB |
@@ -62,9 +62,9 @@ tokens.themes.default.components = {
|
||||
beta: false,
|
||||
'image-system-filter': '',
|
||||
favicon: {
|
||||
ico: '/assets/favicon-light.ico',
|
||||
'png-light': '/assets/favicon-light.png',
|
||||
'png-dark': '/assets/favicon-dark.png',
|
||||
ico: '/assets/favicon.ico',
|
||||
'png-light': '/assets/icon-assistant.svg',
|
||||
'png-dark': '/assets/icon-assistant.svg',
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -88,9 +88,9 @@ const dsfrTheme = {
|
||||
alpha: true,
|
||||
beta: true,
|
||||
favicon: {
|
||||
ico: '/assets/favicon-dsfr.ico',
|
||||
'png-light': '/assets/favicon-dsfr.png',
|
||||
'png-dark': '/assets/favicon-dark-dsfr.png',
|
||||
ico: '/assets/favicon.ico',
|
||||
'png-light': '/assets/icon-assistant.svg',
|
||||
'png-dark': '/assets/icon-assistant.svg',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -137,6 +137,7 @@ const genericTheme = {
|
||||
'greyscale-350': '#eee',
|
||||
'greyscale-400': '#96948E',
|
||||
'greyscale-500': '#817E77',
|
||||
'greyscale-550': '#626A80',
|
||||
'greyscale-600': '#6A6862',
|
||||
'greyscale-700': '#3C3B38',
|
||||
'greyscale-750': '#383632',
|
||||
|
||||
@@ -41,9 +41,10 @@
|
||||
"posthog-js": "1.249.3",
|
||||
"react": "*",
|
||||
"react-aria-components": "1.9.0",
|
||||
"react-dom": "*",
|
||||
"react-dom": "18.3.1",
|
||||
"react-i18next": "15.5.2",
|
||||
"react-intersection-observer": "9.16.0",
|
||||
"react-lottie": "^1.2.10",
|
||||
"react-markdown": "10.1.0",
|
||||
"react-select": "5.10.1",
|
||||
"rehype-katex": "7.0.1",
|
||||
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 992 B After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M43.9612 12.1078C43.9612 10.7446 43.9612 10.063 43.8197 9.44065C43.5582 8.29032 42.9454 7.24979 42.0663 6.46318C41.5907 6.03759 40.9946 5.707 39.8025 5.04582L36.7561 3.35621C35.6298 2.73158 35.0667 2.41926 34.4857 2.24352C33.4121 1.91883 32.2665 1.91883 31.1929 2.24352C30.6119 2.41926 30.0488 2.73158 28.9226 3.35621L27.6662 4.05301C26.1413 4.89875 25.3789 5.32161 25.0296 5.81385C24.3763 6.73448 24.3769 7.96763 25.0311 8.88764C25.3808 9.37954 26.1437 9.80168 27.6694 10.646L28.6864 11.2088C29.8804 11.8695 30.4774 12.1998 30.9538 12.6255C31.8343 13.4121 32.4482 14.4534 32.7101 15.6047C32.8519 16.2276 32.8519 16.9099 32.8519 18.2745V19.4391C32.8519 21.0927 32.8519 21.9195 33.1003 22.4525C33.5646 23.4487 34.595 24.0556 35.6913 23.9787C36.278 23.9376 37.0012 23.5368 38.4474 22.7351L39.8008 21.9849C40.9934 21.3238 41.5897 20.9933 42.0655 20.5677C42.945 19.7811 43.558 18.7404 43.8196 17.5898C43.9612 16.9673 43.9612 16.2855 43.9612 14.922V12.1078Z" fill="#3E5DE7"/>
|
||||
<path d="M10.0512 32.3143C8.87068 32.9959 8.2804 33.3367 7.81215 33.7704C6.94669 34.572 6.35194 35.623 6.11028 36.7776C5.97953 37.4023 5.99126 38.0838 6.01473 39.4468L6.07469 42.9299C6.09685 44.2175 6.10794 44.8614 6.24627 45.4524C6.50185 46.5445 7.07465 47.5366 7.89263 48.304C8.33535 48.7194 8.88738 49.0509 9.99144 49.7139L11.2231 50.4535C12.7179 51.3513 13.4654 51.8001 14.0663 51.8565C15.1902 51.962 16.2579 51.3449 16.7275 50.3183C16.9787 49.7695 16.9628 48.8978 16.9311 47.1543L16.91 45.9921C16.8852 44.6277 16.8728 43.9456 17.0032 43.3202C17.2442 42.1643 17.839 41.1121 18.7051 40.3095C19.1737 39.8753 19.7646 39.5342 20.9464 38.8519L21.9549 38.2696C23.387 37.4428 24.103 37.0294 24.4404 36.5477C25.071 35.6475 25.0814 34.4518 24.4667 33.5407C24.1377 33.0532 23.429 32.6273 22.0116 31.7757L20.6853 30.9787C19.5165 30.2765 18.9321 29.9253 18.3256 29.726C17.2046 29.3577 15.9968 29.3471 14.8696 29.6959C14.2597 29.8845 13.6693 30.2254 12.4884 30.9072L10.0512 32.3143Z" fill="#3E5DE7"/>
|
||||
<path d="M21.7175 51.8922C21.7175 53.2554 21.7175 53.937 21.8589 54.5594C22.1204 55.7097 22.7332 56.7502 23.6123 57.5368C24.088 57.9624 24.684 58.293 25.8762 58.9542L28.9226 60.6438C30.0488 61.2684 30.6119 61.5807 31.1929 61.7565C32.2665 62.0812 33.4121 62.0812 34.4857 61.7565C35.0667 61.5807 35.6298 61.2684 36.7561 60.6438L38.0124 59.947C39.5373 59.1012 40.2997 58.6784 40.649 58.1862C41.3023 57.2655 41.3017 56.0324 40.6476 55.1124C40.2978 54.6205 39.5349 54.1983 38.0093 53.354L36.9922 52.7912C35.7982 52.1305 35.2012 51.8002 34.7248 51.3745C33.8443 50.5879 33.2305 49.5466 32.9685 48.3953C32.8268 47.7724 32.8268 47.0901 32.8268 45.7255V44.5609C32.8268 42.9073 32.8268 42.0805 32.5783 41.5475C32.114 40.5513 31.0837 39.9444 29.9873 40.0213C29.4006 40.0624 28.6775 40.4632 27.2312 41.2649L25.8778 42.0151C24.6852 42.6761 24.089 43.0067 23.6131 43.4323C22.7336 44.2189 22.1206 45.2596 21.859 46.4102C21.7175 47.0327 21.7175 47.7145 21.7175 49.078V51.8922Z" fill="#3E5DE7"/>
|
||||
<path d="M44.5055 51.5779C45.6861 52.2595 46.2764 52.6003 46.8861 52.789C48.0131 53.1377 49.2206 53.1273 50.3414 52.7592C50.9477 52.5601 51.5321 52.2092 52.7007 51.5074L55.6872 49.7139C56.7912 49.0509 57.3433 48.7194 57.786 48.304C58.604 47.5366 59.1768 46.5445 59.4324 45.4524C59.5707 44.8614 59.5818 44.2175 59.6039 42.9299L59.6287 41.4935C59.6587 39.75 59.6737 38.8783 59.422 38.3297C58.9514 37.3036 57.8832 36.6875 56.7593 36.794C56.1584 36.851 55.4114 37.3006 53.9174 38.1997L52.9215 38.7991C51.7523 39.5028 51.1677 39.8546 50.5609 40.0544C49.4394 40.4236 48.2307 40.4346 47.1027 40.0858C46.4924 39.8971 45.9015 39.5559 44.7197 38.8736L43.7111 38.2913C42.2791 37.4645 41.563 37.0511 40.9772 36.9998C39.8823 36.9038 38.8415 37.4926 38.3599 38.4806C38.1022 39.0092 38.0878 39.8359 38.0589 41.4892L38.0319 43.0364C38.0081 44.3997 37.9962 45.0814 38.1269 45.7062C38.3684 46.8612 38.9631 47.9125 39.8287 48.7143C40.2971 49.1481 40.8875 49.489 42.0684 50.1708L44.5055 51.5779Z" fill="#3E5DE7"/>
|
||||
<path d="M55.6274 31.6857C56.8079 31.0041 57.3982 30.6633 57.8665 30.2296C58.7319 29.428 59.3267 28.377 59.5683 27.2224C59.6991 26.5977 59.6874 25.9162 59.6639 24.5532L59.6039 21.0701C59.5818 19.7825 59.5707 19.1386 59.4324 18.5476C59.1768 17.4555 58.604 16.4634 57.786 15.696C57.3433 15.2806 56.7912 14.9491 55.6872 14.2861L54.4556 13.5465C52.9607 12.6488 52.2133 12.1999 51.6123 12.1435C50.4884 12.038 49.4207 12.6551 48.9511 13.6817C48.7 14.2305 48.7158 15.1022 48.7475 16.8457L48.7686 18.0079C48.7934 19.3723 48.8058 20.0544 48.6754 20.6798C48.4344 21.8357 47.8396 22.8879 46.9735 23.6905C46.5049 24.1247 45.914 24.4658 44.7322 25.1481L43.7237 25.7304C42.2916 26.5572 41.5756 26.9706 41.2382 27.4523C40.6076 28.3525 40.5972 29.5482 41.2119 30.4593C41.5409 30.9468 42.2496 31.3727 43.667 32.2243L44.9934 33.0213C46.1622 33.7235 46.7466 34.0747 47.353 34.274C48.474 34.6423 49.6818 34.6529 50.809 34.3041C51.4189 34.1155 52.0094 33.7746 53.1902 33.0928L55.6274 31.6857Z" fill="#3E5DE7"/>
|
||||
<path d="M21.173 12.4222C19.9925 11.7406 19.4022 11.3998 18.7924 11.2112C17.6655 10.8625 16.458 10.8728 15.3372 11.2409C14.7308 11.44 14.1465 11.7909 12.9778 12.4927L9.99135 14.2862C8.8873 14.9492 8.33527 15.2807 7.89255 15.6961C7.07457 16.4635 6.50177 17.4556 6.24619 18.5477C6.10786 19.1387 6.09677 19.7826 6.07461 21.0702L6.04988 22.5066C6.01987 24.2501 6.00486 25.1218 6.2565 25.6704C6.72713 26.6965 7.79538 27.3126 8.91921 27.2061C9.5201 27.1491 10.2671 26.6995 11.7611 25.8004L12.757 25.201C13.9262 24.4973 14.5108 24.1455 15.1176 23.9457C16.2392 23.5765 17.4478 23.5655 18.5759 23.9143C19.1862 24.103 19.7771 24.4442 20.9589 25.1265L21.9674 25.7088C23.3995 26.5356 24.1155 26.949 24.7014 27.0003C25.7962 27.0963 26.837 26.5075 27.3186 25.5195C27.5764 24.9909 27.5908 24.1642 27.6196 22.5109L27.6466 20.9638C27.6704 19.6004 27.6823 18.9187 27.5517 18.2939C27.3102 17.1389 26.7154 16.0876 25.8498 15.2858C25.3815 14.852 24.791 14.5111 23.6102 13.8293L21.173 12.4222Z" fill="#D3343F"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,31 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_12196_859)">
|
||||
<path d="M8.69629 4.34961H23.3037C24.3064 4.34961 25.038 4.35047 25.6143 4.39746C26.186 4.44412 26.5745 4.53473 26.8975 4.69922C27.5013 5.00695 27.9931 5.49869 28.3008 6.10254C28.4653 6.42553 28.5559 6.81398 28.6025 7.38574C28.6495 7.96203 28.6504 8.69359 28.6504 9.69629V18.3037C28.6504 19.3064 28.6495 20.038 28.6025 20.6143C28.5559 21.186 28.4653 21.5745 28.3008 21.8975C27.9931 22.5013 27.5013 22.9931 26.8975 23.3008C26.3863 23.5611 25.7286 23.6285 24.4746 23.6426C24.3959 23.6435 24.3163 23.6443 24.249 23.6504C24.1779 23.6569 24.0891 23.6715 24 23.7178C23.9091 23.765 23.8316 23.8328 23.7725 23.915L23.7197 24.002C23.6747 24.0912 23.661 24.1789 23.6553 24.25C23.6498 24.3172 23.6504 24.3966 23.6504 24.4746V24.8008C23.6504 25.4092 23.6497 25.8413 23.6201 26.1641C23.5902 26.4901 23.5338 26.643 23.4688 26.7295C23.3111 26.9386 23.0699 27.0688 22.8086 27.0859C22.7006 27.0929 22.5426 27.0566 22.2539 26.9033C21.9676 26.7513 21.6059 26.514 21.0967 26.1807L17.7158 23.9688C17.5773 23.8781 17.4739 23.809 17.3594 23.7598C17.2635 23.7186 17.1633 23.688 17.0605 23.6699C16.9378 23.6484 16.813 23.6504 16.6475 23.6504H8.69629C7.69359 23.6504 6.96203 23.6495 6.38574 23.6025C5.81398 23.5559 5.42553 23.4653 5.10254 23.3008C4.49869 22.9931 4.00695 22.5013 3.69922 21.8975C3.53473 21.5745 3.44412 21.186 3.39746 20.6143C3.35047 20.038 3.34961 19.3064 3.34961 18.3037V9.69629C3.34961 8.69359 3.35047 7.96203 3.39746 7.38574C3.44412 6.81398 3.53473 6.42553 3.69922 6.10254C4.00695 5.49869 4.49869 5.00695 5.10254 4.69922C5.42553 4.53473 5.81398 4.44412 6.38574 4.39746C6.96203 4.35047 7.69359 4.34961 8.69629 4.34961Z" fill="#D9D9D9"/>
|
||||
<path d="M8.69629 4.34961H23.3037C24.3064 4.34961 25.038 4.35047 25.6143 4.39746C26.186 4.44412 26.5745 4.53473 26.8975 4.69922C27.5013 5.00695 27.9931 5.49869 28.3008 6.10254C28.4653 6.42553 28.5559 6.81398 28.6025 7.38574C28.6495 7.96203 28.6504 8.69359 28.6504 9.69629V18.3037C28.6504 19.3064 28.6495 20.038 28.6025 20.6143C28.5559 21.186 28.4653 21.5745 28.3008 21.8975C27.9931 22.5013 27.5013 22.9931 26.8975 23.3008C26.3863 23.5611 25.7286 23.6285 24.4746 23.6426C24.3959 23.6435 24.3163 23.6443 24.249 23.6504C24.1779 23.6569 24.0891 23.6715 24 23.7178C23.9091 23.765 23.8316 23.8328 23.7725 23.915L23.7197 24.002C23.6747 24.0912 23.661 24.1789 23.6553 24.25C23.6498 24.3172 23.6504 24.3966 23.6504 24.4746V24.8008C23.6504 25.4092 23.6497 25.8413 23.6201 26.1641C23.5902 26.4901 23.5338 26.643 23.4688 26.7295C23.3111 26.9386 23.0699 27.0688 22.8086 27.0859C22.7006 27.0929 22.5426 27.0566 22.2539 26.9033C21.9676 26.7513 21.6059 26.514 21.0967 26.1807L17.7158 23.9688C17.5773 23.8781 17.4739 23.809 17.3594 23.7598C17.2635 23.7186 17.1633 23.688 17.0605 23.6699C16.9378 23.6484 16.813 23.6504 16.6475 23.6504H8.69629C7.69359 23.6504 6.96203 23.6495 6.38574 23.6025C5.81398 23.5559 5.42553 23.4653 5.10254 23.3008C4.49869 22.9931 4.00695 22.5013 3.69922 21.8975C3.53473 21.5745 3.44412 21.186 3.39746 20.6143C3.35047 20.038 3.34961 19.3064 3.34961 18.3037V9.69629C3.34961 8.69359 3.35047 7.96203 3.39746 7.38574C3.44412 6.81398 3.53473 6.42553 3.69922 6.10254C4.00695 5.49869 4.49869 5.00695 5.10254 4.69922C5.42553 4.53473 5.81398 4.44412 6.38574 4.39746C6.96203 4.35047 7.69359 4.34961 8.69629 4.34961Z" fill="white"/>
|
||||
<path d="M8.69629 4.34961H23.3037C24.3064 4.34961 25.038 4.35047 25.6143 4.39746C26.186 4.44412 26.5745 4.53473 26.8975 4.69922C27.5013 5.00695 27.9931 5.49869 28.3008 6.10254C28.4653 6.42553 28.5559 6.81398 28.6025 7.38574C28.6495 7.96203 28.6504 8.69359 28.6504 9.69629V18.3037C28.6504 19.3064 28.6495 20.038 28.6025 20.6143C28.5559 21.186 28.4653 21.5745 28.3008 21.8975C27.9931 22.5013 27.5013 22.9931 26.8975 23.3008C26.3863 23.5611 25.7286 23.6285 24.4746 23.6426C24.3959 23.6435 24.3163 23.6443 24.249 23.6504C24.1779 23.6569 24.0891 23.6715 24 23.7178C23.9091 23.765 23.8316 23.8328 23.7725 23.915L23.7197 24.002C23.6747 24.0912 23.661 24.1789 23.6553 24.25C23.6498 24.3172 23.6504 24.3966 23.6504 24.4746V24.8008C23.6504 25.4092 23.6497 25.8413 23.6201 26.1641C23.5902 26.4901 23.5338 26.643 23.4688 26.7295C23.3111 26.9386 23.0699 27.0688 22.8086 27.0859C22.7006 27.0929 22.5426 27.0566 22.2539 26.9033C21.9676 26.7513 21.6059 26.514 21.0967 26.1807L17.7158 23.9688C17.5773 23.8781 17.4739 23.809 17.3594 23.7598C17.2635 23.7186 17.1633 23.688 17.0605 23.6699C16.9378 23.6484 16.813 23.6504 16.6475 23.6504H8.69629C7.69359 23.6504 6.96203 23.6495 6.38574 23.6025C5.81398 23.5559 5.42553 23.4653 5.10254 23.3008C4.49869 22.9931 4.00695 22.5013 3.69922 21.8975C3.53473 21.5745 3.44412 21.186 3.39746 20.6143C3.35047 20.038 3.34961 19.3064 3.34961 18.3037V9.69629C3.34961 8.69359 3.35047 7.96203 3.39746 7.38574C3.44412 6.81398 3.53473 6.42553 3.69922 6.10254C4.00695 5.49869 4.49869 5.00695 5.10254 4.69922C5.42553 4.53473 5.81398 4.44412 6.38574 4.39746C6.96203 4.35047 7.69359 4.34961 8.69629 4.34961Z" stroke="#CACAFB" stroke-width="0.7"/>
|
||||
<path d="M8.69629 4.34961H23.3037C24.3064 4.34961 25.038 4.35047 25.6143 4.39746C26.186 4.44412 26.5745 4.53473 26.8975 4.69922C27.5013 5.00695 27.9931 5.49869 28.3008 6.10254C28.4653 6.42553 28.5559 6.81398 28.6025 7.38574C28.6495 7.96203 28.6504 8.69359 28.6504 9.69629V18.3037C28.6504 19.3064 28.6495 20.038 28.6025 20.6143C28.5559 21.186 28.4653 21.5745 28.3008 21.8975C27.9931 22.5013 27.5013 22.9931 26.8975 23.3008C26.3863 23.5611 25.7286 23.6285 24.4746 23.6426C24.3959 23.6435 24.3163 23.6443 24.249 23.6504C24.1779 23.6569 24.0891 23.6715 24 23.7178C23.9091 23.765 23.8316 23.8328 23.7725 23.915L23.7197 24.002C23.6747 24.0912 23.661 24.1789 23.6553 24.25C23.6498 24.3172 23.6504 24.3966 23.6504 24.4746V24.8008C23.6504 25.4092 23.6497 25.8413 23.6201 26.1641C23.5902 26.4901 23.5338 26.643 23.4688 26.7295C23.3111 26.9386 23.0699 27.0688 22.8086 27.0859C22.7006 27.0929 22.5426 27.0566 22.2539 26.9033C21.9676 26.7513 21.6059 26.514 21.0967 26.1807L17.7158 23.9688C17.5773 23.8781 17.4739 23.809 17.3594 23.7598C17.2635 23.7186 17.1633 23.688 17.0605 23.6699C16.9378 23.6484 16.813 23.6504 16.6475 23.6504H8.69629C7.69359 23.6504 6.96203 23.6495 6.38574 23.6025C5.81398 23.5559 5.42553 23.4653 5.10254 23.3008C4.49869 22.9931 4.00695 22.5013 3.69922 21.8975C3.53473 21.5745 3.44412 21.186 3.39746 20.6143C3.35047 20.038 3.34961 19.3064 3.34961 18.3037V9.69629C3.34961 8.69359 3.35047 7.96203 3.39746 7.38574C3.44412 6.81398 3.53473 6.42553 3.69922 6.10254C4.00695 5.49869 4.49869 5.00695 5.10254 4.69922C5.42553 4.53473 5.81398 4.44412 6.38574 4.39746C6.96203 4.35047 7.69359 4.34961 8.69629 4.34961Z" stroke="url(#paint0_linear_12196_859)" stroke-opacity="0.35" stroke-width="0.7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 13.0689C7 12.578 7.39797 12.1801 7.88889 12.1801H23.9436C24.4345 12.1801 24.8325 12.578 24.8325 13.0689C24.8325 13.5599 24.4345 13.9578 23.9436 13.9578H7.88889C7.39797 13.9578 7 13.5599 7 13.0689ZM7 15.7356C7 15.2447 7.39797 14.8467 7.88889 14.8467H23.9436C24.4345 14.8467 24.8325 15.2447 24.8325 15.7356C24.8325 16.2265 24.4345 16.6245 23.9436 16.6245H7.88889C7.39797 16.6245 7 16.2265 7 15.7356ZM7 18.4023C7 17.9114 7.39797 17.5134 7.88889 17.5134H14.9436C15.4345 17.5134 15.8325 17.9114 15.8325 18.4023C15.8325 18.8932 15.4345 19.2912 14.9436 19.2912H7.88889C7.39797 19.2912 7 18.8932 7 18.4023Z" fill="#CACAFB"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 13.0689C7 12.578 7.39797 12.1801 7.88889 12.1801H23.9436C24.4345 12.1801 24.8325 12.578 24.8325 13.0689C24.8325 13.5599 24.4345 13.9578 23.9436 13.9578H7.88889C7.39797 13.9578 7 13.5599 7 13.0689ZM7 15.7356C7 15.2447 7.39797 14.8467 7.88889 14.8467H23.9436C24.4345 14.8467 24.8325 15.2447 24.8325 15.7356C24.8325 16.2265 24.4345 16.6245 23.9436 16.6245H7.88889C7.39797 16.6245 7 16.2265 7 15.7356ZM7 18.4023C7 17.9114 7.39797 17.5134 7.88889 17.5134H14.9436C15.4345 17.5134 15.8325 17.9114 15.8325 18.4023C15.8325 18.8932 15.4345 19.2912 14.9436 19.2912H7.88889C7.39797 19.2912 7 18.8932 7 18.4023Z" fill="url(#paint1_linear_12196_859)" fill-opacity="0.4"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 9.56894C11 9.07802 11.398 8.68005 11.8889 8.68005H23.8889C24.3798 8.68005 24.7778 9.07802 24.7778 9.56894C24.7778 10.0599 24.3798 10.4578 23.8889 10.4578H11.8889C11.398 10.4578 11 10.0599 11 9.56894Z" fill="#6A6AF4" fill-opacity="0.69"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_12196_859" x="-2" y="0" width="36" height="36" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="1"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_12196_859"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_12196_859" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_12196_859" x1="16" y1="4" x2="16" y2="27.3877" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_12196_859" x1="15.9162" y1="12.1801" x2="16" y2="22.6801" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="white"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.3 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.04601 20.8381C3.04306 20.8381 2.28465 20.5812 1.77079 20.0673C1.25693 19.5597 1 18.8105 1 17.82V6.51815C1 5.52139 1.25693 4.76917 1.77079 4.2615C2.28465 3.75383 3.04306 3.5 4.04601 3.5H19.9447C20.9538 3.5 21.7154 3.75383 22.2292 4.2615C22.7431 4.76917 23 5.52139 23 6.51815V17.82C23 18.8105 22.7431 19.5597 22.2292 20.0673C21.7154 20.5812 20.9538 20.8381 19.9447 20.8381H4.04601ZM4.15745 19.0087H19.8425C20.2697 19.0087 20.5979 18.8972 20.8269 18.6743C21.056 18.4515 21.1705 18.114 21.1705 17.6621V6.66674C21.1705 6.22098 21.056 5.88666 20.8269 5.66378C20.5979 5.4409 20.2697 5.32946 19.8425 5.32946H4.15745C3.72407 5.32946 3.39285 5.4409 3.16378 5.66378C2.9409 5.88666 2.82946 6.22098 2.82946 6.66674V17.6621C2.82946 18.114 2.9409 18.4515 3.16378 18.6743C3.39285 18.8972 3.72407 19.0087 4.15745 19.0087ZM8.38286 19.3058V5.01372H10.1195V19.3058H8.38286ZM6.56268 8.72837H4.65893C4.49796 8.72837 4.35556 8.66646 4.23174 8.54263C4.11411 8.41881 4.0553 8.28261 4.0553 8.13402C4.0553 7.97305 4.11411 7.83376 4.23174 7.71613C4.35556 7.59849 4.49796 7.53968 4.65893 7.53968H6.56268C6.72984 7.53968 6.87224 7.59849 6.98987 7.71613C7.11369 7.83376 7.1756 7.97305 7.1756 8.13402C7.1756 8.28261 7.11369 8.41881 6.98987 8.54263C6.87224 8.66646 6.72984 8.72837 6.56268 8.72837ZM6.56268 11.2172H4.65893C4.49796 11.2172 4.35556 11.1584 4.23174 11.0407C4.11411 10.9169 4.0553 10.7745 4.0553 10.6136C4.0553 10.4588 4.11411 10.3226 4.23174 10.2049C4.35556 10.0873 4.49796 10.0285 4.65893 10.0285H6.56268C6.72984 10.0285 6.87224 10.0873 6.98987 10.2049C7.11369 10.3226 7.1756 10.4588 7.1756 10.6136C7.1756 10.7745 7.11369 10.9169 6.98987 11.0407C6.87224 11.1584 6.72984 11.2172 6.56268 11.2172ZM6.56268 13.6967H4.65893C4.49796 13.6967 4.35556 13.6379 4.23174 13.5203C4.11411 13.4026 4.0553 13.2664 4.0553 13.1117C4.0553 12.9507 4.11411 12.8114 4.23174 12.6938C4.35556 12.5761 4.49796 12.5173 4.65893 12.5173H6.56268C6.72984 12.5173 6.87224 12.5761 6.98987 12.6938C7.11369 12.8114 7.1756 12.9507 7.1756 13.1117C7.1756 13.2664 7.11369 13.4026 6.98987 13.5203C6.87224 13.6379 6.72984 13.6967 6.56268 13.6967Z" fill="#3251E0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.0909 6.11002H6.30726C5.51461 6.11002 4.92401 6.30619 4.53649 6.69958C4.14908 7.09297 3.95521 7.67436 3.95521 8.44342V15.1722C3.95526 15.947 4.14902 16.532 4.53649 16.9253C4.92401 17.3184 5.50902 17.5149 6.28965 17.5149H11.6175C11.8993 17.5149 12.1259 17.5501 12.2962 17.6206C12.4604 17.6852 12.6428 17.818 12.8422 18.0174L15.6253 20.756V18.2723C15.6253 17.9965 15.6866 17.8026 15.8098 17.691C15.9331 17.5736 16.1244 17.5149 16.3828 17.5149H17.6593C18.4518 17.5149 19.0425 17.3186 19.4301 16.9253C19.8175 16.532 20.0113 15.947 20.0113 15.1722V8.75944L21.7997 6.96484C21.9094 7.38948 21.9665 7.85602 21.9665 8.36467V15.2602C21.9665 16.1408 21.7987 16.896 21.464 17.5242C21.1235 18.1521 20.6452 18.634 20.029 18.9686C19.4125 19.3032 18.6867 19.4701 17.853 19.4701H17.3339V21.5579C17.3338 21.9803 17.2247 22.3179 17.0076 22.5702C16.7904 22.8225 16.4881 22.9494 16.1009 22.9495C15.831 22.9495 15.5782 22.8812 15.3435 22.7464C15.1028 22.6114 14.8174 22.3999 14.4887 22.1123L11.4859 19.4701H6.20986C5.31757 19.4701 4.55991 19.3031 3.93759 18.9686C3.30964 18.6341 2.83132 18.152 2.50253 17.5242C2.1679 16.896 2.00004 16.1408 2 15.2602V8.36467C2 7.48407 2.16449 6.72889 2.49321 6.10069C2.82786 5.47249 3.30941 4.99098 3.93759 4.6563C4.56584 4.31576 5.32672 4.14548 6.21919 4.14548H15.0534L13.0909 6.11002Z" fill="currentColor"/>
|
||||
<path d="M20.2766 5.29043L12.2475 13.3206L10.2021 14.1909C10.0759 14.2351 9.95923 14.207 9.85192 14.106C9.74466 13.9987 9.71948 13.882 9.77628 13.7557L10.6757 11.7581L18.6954 3.72895L20.2766 5.29043Z" fill="currentColor"/>
|
||||
<path d="M20.7791 2.0048C21.0377 1.97969 21.2583 2.0531 21.4412 2.22343L21.7158 2.49801C21.9114 2.69368 22.006 2.92102 21.9997 3.17979C21.9933 3.43841 21.8867 3.66903 21.6785 3.8709L21.0154 4.55269L19.4435 2.97153L20.1067 2.31772C20.296 2.12842 20.5204 2.02374 20.7791 2.0048Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_12178_2350)">
|
||||
<path d="M27.6 29L21.3 22.7C20.8 23.1 20.225 23.4167 19.575 23.65C18.925 23.8833 18.2333 24 17.5 24C15.6833 24 14.1458 23.3708 12.8875 22.1125C11.6292 20.8542 11 19.3167 11 17.5C11 15.6833 11.6292 14.1458 12.8875 12.8875C14.1458 11.6292 15.6833 11 17.5 11C19.3167 11 20.8542 11.6292 22.1125 12.8875C23.3708 14.1458 24 15.6833 24 17.5C24 18.2333 23.8833 18.925 23.65 19.575C23.4167 20.225 23.1 20.8 22.7 21.3L29 27.6L27.6 29ZM17.5 22C18.75 22 19.8125 21.5625 20.6875 20.6875C21.5625 19.8125 22 18.75 22 17.5C22 16.25 21.5625 15.1875 20.6875 14.3125C19.8125 13.4375 18.75 13 17.5 13C16.25 13 15.1875 13.4375 14.3125 14.3125C13.4375 15.1875 13 16.25 13 17.5C13 18.75 13.4375 19.8125 14.3125 20.6875C15.1875 21.5625 16.25 22 17.5 22Z" fill="#3251E0"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_12178_2350">
|
||||
<rect width="24" height="24" fill="white" transform="matrix(-1 0 0 1 32 8)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M43.9612 12.1078C43.9612 10.7446 43.9612 10.063 43.8197 9.44065C43.5582 8.29032 42.9454 7.24979 42.0663 6.46318C41.5907 6.03759 40.9946 5.707 39.8025 5.04582L36.7561 3.35621C35.6298 2.73158 35.0667 2.41926 34.4857 2.24352C33.4121 1.91883 32.2665 1.91883 31.1929 2.24352C30.6119 2.41926 30.0488 2.73158 28.9226 3.35621L27.6662 4.05301C26.1413 4.89875 25.3789 5.32161 25.0296 5.81385C24.3763 6.73448 24.3769 7.96764 25.0311 8.88764C25.3808 9.37954 26.1437 9.80168 27.6694 10.646L28.6864 11.2088C29.8804 11.8695 30.4774 12.1998 30.9538 12.6255C31.8343 13.4121 32.4482 14.4534 32.7101 15.6047C32.8519 16.2276 32.8519 16.9099 32.8519 18.2745V19.4391C32.8519 21.0927 32.8519 21.9195 33.1003 22.4525C33.5646 23.4487 34.595 24.0556 35.6913 23.9787C36.278 23.9376 37.0012 23.5368 38.4474 22.7351L39.8008 21.9849C40.9934 21.3238 41.5897 20.9933 42.0655 20.5677C42.945 19.7811 43.558 18.7404 43.8196 17.5898C43.9612 16.9673 43.9612 16.2855 43.9612 14.922V12.1078Z" fill="#2845C1"/>
|
||||
<path d="M10.0512 32.3143C8.87068 32.9959 8.2804 33.3367 7.81215 33.7704C6.94669 34.572 6.35194 35.623 6.11028 36.7776C5.97953 37.4023 5.99126 38.0838 6.01473 39.4468L6.07469 42.9299C6.09685 44.2175 6.10794 44.8614 6.24627 45.4524C6.50185 46.5445 7.07465 47.5366 7.89263 48.304C8.33535 48.7194 8.88738 49.0509 9.99144 49.7139L11.2231 50.4535C12.7179 51.3512 13.4654 51.8001 14.0663 51.8565C15.1902 51.962 16.2579 51.3449 16.7275 50.3183C16.9787 49.7695 16.9628 48.8978 16.9311 47.1543L16.91 45.9921C16.8852 44.6277 16.8728 43.9456 17.0032 43.3202C17.2442 42.1643 17.839 41.1121 18.7051 40.3095C19.1737 39.8753 19.7646 39.5342 20.9464 38.8519L21.9549 38.2696C23.387 37.4428 24.103 37.0294 24.4404 36.5477C25.071 35.6475 25.0814 34.4518 24.4667 33.5407C24.1377 33.0532 23.429 32.6273 22.0116 31.7757L20.6853 30.9787C19.5165 30.2765 18.9321 29.9253 18.3256 29.726C17.2046 29.3577 15.9968 29.3471 14.8696 29.6959C14.2597 29.8845 13.6693 30.2254 12.4884 30.9072L10.0512 32.3143Z" fill="#2845C1"/>
|
||||
<path d="M21.7175 51.8922C21.7175 53.2554 21.7175 53.937 21.8589 54.5594C22.1204 55.7097 22.7332 56.7502 23.6123 57.5368C24.088 57.9624 24.684 58.293 25.8762 58.9542L28.9226 60.6438C30.0488 61.2684 30.6119 61.5807 31.1929 61.7565C32.2665 62.0812 33.4121 62.0812 34.4857 61.7565C35.0667 61.5807 35.6298 61.2684 36.7561 60.6438L38.0124 59.947C39.5373 59.1012 40.2997 58.6784 40.649 58.1862C41.3023 57.2655 41.3017 56.0324 40.6476 55.1124C40.2978 54.6205 39.5349 54.1983 38.0093 53.354L36.9922 52.7912C35.7982 52.1305 35.2012 51.8002 34.7248 51.3745C33.8443 50.5879 33.2305 49.5466 32.9685 48.3953C32.8268 47.7724 32.8268 47.0901 32.8268 45.7255V44.5609C32.8268 42.9073 32.8268 42.0805 32.5783 41.5475C32.114 40.5513 31.0837 39.9444 29.9873 40.0213C29.4006 40.0624 28.6775 40.4632 27.2312 41.2649L25.8778 42.0151C24.6852 42.6761 24.089 43.0067 23.6131 43.4323C22.7336 44.2189 22.1206 45.2596 21.859 46.4102C21.7175 47.0327 21.7175 47.7145 21.7175 49.078V51.8922Z" fill="#2845C1"/>
|
||||
<path d="M44.5055 51.5779C45.6861 52.2595 46.2764 52.6003 46.8861 52.789C48.0131 53.1376 49.2206 53.1273 50.3414 52.7592C50.9478 52.5601 51.5321 52.2092 52.7007 51.5074L55.6872 49.7139C56.7912 49.0509 57.3433 48.7194 57.786 48.304C58.604 47.5366 59.1768 46.5445 59.4324 45.4524C59.5707 44.8614 59.5818 44.2175 59.6039 42.9299L59.6287 41.4935C59.6587 39.75 59.6737 38.8783 59.422 38.3297C58.9514 37.3036 57.8832 36.6875 56.7593 36.794C56.1584 36.851 55.4114 37.3006 53.9174 38.1997L52.9215 38.7991C51.7523 39.5028 51.1677 39.8546 50.5609 40.0544C49.4394 40.4236 48.2307 40.4346 47.1027 40.0858C46.4924 39.8971 45.9015 39.5559 44.7197 38.8736L43.7111 38.2913C42.2791 37.4645 41.563 37.0511 40.9772 36.9998C39.8823 36.9038 38.8415 37.4926 38.3599 38.4806C38.1022 39.0092 38.0878 39.8359 38.0589 41.4892L38.0319 43.0364C38.0081 44.3997 37.9962 45.0814 38.1269 45.7062C38.3684 46.8612 38.9631 47.9125 39.8287 48.7143C40.2971 49.1481 40.8875 49.489 42.0684 50.1708L44.5055 51.5779Z" fill="#2845C1"/>
|
||||
<path d="M55.6274 31.6857C56.8079 31.0041 57.3982 30.6633 57.8665 30.2296C58.7319 29.428 59.3267 28.3771 59.5683 27.2224C59.6991 26.5977 59.6874 25.9162 59.6639 24.5532L59.6039 21.0701C59.5818 19.7825 59.5707 19.1386 59.4324 18.5476C59.1768 17.4555 58.604 16.4634 57.786 15.696C57.3433 15.2806 56.7912 14.9491 55.6872 14.2861L54.4556 13.5465C52.9607 12.6488 52.2133 12.1999 51.6123 12.1435C50.4884 12.038 49.4207 12.6551 48.9511 13.6817C48.7 14.2305 48.7158 15.1022 48.7475 16.8457L48.7686 18.0079C48.7934 19.3723 48.8058 20.0544 48.6754 20.6798C48.4344 21.8357 47.8396 22.8879 46.9735 23.6905C46.5049 24.1247 45.914 24.4658 44.7322 25.1481L43.7237 25.7304C42.2916 26.5572 41.5756 26.9706 41.2382 27.4523C40.6076 28.3525 40.5972 29.5482 41.2119 30.4593C41.5409 30.9468 42.2496 31.3727 43.667 32.2243L44.9934 33.0213C46.1622 33.7235 46.7466 34.0747 47.353 34.274C48.474 34.6423 49.6818 34.6529 50.809 34.3041C51.4189 34.1155 52.0094 33.7746 53.1902 33.0928L55.6274 31.6857Z" fill="#2845C1"/>
|
||||
<path d="M21.173 12.4222C19.9925 11.7406 19.4022 11.3998 18.7924 11.2112C17.6655 10.8625 16.458 10.8728 15.3372 11.2409C14.7308 11.44 14.1465 11.7909 12.9778 12.4927L9.99135 14.2862C8.8873 14.9492 8.33527 15.2807 7.89255 15.6961C7.07457 16.4635 6.50177 17.4556 6.24619 18.5477C6.10786 19.1387 6.09677 19.7826 6.07461 21.0702L6.04988 22.5066C6.01987 24.2501 6.00486 25.1218 6.2565 25.6704C6.72713 26.6965 7.79538 27.3126 8.91921 27.2061C9.5201 27.1491 10.2671 26.6995 11.7611 25.8004L12.757 25.201C13.9262 24.4973 14.5108 24.1455 15.1176 23.9457C16.2392 23.5765 17.4478 23.5655 18.5759 23.9143C19.1862 24.103 19.7771 24.4442 20.9589 25.1265L21.9674 25.7088C23.3995 26.5356 24.1155 26.949 24.7014 27.0003C25.7962 27.0963 26.837 26.5075 27.3186 25.5195C27.5764 24.9909 27.5908 24.1642 27.6196 22.5109L27.6466 20.9638C27.6704 19.6004 27.6823 18.9187 27.5517 18.2939C27.3102 17.1389 26.7154 16.0876 25.8498 15.2858C25.3815 14.852 24.791 14.5111 23.6102 13.8293L21.173 12.4222Z" fill="#C83F49"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,21 @@
|
||||
<svg width="183" height="41" viewBox="0 0 183 41" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M25.9806 10.5539C25.9806 9.87231 25.9806 9.53151 25.9098 9.22032C25.7791 8.64516 25.4727 8.12489 25.0331 7.73159C24.7953 7.51879 24.4973 7.3535 23.9012 7.02291L22.378 6.1781C21.8149 5.86579 21.5334 5.70963 21.2428 5.62176C20.7061 5.45941 20.1333 5.45941 19.5965 5.62176C19.3059 5.70963 19.0244 5.86579 18.4613 6.1781L17.8331 6.52651C17.0707 6.94937 16.6894 7.16081 16.5148 7.40692C16.1881 7.86724 16.1884 8.48382 16.5155 8.94382C16.6904 9.18977 17.0718 9.40084 17.8347 9.82298L18.3432 10.1044C18.9402 10.4347 19.2387 10.5999 19.4769 10.8127C19.9172 11.2061 20.2241 11.7267 20.3551 12.3023C20.4259 12.6138 20.4259 12.9549 20.4259 13.6372V14.2195C20.4259 15.0463 20.4259 15.4597 20.5502 15.7263C20.7823 16.2243 21.2975 16.5278 21.8457 16.4894C22.139 16.4688 22.5006 16.2684 23.2237 15.8675L23.9004 15.4925C24.4967 15.1619 24.7948 14.9967 25.0327 14.7839C25.4725 14.3905 25.779 13.8702 25.9098 13.2949C25.9806 12.9837 25.9806 12.6428 25.9806 11.961V10.5539Z" fill="#2845C1"/>
|
||||
<path d="M9.02562 20.6571C8.43534 20.9979 8.1402 21.1683 7.90608 21.3852C7.47335 21.786 7.17597 22.3115 7.05514 22.8888C6.98977 23.2012 6.99563 23.5419 7.00736 24.2234L7.03734 25.9649C7.04843 26.6088 7.05397 26.9307 7.12313 27.2262C7.25092 27.7723 7.53733 28.2683 7.94632 28.652C8.16767 28.8597 8.44369 29.0254 8.99572 29.357L9.61153 29.7268C10.359 30.1756 10.7327 30.4001 11.0331 30.4282C11.5951 30.481 12.1289 30.1724 12.3638 29.6592C12.4893 29.3847 12.4814 28.9489 12.4656 28.0772L12.455 27.4961C12.4426 26.8139 12.4364 26.4728 12.5016 26.1601C12.6221 25.5821 12.9195 25.056 13.3526 24.6548C13.5869 24.4377 13.8823 24.2671 14.4732 23.9259L14.9775 23.6348C15.6935 23.2214 16.0515 23.0147 16.2202 22.7739C16.5355 22.3238 16.5407 21.7259 16.2333 21.2703C16.0689 21.0266 15.7145 20.8137 15.0058 20.3878L14.3426 19.9894C13.7582 19.6382 13.466 19.4627 13.1628 19.363C12.6023 19.1788 11.9984 19.1736 11.4348 19.3479C11.1298 19.4423 10.8346 19.6127 10.2442 19.9536L9.02562 20.6571Z" fill="#2845C1"/>
|
||||
<path d="M14.8587 30.4461C14.8587 31.1277 14.8587 31.4685 14.9295 31.7797C15.0602 32.3548 15.3666 32.8751 15.8062 33.2684C16.044 33.4812 16.342 33.6465 16.9381 33.9771L18.4613 34.8219C19.0244 35.1342 19.306 35.2904 19.5965 35.3782C20.1333 35.5406 20.7061 35.5406 21.2428 35.3782C21.5334 35.2904 21.8149 35.1342 22.378 34.8219L23.0062 34.4735C23.7686 34.0506 24.1499 33.8392 24.3245 33.5931C24.6512 33.1328 24.6509 32.5162 24.3238 32.0562C24.1489 31.8102 23.7675 31.5992 23.0046 31.177L22.4961 30.8956C21.8991 30.5653 21.6006 30.4001 21.3624 30.1873C20.9222 29.7939 20.6152 29.2733 20.4842 28.6977C20.4134 28.3862 20.4134 28.0451 20.4134 27.3627V26.7805C20.4134 25.9537 20.4134 25.5403 20.2892 25.2737C20.057 24.7757 19.5418 24.4722 18.9936 24.5106C18.7003 24.5312 18.3387 24.7316 17.6156 25.1325L16.9389 25.5075C16.3426 25.8381 16.0445 26.0033 15.8066 26.2161C15.3668 26.6095 15.0603 27.1298 14.9295 27.7051C14.8587 28.0163 14.8587 28.3572 14.8587 29.039V30.4461Z" fill="#2845C1"/>
|
||||
<path d="M26.2528 30.2889C26.843 30.6297 27.1382 30.8001 27.4431 30.8945C28.0065 31.0688 28.6103 31.0636 29.1707 30.8796C29.4739 30.78 29.766 30.6046 30.3504 30.2537L31.8436 29.3569C32.3956 29.0254 32.6716 28.8597 32.893 28.652C33.302 28.2683 33.5884 27.7723 33.7162 27.2262C33.7853 26.9307 33.7909 26.6088 33.802 25.9649L33.8143 25.2467C33.8293 24.375 33.8368 23.9391 33.711 23.6648C33.4757 23.1518 32.9416 22.8437 32.3797 22.897C32.0792 22.9255 31.7057 23.1503 30.9587 23.5999L30.4608 23.8995C29.8762 24.2514 29.5839 24.4273 29.2805 24.5272C28.7197 24.7118 28.1154 24.7173 27.5513 24.5429C27.2462 24.4485 26.9507 24.278 26.3598 23.9368L25.8556 23.6457C25.1395 23.2323 24.7815 23.0256 24.4886 22.9999C23.9411 22.9519 23.4208 23.2463 23.18 23.7403C23.0511 24.0046 23.0439 24.4179 23.0294 25.2446L23.0159 26.0182C23.004 26.6998 22.9981 27.0407 23.0634 27.3531C23.1842 27.9306 23.4816 28.4562 23.9144 28.8572C24.1485 29.0741 24.4438 29.2445 25.0342 29.5854L26.2528 30.2889Z" fill="#2845C1"/>
|
||||
<path d="M31.8137 20.3429C32.404 20.0021 32.6991 19.8317 32.9332 19.6148C33.366 19.214 33.6633 18.6885 33.7842 18.1112C33.8495 17.7988 33.8437 17.4581 33.8319 16.7766L33.802 15.0351C33.7909 14.3912 33.7853 14.0693 33.7162 13.7738C33.5884 13.2277 33.302 12.7317 32.893 12.348C32.6716 12.1403 32.3956 11.9746 31.8436 11.6431L31.2278 11.2732C30.4804 10.8244 30.1066 10.5999 29.8062 10.5718C29.2442 10.519 28.7104 10.8276 28.4755 11.3408C28.35 11.6153 28.3579 12.0511 28.3737 12.9228L28.3843 13.5039C28.3967 14.1861 28.4029 14.5272 28.3377 14.8399C28.2172 15.4179 27.9198 15.944 27.4867 16.3452C27.2524 16.5623 26.957 16.7329 26.3661 17.0741L25.8618 17.3652C25.1458 17.7786 24.7878 17.9853 24.6191 18.2261C24.3038 18.6762 24.2986 19.2741 24.606 19.7297C24.7704 19.9734 25.1248 20.1863 25.8335 20.6122L26.4967 21.0106C27.0811 21.3618 27.3733 21.5373 27.6765 21.637C28.237 21.8212 28.8409 21.8264 29.4045 21.6521C29.7095 21.5577 30.0047 21.3873 30.5951 21.0464L31.8137 20.3429Z" fill="#2845C1"/>
|
||||
<path d="M14.5863 10.7111C13.996 10.3703 13.7008 10.1999 13.396 10.1056C12.8325 9.93123 12.2287 9.93642 11.6683 10.1204C11.3652 10.22 11.073 10.3955 10.4887 10.7464L8.99543 11.6431C8.4434 11.9746 8.16739 12.1404 7.94603 12.348C7.53704 12.7317 7.25064 13.2278 7.12285 13.7738C7.05368 14.0694 7.04814 14.3913 7.03706 15.0351L7.0247 15.7533C7.00969 16.6251 7.00219 17.0609 7.128 17.3352C7.36332 17.8483 7.89744 18.1563 8.45936 18.103C8.75981 18.0746 9.13331 17.8498 9.88031 17.4002L10.3783 17.1005C10.9629 16.7487 11.2552 16.5728 11.5586 16.4729C12.1193 16.2883 12.7237 16.2828 13.2877 16.4572C13.5929 16.5515 13.8883 16.7221 14.4792 17.0632L14.9835 17.3544C15.6995 17.7678 16.0575 17.9745 16.3504 18.0002C16.8979 18.0482 17.4183 17.7537 17.6591 17.2598C17.7879 16.9955 17.7951 16.5821 17.8096 15.7554L17.8231 14.9819C17.835 14.3002 17.8409 13.9594 17.7756 13.6469C17.6548 13.0694 17.3575 12.5438 16.9247 12.1429C16.6905 11.926 16.3953 11.7555 15.8048 11.4146L14.5863 10.7111Z" fill="#C83F49"/>
|
||||
<path d="M61.8577 16.0576C62.6931 16.0576 63.468 16.24 64.1819 16.6045C64.8463 16.9367 65.3785 17.3509 65.7781 17.8471C65.8437 17.9285 65.8294 18.0466 65.7498 18.1145L64.3459 19.3122C64.2574 19.3877 64.1236 19.3717 64.0503 19.2814C63.7909 18.9622 63.4929 18.6926 63.1565 18.4727C62.7616 18.2145 62.3285 18.085 61.8577 18.085C61.5237 18.085 61.2353 18.1462 60.9924 18.2676C60.7646 18.3891 60.5895 18.5486 60.468 18.7461C60.3617 18.9436 60.3088 19.1642 60.3088 19.4072C60.3089 19.7716 60.4375 20.0754 60.6955 20.3184C60.969 20.5462 61.319 20.744 61.7444 20.9111C62.1696 21.0782 62.6174 21.2606 63.0881 21.458C63.5742 21.6403 64.03 21.8682 64.4553 22.1416C64.8806 22.3998 65.2225 22.7489 65.4807 23.1895C65.7541 23.6147 65.8908 24.1537 65.8909 24.8066C65.8909 25.5812 65.7012 26.2423 65.3215 26.7891C64.957 27.3206 64.471 27.7309 63.8635 28.0195C63.2559 28.3082 62.5868 28.4531 61.8577 28.4531C60.8706 28.4531 60.0124 28.2707 59.2834 27.9062C58.6116 27.5563 58.0171 27.0962 57.5 26.5269C57.4264 26.4459 57.4354 26.3208 57.5176 26.2485L58.921 25.0135C59.0067 24.9381 59.1377 24.9498 59.2123 25.0363C59.5425 25.4194 59.9081 25.7384 60.3088 25.9922C60.7645 26.2807 61.2733 26.4248 61.8352 26.4248C62.3669 26.4248 62.7698 26.2881 63.0432 26.0146C63.3316 25.7261 63.4758 25.3768 63.4758 24.9668C63.4758 24.5871 63.339 24.2835 63.0657 24.0557C62.8074 23.8278 62.4656 23.63 62.0403 23.4629C61.6149 23.2958 61.1592 23.1208 60.6731 22.9385C60.2024 22.7411 59.7545 22.5057 59.3293 22.2324C58.9041 21.959 58.5539 21.6098 58.2805 21.1846C58.0223 20.744 57.8938 20.1816 57.8938 19.498C57.8938 18.8601 58.0606 18.283 58.3948 17.7666C58.729 17.2349 59.192 16.8165 59.7844 16.5127C60.3919 16.209 61.0831 16.0577 61.8577 16.0576Z" fill="#2845C1"/>
|
||||
<path d="M71.3215 16.0576C72.1569 16.0577 72.9319 16.24 73.6457 16.6045C74.3101 16.9367 74.8424 17.3509 75.2419 17.8471C75.3075 17.9285 75.2933 18.0466 75.2137 18.1144L73.8098 19.3122C73.7213 19.3877 73.5875 19.3717 73.5141 19.2813C73.2548 18.9622 72.9568 18.6927 72.6204 18.4727C72.2255 18.2145 71.7923 18.085 71.3215 18.085C70.9873 18.085 70.6984 18.1461 70.4553 18.2676C70.2275 18.3891 70.0524 18.5486 69.9309 18.7461C69.8246 18.9435 69.7717 19.1642 69.7717 19.4072C69.7718 19.7717 69.9013 20.0754 70.1594 20.3184C70.4328 20.5462 70.782 20.7441 71.2073 20.9111C71.6326 21.0782 72.0811 21.2605 72.552 21.458C73.0379 21.6403 73.494 21.8682 73.9192 22.1416C74.3443 22.3998 74.6864 22.7491 74.9446 23.1895C75.2178 23.6146 75.3547 24.1538 75.3547 24.8066C75.3547 25.5813 75.1641 26.2422 74.7844 26.7891C74.4199 27.3207 73.934 27.7309 73.3264 28.0195C72.7189 28.3081 72.0506 28.4531 71.3215 28.4531C70.3341 28.4531 69.4755 28.2708 68.7463 27.9062C68.0745 27.5563 67.48 27.0962 66.9629 26.5269C66.8893 26.4459 66.8983 26.3208 66.9805 26.2485L68.3839 25.0135C68.4696 24.9381 68.6006 24.9498 68.6752 25.0363C69.0054 25.4194 69.371 25.7384 69.7717 25.9922C70.2273 26.2807 70.7362 26.4247 71.2981 26.4248C71.8298 26.4248 72.2327 26.2881 72.5061 26.0146C72.7946 25.7261 72.9387 25.3768 72.9387 24.9668C72.9387 24.587 72.802 24.2835 72.5286 24.0557C72.2703 23.8278 71.9285 23.63 71.5032 23.4629C71.0779 23.2958 70.622 23.1207 70.136 22.9385C69.6653 22.7411 69.2174 22.5057 68.7922 22.2324C68.3671 21.9591 68.0178 21.6097 67.7444 21.1846C67.4861 20.744 67.3567 20.1816 67.3567 19.498C67.3567 18.8602 67.5236 18.283 67.8577 17.7666C68.1918 17.235 68.655 16.8165 69.2473 16.5127C69.8549 16.2089 70.5468 16.0576 71.3215 16.0576Z" fill="#2845C1"/>
|
||||
<path d="M86.3313 16.0576C87.1668 16.0576 87.9416 16.2399 88.6555 16.6045C89.32 16.9368 89.8521 17.3508 90.2517 17.8471C90.3173 17.9285 90.303 18.0466 90.2235 18.1144L88.8195 19.3122C88.731 19.3877 88.5973 19.3717 88.5239 19.2814C88.2646 18.9622 87.9666 18.6926 87.6301 18.4727C87.2352 18.2144 86.8022 18.085 86.3313 18.085C85.9971 18.085 85.7081 18.1461 85.4651 18.2676C85.2374 18.3891 85.0631 18.5488 84.9416 18.7461C84.8353 18.9436 84.7815 19.1642 84.7815 19.4072C84.7816 19.7716 84.911 20.0754 85.1692 20.3184C85.4426 20.5462 85.7918 20.7441 86.217 20.9111C86.6424 21.0782 87.0909 21.2605 87.5618 21.458C88.0478 21.6403 88.5036 21.8682 88.9289 22.1416C89.3542 22.3998 89.6961 22.749 89.9543 23.1895C90.2276 23.6147 90.3644 24.1537 90.3645 24.8066C90.3645 25.5811 90.1747 26.2423 89.7952 26.7891C89.4306 27.3207 88.9438 27.7309 88.3362 28.0195C87.7286 28.3081 87.0604 28.4531 86.3313 28.4531C85.3439 28.4531 84.4852 28.2708 83.7561 27.9062C83.0843 27.5563 82.4905 27.0961 81.9736 26.5269C81.9 26.4459 81.909 26.3208 81.9911 26.2485L83.3937 25.0136C83.4793 24.9381 83.6104 24.9498 83.685 25.0363C84.0152 25.4194 84.3808 25.7384 84.7815 25.9922C85.2372 26.2808 85.7468 26.4248 86.3088 26.4248C86.8403 26.4248 87.2425 26.288 87.5159 26.0146C87.8044 25.7261 87.9494 25.3769 87.9495 24.9668C87.9495 24.5872 87.8125 24.2835 87.5393 24.0557C87.2811 23.8279 86.9391 23.63 86.5139 23.4629C86.0886 23.2958 85.6328 23.1207 85.1467 22.9385C84.6758 22.741 84.2273 22.5059 83.802 22.2324C83.3768 21.9591 83.0275 21.6097 82.7541 21.1846C82.4959 20.744 82.3664 20.1816 82.3664 19.498C82.3664 18.86 82.5342 18.2831 82.8684 17.7666C83.2026 17.2349 83.6656 16.8165 84.258 16.5127C84.8656 16.209 85.5567 16.0576 86.3313 16.0576Z" fill="#2845C1"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M106.191 16.2861C107.239 16.2861 108.128 16.4757 108.857 16.8555C109.586 17.2352 110.133 17.7594 110.498 18.4277C110.877 19.0961 111.067 19.8481 111.067 20.6836V28.0256C111.067 28.136 110.977 28.2256 110.867 28.2256H108.76C108.65 28.2256 108.56 28.136 108.56 28.0256V27.2662C108.56 27.1718 108.438 27.1271 108.372 27.1948C108.27 27.2997 108.159 27.4002 108.037 27.4961C107.626 27.8303 107.148 28.0892 106.601 28.2715C106.054 28.4689 105.5 28.5673 104.938 28.5674C103.814 28.5674 102.894 28.2639 102.18 27.6562C101.466 27.0486 101.11 26.2355 101.11 25.2178C101.11 24.352 101.436 23.6154 102.089 23.0078C102.743 22.4002 103.684 21.9973 104.915 21.7998L108.394 21.2089C108.49 21.1926 108.56 21.1093 108.56 21.0118V20.6836C108.56 20.0002 108.333 19.4686 107.877 19.0889C107.422 18.694 106.829 18.4962 106.1 18.4961C105.508 18.4961 104.968 18.6256 104.482 18.8838C104.071 19.1094 103.717 19.4102 103.422 19.7865C103.351 19.876 103.222 19.8965 103.132 19.8273L101.606 18.6598C101.52 18.5942 101.501 18.4719 101.568 18.3865C102.052 17.7617 102.666 17.2665 103.411 16.9014C104.231 16.4912 105.158 16.2861 106.191 16.2861ZM105.553 23.4639C104.87 23.5702 104.376 23.7671 104.072 24.0557C103.768 24.329 103.616 24.6784 103.616 25.1035C103.616 25.5288 103.775 25.8789 104.094 26.1523C104.428 26.4258 104.877 26.5625 105.439 26.5625C106.138 26.5625 106.753 26.403 107.285 26.084C107.721 25.8222 108.09 25.4882 108.393 25.083C108.508 24.9295 108.56 24.7399 108.56 24.5483V23.2008C108.56 23.0772 108.449 22.9832 108.327 23.0035L105.553 23.4639Z" fill="#2845C1"/>
|
||||
<path d="M95.9868 16.5412C95.9868 16.6517 96.0764 16.7412 96.1868 16.7412H99.5017C99.6121 16.7412 99.7017 16.8308 99.7017 16.9412V18.7971C99.7017 18.9075 99.6121 18.9971 99.5017 18.9971H96.1868C96.0764 18.9971 95.9868 19.0866 95.9868 19.1971V24.1699C95.9868 24.671 96.0708 25.0659 96.2378 25.3545C96.4048 25.6429 96.6403 25.8555 96.9439 25.9922C97.2477 26.1137 97.605 26.1748 98.0151 26.1748C98.4101 26.1748 98.7446 26.152 99.0181 26.1064C99.1739 26.0718 99.3174 26.0347 99.4485 25.9951C99.5829 25.9545 99.7241 26.0522 99.7241 26.1926V27.9814C99.7241 28.0604 99.6778 28.1326 99.6042 28.1613C99.3605 28.2561 99.0888 28.3233 98.7896 28.3623C98.4554 28.423 98.0605 28.4531 97.605 28.4531C96.6936 28.4531 95.926 28.2936 95.3032 27.9746C94.6959 27.6404 94.2325 27.1617 93.9136 26.5391C93.6099 25.9012 93.4585 25.1115 93.4585 24.1699V19.1971C93.4585 19.0866 93.369 18.9971 93.2585 18.9971H91.6087C91.4982 18.9971 91.4087 18.9075 91.4087 18.7971V16.9412C91.4087 16.8308 91.4982 16.7412 91.6087 16.7412H93.2585C93.369 16.7412 93.4585 16.6517 93.4585 16.5412V14.0711C93.4585 13.9606 93.548 13.8711 93.6585 13.8711H95.7868C95.8973 13.8711 95.9868 13.9606 95.9868 14.0711V16.5412Z" fill="#2845C1"/>
|
||||
<path d="M130.563 16.5412C130.563 16.6517 130.653 16.7412 130.763 16.7412H134.077C134.187 16.7412 134.277 16.8308 134.277 16.9412V18.7971C134.277 18.9075 134.187 18.9971 134.077 18.9971H130.763C130.653 18.9971 130.563 19.0866 130.563 19.1971V24.1699C130.563 24.671 130.646 25.0659 130.813 25.3545C130.98 25.6431 131.216 25.8555 131.52 25.9922C131.824 26.1137 132.18 26.1748 132.59 26.1748C132.985 26.1748 133.32 26.152 133.593 26.1064C133.749 26.0718 133.893 26.0347 134.024 25.9951C134.158 25.9545 134.299 26.0522 134.299 26.1925V27.9813C134.299 28.0604 134.253 28.1326 134.179 28.1613C133.936 28.2561 133.665 28.3233 133.366 28.3623C133.032 28.4231 132.636 28.4531 132.18 28.4531C131.269 28.4531 130.502 28.2936 129.879 27.9746C129.272 27.6404 128.809 27.1619 128.49 26.5391C128.186 25.9011 128.034 25.1116 128.034 24.1699V19.1971C128.034 19.0866 127.944 18.9971 127.834 18.9971H126.092C125.982 18.9971 125.892 18.9075 125.892 18.7971V16.9412C125.892 16.8308 125.982 16.7412 126.092 16.7412H127.834C127.944 16.7412 128.034 16.6517 128.034 16.5412V14.0711C128.034 13.9606 128.123 13.8711 128.234 13.8711H130.363C130.473 13.8711 130.563 13.9606 130.563 14.0711V16.5412Z" fill="#2845C1"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M56.8209 27.9534C56.8716 28.0844 56.7749 28.2256 56.6344 28.2256H54.0801C53.9969 28.2256 53.9224 28.1741 53.893 28.0964L52.3355 23.9798C52.3061 23.902 52.2316 23.8506 52.1485 23.8506H45.6707C45.5876 23.8506 45.5132 23.9019 45.4837 23.9796L43.9196 28.0966C43.8901 28.1743 43.8157 28.2256 43.7326 28.2256H41.2002C41.0598 28.2256 40.9631 28.0846 41.0136 27.9536L47.0107 12.4034C47.0404 12.3263 47.1146 12.2754 47.1973 12.2754H50.6144C50.697 12.2754 50.7711 12.3262 50.8009 12.4032L56.8209 27.9534ZM46.5361 21.2104C46.4864 21.3413 46.5831 21.4814 46.7231 21.4814H51.1006C51.2405 21.4814 51.3372 21.3415 51.2876 21.2106L49.1032 15.4395C49.038 15.2673 48.7946 15.2672 48.7292 15.4392L46.5361 21.2104Z" fill="#2845C1"/>
|
||||
<path d="M80.1372 28.0256C80.1372 28.136 80.0477 28.2256 79.9372 28.2256H77.8314C77.7209 28.2256 77.6314 28.136 77.6314 28.0256V16.9412C77.6314 16.8308 77.7209 16.7412 77.8314 16.7412H79.9372C80.0477 16.7412 80.1372 16.8308 80.1372 16.9412V28.0256Z" fill="#2845C1"/>
|
||||
<path d="M120.009 16.2861C120.86 16.2861 121.619 16.4758 122.288 16.8555C122.971 17.2352 123.511 17.7977 123.906 18.542C124.301 19.2863 124.499 20.2208 124.499 21.3447V28.0256C124.499 28.136 124.409 28.2256 124.299 28.2256H122.169C122.059 28.2256 121.969 28.136 121.969 28.0256V21.4355C121.969 20.5546 121.741 19.8709 121.286 19.3848C120.83 18.8835 120.206 18.6328 119.417 18.6328C118.915 18.6329 118.475 18.7313 118.095 18.9287C117.715 19.111 117.389 19.3471 117.116 19.6357C116.919 19.8551 116.745 20.0831 116.592 20.3199C116.498 20.4662 116.455 20.6384 116.455 20.8124V28.0256C116.455 28.136 116.365 28.2256 116.255 28.2256H114.149C114.038 28.2256 113.949 28.136 113.949 28.0256V16.9412C113.949 16.8308 114.038 16.7412 114.149 16.7412H116.255C116.365 16.7412 116.455 16.8308 116.455 16.9412V17.5392C116.455 17.6294 116.566 17.6747 116.631 17.6128C117.008 17.2571 117.443 16.9588 117.936 16.7188C118.528 16.4302 119.219 16.2861 120.009 16.2861Z" fill="#2845C1"/>
|
||||
<path d="M78.9067 11C79.2105 11 79.484 11.0757 79.7271 11.2275C79.9853 11.3794 80.1831 11.5845 80.3198 11.8428C80.4717 12.0858 80.5474 12.3593 80.5474 12.6631C80.5474 12.9668 80.4716 13.2477 80.3198 13.5059C80.1831 13.7641 79.9853 13.9692 79.7271 14.1211C79.484 14.2578 79.2106 14.3262 78.9067 14.3262C78.603 14.3262 78.3222 14.2578 78.064 14.1211C77.8057 13.9692 77.6006 13.7641 77.4487 13.5059C77.2969 13.2477 77.2212 12.9668 77.2212 12.6631C77.2212 12.2074 77.3807 11.82 77.6997 11.501C78.0338 11.167 78.436 11 78.9067 11Z" fill="#2845C1"/>
|
||||
<rect x="143" y="12.5" width="40" height="16" rx="8" fill="#2845C1"/>
|
||||
<rect x="143" y="12.5" width="40" height="16" rx="8" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path d="M150.133 24.5V16.8H152.399C154.005 16.8 154.984 17.592 154.984 18.89C154.984 19.517 154.698 20.056 154.159 20.408C154.973 20.771 155.424 21.431 155.424 22.234C155.424 23.642 154.335 24.5 152.564 24.5H150.133ZM152.432 18.098H151.695V19.836H152.432C153.026 19.836 153.378 19.517 153.378 18.956C153.378 18.417 153.026 18.098 152.432 18.098ZM152.652 21.134H151.695V23.202H152.652C153.378 23.202 153.818 22.817 153.818 22.168C153.818 21.508 153.378 21.134 152.652 21.134ZM156.917 24.5V16.8H161.405V18.098H158.479V19.924H160.965V21.222H158.479V23.202H161.405V24.5H156.917ZM162.479 18.219V16.8H168.793V18.219H166.417V24.5H164.855V18.219H162.479ZM168.346 24.5L171.261 16.8H173.307L176.222 24.5H174.561L173.824 22.498H170.744L170.007 24.5H168.346ZM171.228 21.167H173.34L172.284 18.274L171.228 21.167Z" fill="#2845C1"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,131 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import { Box, Text } from '@/components';
|
||||
import { Icon } from '@/components/Icon';
|
||||
|
||||
export type ToastType = 'success' | 'error' | 'info' | 'warning';
|
||||
|
||||
export interface ToastProps {
|
||||
id: string;
|
||||
message: string;
|
||||
type: ToastType;
|
||||
icon?: string;
|
||||
duration?: number;
|
||||
onClose: (id: string) => void;
|
||||
}
|
||||
|
||||
const getToastConfig = (type: ToastType) => {
|
||||
switch (type) {
|
||||
case 'success':
|
||||
return {
|
||||
icon: 'check_circle',
|
||||
color: '#223E9E',
|
||||
bgColor: '#EDF0FF',
|
||||
borderColor: '#C8D3FF',
|
||||
};
|
||||
case 'error':
|
||||
return {
|
||||
icon: 'error',
|
||||
color: '#EF4444',
|
||||
bgColor: '#FEF2F2',
|
||||
borderColor: '#FECACA',
|
||||
};
|
||||
case 'warning':
|
||||
return {
|
||||
icon: 'warning',
|
||||
color: '#F59E0B',
|
||||
bgColor: '#FFFBEB',
|
||||
borderColor: '#FED7AA',
|
||||
};
|
||||
case 'info':
|
||||
return {
|
||||
icon: 'info',
|
||||
color: '#3B82F6',
|
||||
bgColor: '#EFF6FF',
|
||||
borderColor: '#BFDBFE',
|
||||
};
|
||||
default:
|
||||
return {
|
||||
icon: 'info',
|
||||
color: '#6B7280',
|
||||
bgColor: '#F9FAFB',
|
||||
borderColor: '#E5E7EB',
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const Toast = ({
|
||||
id,
|
||||
message,
|
||||
type,
|
||||
icon,
|
||||
duration = 4000,
|
||||
onClose,
|
||||
}: ToastProps) => {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [isLeaving, setIsLeaving] = useState(false);
|
||||
const config = getToastConfig(type);
|
||||
const iconToUse = icon || config.icon;
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setIsVisible(true), 100);
|
||||
|
||||
const autoCloseTimer = setTimeout(() => {
|
||||
setIsLeaving(true);
|
||||
setTimeout(() => onClose(id), 300);
|
||||
}, duration);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
clearTimeout(autoCloseTimer);
|
||||
};
|
||||
}, [id, duration, onClose]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
$css={css`
|
||||
background-color: ${config.bgColor};
|
||||
border: 1px solid ${config.borderColor};
|
||||
color: ${config.color};
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
width: auto;
|
||||
margin-bottom: 8px;
|
||||
box-shadow: 0 6px 18px 0 rgba(0, 0, 145, 0.05);
|
||||
transform: translateY(${isVisible ? '0' : '100%'});
|
||||
opacity: ${isVisible ? '1' : '0'};
|
||||
transition: all 0.3s ease-in-out;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
${isLeaving &&
|
||||
css`
|
||||
transform: translateY(-100%);
|
||||
opacity: 0;
|
||||
`}
|
||||
`}
|
||||
>
|
||||
<Box $direction="row" $align="center" $gap="12px">
|
||||
<Icon
|
||||
iconName={iconToUse}
|
||||
$variation="600"
|
||||
$size="20px"
|
||||
$css={css`
|
||||
color: ${config.color} !important;
|
||||
`}
|
||||
/>
|
||||
<Text
|
||||
$weight="500"
|
||||
$size="14px"
|
||||
$css={css`
|
||||
color: ${config.color} !important;
|
||||
padding: 4px;
|
||||
`}
|
||||
>
|
||||
{message}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import Lottie from 'react-lottie';
|
||||
|
||||
import searchingAnimation from '@/assets/lotties/searching';
|
||||
|
||||
export const Loader = () => {
|
||||
const LoaderOptions = {
|
||||
loop: true,
|
||||
autoplay: true,
|
||||
animationData: searchingAnimation,
|
||||
rendererSettings: {
|
||||
preserveAspectRatio: 'xMidYMid slice',
|
||||
},
|
||||
} as const;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Lottie options={LoaderOptions} height={24} width={24} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -20,8 +20,6 @@ const SideModalStyle = createGlobalStyle<SideModalStyleProps>`
|
||||
}
|
||||
|
||||
& .c__modal{
|
||||
animation: slidein 0.7s;
|
||||
|
||||
width: ${({ width }) => width};
|
||||
${({ side }) => side === 'right' && 'left: auto;'};
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import {
|
||||
ReactNode,
|
||||
createContext,
|
||||
useCallback,
|
||||
useContext,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import { Box } from '@/components';
|
||||
|
||||
import { Toast, ToastType } from './CustomToast';
|
||||
|
||||
interface ToastItem {
|
||||
id: string;
|
||||
message: string;
|
||||
type: ToastType;
|
||||
icon?: string;
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
interface ToastContextType {
|
||||
showToast: (
|
||||
type: ToastType,
|
||||
message: string,
|
||||
icon?: string,
|
||||
duration?: number,
|
||||
) => void;
|
||||
}
|
||||
|
||||
const ToastContext = createContext<ToastContextType | undefined>(undefined);
|
||||
|
||||
export const useToast = () => {
|
||||
const context = useContext(ToastContext);
|
||||
if (!context) {
|
||||
throw new Error('useToast must be used within a ToastProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
interface ToastProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const ToastProvider = ({ children }: ToastProviderProps) => {
|
||||
const [toasts, setToasts] = useState<ToastItem[]>([]);
|
||||
|
||||
const showToast = useCallback(
|
||||
(type: ToastType, message: string, icon?: string, duration = 4000) => {
|
||||
const id = Math.random().toString(36).substr(2, 9);
|
||||
const newToast: ToastItem = { id, message, type, icon, duration };
|
||||
|
||||
setToasts((prev) => [...prev, newToast]);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const removeToast = useCallback((id: string) => {
|
||||
setToasts((prev) => prev.filter((toast) => toast.id !== id));
|
||||
}, []);
|
||||
|
||||
const value = {
|
||||
showToast,
|
||||
};
|
||||
|
||||
return (
|
||||
<ToastContext.Provider value={value}>
|
||||
{children}
|
||||
{typeof window !== 'undefined' &&
|
||||
createPortal(
|
||||
<Box
|
||||
$css={`
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1000;
|
||||
display: inline-block;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
width: auto;
|
||||
pointer-events: none;
|
||||
& > * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
`}
|
||||
>
|
||||
{toasts.map((toast) => (
|
||||
<Toast
|
||||
key={toast.id}
|
||||
id={toast.id}
|
||||
message={toast.message}
|
||||
type={toast.type}
|
||||
icon={toast.icon}
|
||||
duration={toast.duration}
|
||||
onClose={removeToast}
|
||||
/>
|
||||
))}
|
||||
</Box>,
|
||||
document.body,
|
||||
)}
|
||||
</ToastContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -6,8 +6,11 @@ export * from './DropdownMenu';
|
||||
export * from './Icon';
|
||||
export * from './InfiniteScroll';
|
||||
export * from './Link';
|
||||
export * from './Loader';
|
||||
export * from './LoadMoreText';
|
||||
export * from './SideModal';
|
||||
export * from './separators';
|
||||
export * from './Text';
|
||||
export * from './TextErrors';
|
||||
export * from './CustomToast';
|
||||
export * from './ToastProvider';
|
||||
|
||||
@@ -24,6 +24,7 @@ export type QuickSearchData<T> = {
|
||||
|
||||
export type QuickSearchProps = {
|
||||
onFilter?: (str: string) => void;
|
||||
onClear?: () => void;
|
||||
inputValue?: string;
|
||||
inputContent?: ReactNode;
|
||||
showInput?: boolean;
|
||||
@@ -35,6 +36,7 @@ export type QuickSearchProps = {
|
||||
|
||||
export const QuickSearch = ({
|
||||
onFilter,
|
||||
onClear,
|
||||
inputContent,
|
||||
inputValue,
|
||||
loading,
|
||||
@@ -48,24 +50,23 @@ export const QuickSearch = ({
|
||||
return (
|
||||
<>
|
||||
<QuickSearchStyle />
|
||||
<div className="quick-search-container">
|
||||
<Command label={label} shouldFilter={false} ref={ref}>
|
||||
{showInput && (
|
||||
<QuickSearchInput
|
||||
loading={loading}
|
||||
withSeparator={hasChildrens(children)}
|
||||
inputValue={inputValue}
|
||||
onFilter={onFilter}
|
||||
placeholder={placeholder}
|
||||
>
|
||||
{inputContent}
|
||||
</QuickSearchInput>
|
||||
)}
|
||||
<Command.List>
|
||||
<Box>{children}</Box>
|
||||
</Command.List>
|
||||
</Command>
|
||||
</div>
|
||||
<Command label={label} shouldFilter={false} ref={ref}>
|
||||
{showInput && (
|
||||
<QuickSearchInput
|
||||
loading={loading}
|
||||
withSeparator={hasChildrens(children)}
|
||||
inputValue={inputValue}
|
||||
onFilter={onFilter}
|
||||
onClear={onClear}
|
||||
placeholder={placeholder}
|
||||
>
|
||||
{inputContent}
|
||||
</QuickSearchInput>
|
||||
)}
|
||||
<Command.List>
|
||||
<Box $padding={{ horizontal: 'sm', top: 'sm' }}>{children}</Box>
|
||||
</Command.List>
|
||||
</Command>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { Command } from 'cmdk';
|
||||
import { ReactNode } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
|
||||
import { Box } from '../Box';
|
||||
import { Text } from '../Text';
|
||||
|
||||
import { QuickSearchData } from './QuickSearch';
|
||||
import { QuickSearchItem } from './QuickSearchItem';
|
||||
@@ -17,13 +21,22 @@ export const QuickSearchGroup = <T,>({
|
||||
onSelect,
|
||||
renderElement,
|
||||
}: Props<T>) => {
|
||||
const { t } = useTranslation();
|
||||
const { spacingsTokens } = useCunninghamTheme();
|
||||
|
||||
return (
|
||||
<Box $margin={{ top: 'base' }}>
|
||||
<Command.Group
|
||||
key={group.groupName}
|
||||
heading={group.groupName}
|
||||
forceMount={false}
|
||||
>
|
||||
<Box>
|
||||
<Command.Group key={group.groupName} forceMount={false}>
|
||||
<Text
|
||||
$size="sm"
|
||||
$variation="700"
|
||||
$margin={{ bottom: spacingsTokens['2xs'] }}
|
||||
$padding={{ horizontal: 'xs' }}
|
||||
$weight="700"
|
||||
>
|
||||
{t('Search results')}
|
||||
</Text>
|
||||
|
||||
{group.startActions?.map((action, index) => {
|
||||
return (
|
||||
<QuickSearchItem
|
||||
@@ -58,7 +71,14 @@ export const QuickSearchGroup = <T,>({
|
||||
);
|
||||
})}
|
||||
{group.emptyString && group.elements.length === 0 && (
|
||||
<span className="ml-b clr-greyscale-500">{group.emptyString}</span>
|
||||
<Text
|
||||
$size="sm"
|
||||
$variation="500"
|
||||
$margin={{ bottom: spacingsTokens['2xs'] }}
|
||||
$padding={{ horizontal: 'xs' }}
|
||||
>
|
||||
{group.emptyString}
|
||||
</Text>
|
||||
)}
|
||||
</Command.Group>
|
||||
</Box>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Loader } from '@openfun/cunningham-react';
|
||||
import { Command } from 'cmdk';
|
||||
import { ReactNode } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -8,6 +7,7 @@ import { useCunninghamTheme } from '@/cunningham';
|
||||
|
||||
import { Box } from '../Box';
|
||||
import { Icon } from '../Icon';
|
||||
import { Loader } from '../Loader';
|
||||
|
||||
type Props = {
|
||||
loading?: boolean;
|
||||
@@ -16,6 +16,7 @@ type Props = {
|
||||
placeholder?: string;
|
||||
children?: ReactNode;
|
||||
withSeparator?: boolean;
|
||||
onClear?: () => void;
|
||||
};
|
||||
export const QuickSearchInput = ({
|
||||
loading,
|
||||
@@ -24,6 +25,7 @@ export const QuickSearchInput = ({
|
||||
placeholder,
|
||||
children,
|
||||
withSeparator: separator = true,
|
||||
onClear,
|
||||
}: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { spacingsTokens } = useCunninghamTheme();
|
||||
@@ -42,16 +44,30 @@ export const QuickSearchInput = ({
|
||||
<Box
|
||||
$direction="row"
|
||||
$align="center"
|
||||
className="quick-search-input"
|
||||
$gap={spacingsTokens['2xs']}
|
||||
$padding={{ all: 'base' }}
|
||||
$css={`
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
margin: 12px 12px 0 12px;
|
||||
border: 1px solid #CFD5DE;
|
||||
background-color: #EEF1F4;
|
||||
padding: 6px 8px;
|
||||
&:focus-within {
|
||||
border: 2px solid #3E5DE7;
|
||||
padding: 5px 7px;
|
||||
}
|
||||
& input {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
&:focus {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
`}
|
||||
>
|
||||
{!loading && <Icon iconName="search" $variation="600" />}
|
||||
{loading && (
|
||||
<div>
|
||||
<Loader size="small" />
|
||||
</div>
|
||||
)}
|
||||
{loading && <Loader />}
|
||||
<Command.Input
|
||||
/* eslint-disable-next-line jsx-a11y/no-autofocus */
|
||||
autoFocus={true}
|
||||
@@ -61,8 +77,21 @@ export const QuickSearchInput = ({
|
||||
placeholder={placeholder ?? t('Search')}
|
||||
onValueChange={onFilter}
|
||||
/>
|
||||
<Icon
|
||||
iconName="close"
|
||||
$size="sm"
|
||||
$variation="600"
|
||||
$css={`cursor: pointer;
|
||||
position: absolute;
|
||||
opacity: ${inputValue && inputValue.length > 0 && onClear ? 1 : 0};
|
||||
transition: opacity 0.3s cubic-bezier(1, 0, 0, 1);
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
z-index: 1000;`}
|
||||
onClick={onClear}
|
||||
aria-label={t('Clear search')}
|
||||
/>
|
||||
</Box>
|
||||
{separator && <HorizontalSeparator $withPadding={false} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,25 +9,18 @@ export const QuickSearchStyle = createGlobalStyle`
|
||||
overflow: hidden;
|
||||
transition: transform 100ms ease;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
[cmdk-input] {
|
||||
border: none;
|
||||
width: 100%;
|
||||
font-size: 17px;
|
||||
padding: 8px;
|
||||
background: white;
|
||||
outline: none;
|
||||
color: var(--c--theme--colors--greyscale-1000);
|
||||
border-radius: 0;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--c--theme--colors--greyscale-500);
|
||||
font-size: 14px;
|
||||
color: #626A80;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[cmdk-item] {
|
||||
content-visibility: auto;
|
||||
cursor: pointer;
|
||||
@@ -96,7 +89,7 @@ export const QuickSearchStyle = createGlobalStyle`
|
||||
[cmdk-separator] {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background: var(--c--theme--colors--greyscale-500);
|
||||
background: transparent;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
@@ -105,18 +98,13 @@ export const QuickSearchStyle = createGlobalStyle`
|
||||
}
|
||||
|
||||
[cmdk-group-heading] {
|
||||
padding: 0 var(--c--theme--spacings--xs);
|
||||
user-select: none;
|
||||
font-size: var(--c--theme--font--sizes--sm);
|
||||
font-size: 12px;
|
||||
color: var(--c--theme--colors--greyscale-700);
|
||||
font-weight: bold;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 700;;
|
||||
margin-bottom: var(--c--theme--spacings--xs);
|
||||
}
|
||||
|
||||
[cmdk-empty] {
|
||||
}
|
||||
}
|
||||
|
||||
.c__modal__scroller:has(.quick-search-container),
|
||||
|
||||
@@ -3,6 +3,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { ToastProvider } from '@/components';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { Auth, KEY_AUTH, setAuthUrl } from '@/features/auth';
|
||||
import { useResponsiveStore } from '@/stores/';
|
||||
@@ -63,7 +64,9 @@ export function AppProvider({ children }: { children: React.ReactNode }) {
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<CunninghamProvider theme={theme}>
|
||||
<ConfigProvider>
|
||||
<Auth>{children}</Auth>
|
||||
<ToastProvider>
|
||||
<Auth>{children}</Auth>
|
||||
</ToastProvider>
|
||||
</ConfigProvider>
|
||||
</CunninghamProvider>
|
||||
</QueryClientProvider>
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
--c--theme--colors--info-700: #273961;
|
||||
--c--theme--colors--info-800: #222a3f;
|
||||
--c--theme--colors--info-900: #1d2437;
|
||||
--c--theme--colors--greyscale-050: #eaecf0;
|
||||
--c--theme--colors--greyscale-100: #eee;
|
||||
--c--theme--colors--greyscale-200: #e5e5e5;
|
||||
--c--theme--colors--greyscale-200: #d9dde6;
|
||||
--c--theme--colors--greyscale-300: #cecece;
|
||||
--c--theme--colors--greyscale-400: #929292;
|
||||
--c--theme--colors--greyscale-500: #7c7c7c;
|
||||
@@ -36,7 +37,7 @@
|
||||
--c--theme--colors--primary-500: #6a6af4;
|
||||
--c--theme--colors--primary-600: #313178;
|
||||
--c--theme--colors--primary-700: #272747;
|
||||
--c--theme--colors--primary-800: #000091;
|
||||
--c--theme--colors--primary-800: #3e5de7;
|
||||
--c--theme--colors--primary-900: #21213f;
|
||||
--c--theme--colors--success-100: #dffee6;
|
||||
--c--theme--colors--success-200: #b8fec9;
|
||||
@@ -65,19 +66,18 @@
|
||||
--c--theme--colors--danger-700: #642626;
|
||||
--c--theme--colors--danger-800: #412121;
|
||||
--c--theme--colors--danger-900: #391c1c;
|
||||
--c--theme--colors--primary-text: #000091;
|
||||
--c--theme--colors--primary-text: #4c6cef;
|
||||
--c--theme--colors--success-text: #1f8d49;
|
||||
--c--theme--colors--warning-text: #d64d00;
|
||||
--c--theme--colors--danger-text: #fff;
|
||||
--c--theme--colors--primary-050: #f5f5fe;
|
||||
--c--theme--colors--primary-150: #f4f4fd;
|
||||
--c--theme--colors--greyscale-text: #303c4b;
|
||||
--c--theme--colors--greyscale-050: #f6f6f6;
|
||||
--c--theme--colors--greyscale-250: #ddd;
|
||||
--c--theme--colors--greyscale-350: #ddd;
|
||||
--c--theme--colors--greyscale-750: #353535;
|
||||
--c--theme--colors--greyscale-950: #1e1e1e;
|
||||
--c--theme--colors--greyscale-1000: #161616;
|
||||
--c--theme--colors--greyscale-1000: #2a2f3c;
|
||||
--c--theme--colors--danger-050: #fff4f4;
|
||||
--c--theme--colors--blue-500: #417dc4;
|
||||
--c--theme--colors--brown-500: #bd987a;
|
||||
@@ -205,10 +205,8 @@
|
||||
--c--components--button--medium-text-height: 40px;
|
||||
--c--components--button--border-radius: 4px;
|
||||
--c--components--button--small-height: 26px;
|
||||
--c--components--button--primary--background--color: var(
|
||||
--c--theme--colors--primary-text
|
||||
);
|
||||
--c--components--button--primary--background--color-hover: #1212ff;
|
||||
--c--components--button--primary--background--color: #3e5de6;
|
||||
--c--components--button--primary--background--color-hover: #2944c2;
|
||||
--c--components--button--primary--background--color-active: #2323ff;
|
||||
--c--components--button--primary--background--color-disabled: var(
|
||||
--c--theme--colors--greyscale-100
|
||||
@@ -220,9 +218,7 @@
|
||||
--c--components--button--primary--disabled: var(
|
||||
--c--theme--colors--greyscale-500
|
||||
);
|
||||
--c--components--button--primary-text--background--color: var(
|
||||
--c--theme--colors--primary-text
|
||||
);
|
||||
--c--components--button--primary-text--background--color: #3e5de6;
|
||||
--c--components--button--primary-text--background--color-hover: var(
|
||||
--c--theme--colors--greyscale-100
|
||||
);
|
||||
@@ -491,7 +487,7 @@
|
||||
--c--components--home-proconnect: false;
|
||||
--c--components--beta: false;
|
||||
--c--components--image-system-filter: ;
|
||||
--c--components--favicon--ico: /assets/favicon-light.ico;
|
||||
--c--components--favicon--ico: /assets/favicon.ico;
|
||||
--c--components--favicon--png-light: /assets/favicon-light.png;
|
||||
--c--components--favicon--png-dark: /assets/favicon-dark.png;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ export const tokens = {
|
||||
'greyscale-300': '#CECECE',
|
||||
'greyscale-400': '#929292',
|
||||
'greyscale-500': '#7C7C7C',
|
||||
'greyscale-550': '#626A80',
|
||||
'greyscale-600': '#666666',
|
||||
'greyscale-700': '#3A3A3A',
|
||||
'greyscale-800': '#2A2A2A',
|
||||
@@ -69,7 +70,7 @@ export const tokens = {
|
||||
'danger-700': '#642626',
|
||||
'danger-800': '#412121',
|
||||
'danger-900': '#391C1C',
|
||||
'primary-text': '#000091',
|
||||
'primary-text': '#314ddf',
|
||||
'success-text': '#1f8d49',
|
||||
'warning-text': '#d64d00',
|
||||
'danger-text': '#FFF',
|
||||
@@ -221,7 +222,7 @@ export const tokens = {
|
||||
'border-radius': '4px',
|
||||
'small-height': '26px',
|
||||
primary: {
|
||||
'background--color': '#000091',
|
||||
'background--color': '#3E5DE7',
|
||||
'background--color-hover': '#1212ff',
|
||||
'background--color-active': '#2323ff',
|
||||
'background--color-disabled': '#eee',
|
||||
@@ -232,13 +233,13 @@ export const tokens = {
|
||||
disabled: '#7C7C7C',
|
||||
},
|
||||
'primary-text': {
|
||||
'background--color': '#000091',
|
||||
'background--color': '#3E5DE7',
|
||||
'background--color-hover': '#eee',
|
||||
'background--color-active': '#ECECFE',
|
||||
'background--color-focus-visible': '#fff',
|
||||
'background--color-disabled': '#fff',
|
||||
color: '#000091',
|
||||
'color-hover': '#000091',
|
||||
color: '#3E5DE7',
|
||||
'color-hover': '#3E5DE7',
|
||||
disabled: '#929292',
|
||||
},
|
||||
secondary: {
|
||||
@@ -268,11 +269,11 @@ export const tokens = {
|
||||
},
|
||||
danger: {
|
||||
'color-hover': 'white',
|
||||
'background--color': '#CE0500',
|
||||
'background--color': '#626A80',
|
||||
'background--color-hover': '#FF2725',
|
||||
'background--color-focus-visible': '#CE0500',
|
||||
'background--color-disabled': '#eee',
|
||||
'color-disabled': '#929292',
|
||||
'color-disabled': '#626A80',
|
||||
},
|
||||
},
|
||||
datagrid: {
|
||||
@@ -381,7 +382,7 @@ export const tokens = {
|
||||
'greyscale-200': '#303C4B',
|
||||
'greyscale-300': '#555F6B',
|
||||
'greyscale-400': '#79818A',
|
||||
'greyscale-500': '#9EA3AA',
|
||||
'greyscale-500': '#6D778C',
|
||||
'greyscale-600': '#C2C6CA',
|
||||
'greyscale-700': '#E7E8EA',
|
||||
'greyscale-800': '#F3F4F4',
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Loader } from '@openfun/cunningham-react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import { Box } from '@/components';
|
||||
import { Box, Loader } from '@/components';
|
||||
import { useConfig } from '@/core';
|
||||
|
||||
import { HOME_URL } from '../conf';
|
||||
|
||||
@@ -45,7 +45,7 @@ export const ProConnectButton = () => {
|
||||
onClick={() => gotoLogin()}
|
||||
aria-label={t('Proconnect Login')}
|
||||
$css={css`
|
||||
background-color: var(--c--theme--colors--primary-text);
|
||||
background-color: #000091;
|
||||
&:hover {
|
||||
background-color: var(--c--theme--colors--primary-action);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 293 KiB |
@@ -1,38 +0,0 @@
|
||||
import { Box, Icon } from '@/components';
|
||||
import { QuickSearchItemContent } from '@/components/quick-search/';
|
||||
import { ChatConversation } from '@/features/chat/types';
|
||||
import { SimpleConversationItem } from '@/features/left-panel/components/SimpleConversationItem';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
type ConversationSearchItemProps = {
|
||||
conversation: ChatConversation;
|
||||
};
|
||||
|
||||
export const ConversationSearchItem = ({
|
||||
conversation,
|
||||
}: ConversationSearchItemProps) => {
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
return (
|
||||
<Box
|
||||
data-testid={`doc-search-item-${conversation.id}`}
|
||||
$width="100%"
|
||||
className="--docs--doc-search-item"
|
||||
>
|
||||
<QuickSearchItemContent
|
||||
left={
|
||||
<Box $direction="row" $align="center" $gap="10px" $width="100%">
|
||||
<Box $flex={isDesktop ? 9 : 1}>
|
||||
<SimpleConversationItem
|
||||
conversation={conversation}
|
||||
showAccesses
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
}
|
||||
right={
|
||||
<Icon iconName="keyboard_return" $theme="primary" $variation="800" />
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -1,114 +0,0 @@
|
||||
import { Modal, ModalSize } from '@openfun/cunningham-react';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { InView } from 'react-intersection-observer';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import { Box } from '@/components';
|
||||
import {
|
||||
QuickSearch,
|
||||
QuickSearchData,
|
||||
QuickSearchGroup,
|
||||
} from '@/components/quick-search';
|
||||
import { useInfiniteConversations } from '@/features/chat/api/useConversations';
|
||||
import { ChatConversation } from '@/features/chat/types';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import EmptySearchIcon from '../assets/illustration-docs-empty.png';
|
||||
|
||||
import { ConversationSearchItem } from './ConversationSearchItem';
|
||||
|
||||
type ConversationSearchModalProps = {
|
||||
onClose: () => void;
|
||||
isOpen: boolean;
|
||||
};
|
||||
|
||||
export const ConversationSearchModal = ({
|
||||
...modalProps
|
||||
}: ConversationSearchModalProps) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const [search, setSearch] = useState('');
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const {
|
||||
data,
|
||||
isFetching,
|
||||
isRefetching,
|
||||
isLoading,
|
||||
fetchNextPage,
|
||||
hasNextPage,
|
||||
} = useInfiniteConversations({
|
||||
page: 1,
|
||||
title: search,
|
||||
});
|
||||
const loading = isFetching || isRefetching || isLoading;
|
||||
const handleInputSearch = useDebouncedCallback(setSearch, 300);
|
||||
|
||||
const handleSelect = (conversation: ChatConversation) => {
|
||||
router.push(`/chat/${conversation.id}`);
|
||||
modalProps.onClose?.();
|
||||
};
|
||||
|
||||
const conversationsData: QuickSearchData<ChatConversation> = useMemo(() => {
|
||||
const conversations = data?.pages.flatMap((page) => page.results) || [];
|
||||
|
||||
return {
|
||||
groupName: conversations.length > 0 ? t('Select a conversation') : '',
|
||||
elements: search ? conversations : [],
|
||||
emptyString: t('No conversation found'),
|
||||
endActions: hasNextPage
|
||||
? [{ content: <InView onChange={() => void fetchNextPage()} /> }]
|
||||
: [],
|
||||
};
|
||||
}, [data, hasNextPage, fetchNextPage, t, search]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
{...modalProps}
|
||||
closeOnClickOutside
|
||||
size={isDesktop ? ModalSize.LARGE : ModalSize.FULL}
|
||||
>
|
||||
<Box
|
||||
aria-label={t('Search modal')}
|
||||
$direction="column"
|
||||
$justify="space-between"
|
||||
className="--docs--doc-search-modal"
|
||||
>
|
||||
<QuickSearch
|
||||
placeholder={t('Type the name of a conversation')}
|
||||
loading={loading}
|
||||
onFilter={handleInputSearch}
|
||||
>
|
||||
<Box $height={isDesktop ? '500px' : 'calc(100vh - 68px - 1rem)'}>
|
||||
{search.length === 0 && (
|
||||
<Box
|
||||
$direction="column"
|
||||
$height="100%"
|
||||
$align="center"
|
||||
$justify="center"
|
||||
>
|
||||
<Image
|
||||
className="c__image-system-filter"
|
||||
width={320}
|
||||
src={EmptySearchIcon}
|
||||
alt={t('No active search')}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{search && (
|
||||
<QuickSearchGroup
|
||||
onSelect={handleSelect}
|
||||
group={conversationsData}
|
||||
renderElement={(conversation) => (
|
||||
<ConversationSearchItem conversation={conversation} />
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</QuickSearch>
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export * from './ConversationSearchModal';
|
||||
@@ -1 +0,0 @@
|
||||
export * from './components';
|
||||
@@ -14,6 +14,14 @@ const fetchAPIAdapter = (input: RequestInfo | URL, init?: RequestInit) => {
|
||||
} else {
|
||||
throw new Error('Unsupported input type for fetchAPIAdapter');
|
||||
}
|
||||
|
||||
// Add force_web_search parameter if it's globally enabled
|
||||
if ((window as { globalForceWebSearch?: boolean }).globalForceWebSearch) {
|
||||
const urlObj = new URL(url);
|
||||
urlObj.searchParams.set('force_web_search', 'true');
|
||||
url = urlObj.toString();
|
||||
}
|
||||
|
||||
return fetchAPI(url, init);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,26 +4,27 @@ import {
|
||||
SourceUIPart,
|
||||
ToolInvocationUIPart,
|
||||
} from '@ai-sdk/ui-utils';
|
||||
import { Loader, Modal, ModalSize } from '@openfun/cunningham-react';
|
||||
import { Modal, ModalSize } from '@openfun/cunningham-react';
|
||||
import 'katex/dist/katex.min.css'; // `rehype-katex` does not import the CSS for you
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Markdown from 'react-markdown';
|
||||
import rehypeKatex from 'rehype-katex';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkMath from 'remark-math';
|
||||
|
||||
import { Box, BoxButton, Icon, Text } from '@/components';
|
||||
import { DropdownMenu } from '@/components/DropdownMenu';
|
||||
import { useConfig } from '@/core';
|
||||
import { useAuth } from '@/features/auth';
|
||||
import { APIError, errorCauses, fetchAPI } from '@/api';
|
||||
import { Box, Icon, Loader, Text } from '@/components';
|
||||
import { useChat } from '@/features/chat/api/useChat';
|
||||
import { getConversation } from '@/features/chat/api/useConversation';
|
||||
import { useCreateChatConversation } from '@/features/chat/api/useCreateConversation';
|
||||
import SourceItemList from '@/features/chat/components/SourceItemList';
|
||||
import { InputChat } from '@/features/chat/components/InputChat';
|
||||
import { SourceItemList } from '@/features/chat/components/SourceItemList';
|
||||
import { ToolInvocationItem } from '@/features/chat/components/ToolInvocationItem';
|
||||
import { setChatContainerRef } from '@/features/chat/hooks/useChatScroll';
|
||||
import { useClipboard } from '@/hook';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { usePendingChatStore } from '../stores/usePendingChatStore';
|
||||
|
||||
@@ -40,28 +41,39 @@ export const Chat = ({
|
||||
initialConversationId: string | undefined;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const copyToClipboard = useClipboard();
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
|
||||
const streamProtocol = 'data'; // or 'text'
|
||||
const [forceWebSearch, setForceWebSearch] = useState(false);
|
||||
const apiUrl = `chats/${initialConversationId}/conversation/?protocol=${streamProtocol}`;
|
||||
|
||||
const router = useRouter();
|
||||
const { user } = useAuth();
|
||||
const { data: conf } = useConfig();
|
||||
const [files, setFiles] = useState<FileList | null>(null);
|
||||
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [isDragActive, setIsDragActive] = useState(false);
|
||||
const chatContainerRef = useRef<HTMLDivElement>(null);
|
||||
const [conversationId, setConversationId] = useState(initialConversationId);
|
||||
const [chatErrorModal, setChatErrorModal] = useState<{
|
||||
title: string;
|
||||
message: string;
|
||||
} | null>(null);
|
||||
const [isSourceOpen, setIsSourceOpen] = useState<string | null>(null);
|
||||
|
||||
// Définir la ref globale pour le hook useChatScroll
|
||||
useEffect(() => {
|
||||
setChatContainerRef(chatContainerRef);
|
||||
}, []);
|
||||
|
||||
const [initialConversationMessages, setInitialConversationMessages] =
|
||||
useState<Message[] | undefined>(undefined);
|
||||
const [pendingFirstMessage, setPendingFirstMessage] = useState<{
|
||||
event: React.FormEvent<HTMLFormElement>;
|
||||
attachments?: FileList | null;
|
||||
forceWebSearch?: boolean;
|
||||
} | null>(null);
|
||||
const [shouldAutoSubmit, setShouldAutoSubmit] = useState(false);
|
||||
const [hasInitialized, setHasInitialized] = useState(false);
|
||||
|
||||
const { mutate: createChatConversation } = useCreateChatConversation();
|
||||
|
||||
@@ -90,6 +102,7 @@ export const Chat = ({
|
||||
handleSubmit: baseHandleSubmit,
|
||||
handleInputChange,
|
||||
status,
|
||||
stop: stopChat,
|
||||
} = useChat({
|
||||
id: conversationId,
|
||||
initialMessages: initialConversationMessages,
|
||||
@@ -99,10 +112,104 @@ export const Chat = ({
|
||||
onError: onErrorChat,
|
||||
});
|
||||
|
||||
// Scroll to bottom when new messages arrive
|
||||
const scrollToBottom = useCallback(() => {
|
||||
if (chatContainerRef.current) {
|
||||
chatContainerRef.current.scrollTo({
|
||||
top: chatContainerRef.current.scrollHeight,
|
||||
behavior: hasInitialized ? 'smooth' : 'auto',
|
||||
});
|
||||
}
|
||||
}, [hasInitialized]);
|
||||
|
||||
const stopGeneration = async () => {
|
||||
stopChat();
|
||||
|
||||
const response = await fetchAPI(`chats/${conversationId}/stop-steaming/`, {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new APIError(
|
||||
'Failed to stop the conversation',
|
||||
await errorCauses(response),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleWebSearch = () => {
|
||||
setForceWebSearch((prev) => {
|
||||
const newValue = !prev;
|
||||
// Update global state for the fetch adapter
|
||||
(window as { globalForceWebSearch?: boolean }).globalForceWebSearch =
|
||||
newValue;
|
||||
return newValue;
|
||||
});
|
||||
};
|
||||
|
||||
const handleStop = () => {
|
||||
void stopGeneration();
|
||||
};
|
||||
|
||||
const handleSubmitWrapper = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
void handleSubmit(event);
|
||||
};
|
||||
|
||||
const openSources = (messageId: string) => {
|
||||
if (isSourceOpen === messageId) {
|
||||
setIsSourceOpen(null);
|
||||
return;
|
||||
}
|
||||
const message = messages.find((msg) => msg.id === messageId);
|
||||
if (message?.parts) {
|
||||
const sourceParts = message.parts.filter(
|
||||
(part): part is SourceUIPart => part.type === 'source',
|
||||
);
|
||||
if (sourceParts.length > 0) {
|
||||
setIsSourceOpen(messageId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (chatContainerRef.current) {
|
||||
// Find the last user message
|
||||
const userMessages = messages.filter((msg) => msg.role === 'user');
|
||||
const lastUserMessage = userMessages[userMessages.length - 1];
|
||||
|
||||
if (lastUserMessage) {
|
||||
// Find the element of the last user message
|
||||
const messageElements =
|
||||
chatContainerRef.current.querySelectorAll('[data-message-id]');
|
||||
const lastUserMessageElement = Array.from(messageElements).find(
|
||||
(el) => el.getAttribute('data-message-id') === lastUserMessage.id,
|
||||
);
|
||||
|
||||
if (lastUserMessageElement) {
|
||||
// Scroll to position the last user message at the very top
|
||||
const messageTop = (lastUserMessageElement as HTMLElement).offsetTop;
|
||||
|
||||
chatContainerRef.current.scrollTo({
|
||||
top: messageTop,
|
||||
behavior: 'auto',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
scrollToBottom();
|
||||
}
|
||||
}
|
||||
}, [messages, hasInitialized, scrollToBottom]);
|
||||
|
||||
// Synchronize conversationId state with prop when it changes (e.g., after navigation)
|
||||
useEffect(() => {
|
||||
setConversationId(initialConversationId);
|
||||
}, [initialConversationId]);
|
||||
// Reset input when conversation changes
|
||||
if (initialConversationId !== conversationId) {
|
||||
handleInputChange({
|
||||
target: { value: '' },
|
||||
} as React.ChangeEvent<HTMLTextAreaElement>);
|
||||
}
|
||||
}, [initialConversationId, conversationId, handleInputChange]);
|
||||
|
||||
// On mount, if there is pending input/files, initialize state and set flag
|
||||
useEffect(() => {
|
||||
@@ -136,7 +243,7 @@ export const Chat = ({
|
||||
preventDefault: () => {},
|
||||
target: form,
|
||||
} as unknown as React.FormEvent<HTMLFormElement>;
|
||||
handleSubmit(syntheticFormEvent);
|
||||
void handleSubmit(syntheticFormEvent);
|
||||
setShouldAutoSubmit(false);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -153,11 +260,13 @@ export const Chat = ({
|
||||
});
|
||||
if (!ignore) {
|
||||
setInitialConversationMessages(conversation.messages);
|
||||
setHasInitialized(true);
|
||||
}
|
||||
} catch {
|
||||
// Optionally handle error (e.g., setInitialConversationMessages([]) or show error)
|
||||
if (!ignore) {
|
||||
setInitialConversationMessages([]);
|
||||
setHasInitialized(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,11 +279,32 @@ export const Chat = ({
|
||||
}, [initialConversationId, pendingInput]);
|
||||
|
||||
// Custom handleSubmit to include attachments and handle chat creation
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
// Convert files to base64 if they exist
|
||||
let attachments: Attachment[] = [];
|
||||
if (files && files.length > 0) {
|
||||
attachments = await Promise.all(
|
||||
Array.from(files).map(async (file) => {
|
||||
return new Promise<Attachment>((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
resolve({
|
||||
name: file.name,
|
||||
contentType: file.type,
|
||||
url: reader.result as string,
|
||||
});
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (!conversationId) {
|
||||
// Save the event and files, then create the chat
|
||||
setPendingFirstMessage({ event, attachments: files });
|
||||
setPendingFirstMessage({ event, attachments: files, forceWebSearch });
|
||||
// Save input and files to Zustand store before navigation
|
||||
setPendingChat(input, files);
|
||||
void createChatConversation(
|
||||
@@ -187,13 +317,18 @@ export const Chat = ({
|
||||
// After setting the conversationId, submit the pending message
|
||||
setTimeout(() => {
|
||||
if (pendingFirstMessage) {
|
||||
// Prepare options with attachments
|
||||
const options: Record<string, unknown> = {};
|
||||
if (
|
||||
pendingFirstMessage.attachments &&
|
||||
pendingFirstMessage.attachments.length > 0
|
||||
) {
|
||||
baseHandleSubmit(pendingFirstMessage.event, {
|
||||
experimental_attachments: pendingFirstMessage.attachments,
|
||||
});
|
||||
options.experimental_attachments =
|
||||
pendingFirstMessage.attachments;
|
||||
}
|
||||
|
||||
if (Object.keys(options).length > 0) {
|
||||
baseHandleSubmit(pendingFirstMessage.event, options);
|
||||
} else {
|
||||
baseHandleSubmit(pendingFirstMessage.event);
|
||||
}
|
||||
@@ -209,132 +344,290 @@ export const Chat = ({
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (files && files.length > 0) {
|
||||
baseHandleSubmit(event, { experimental_attachments: files });
|
||||
|
||||
// Prepare options with attachments
|
||||
const options: Record<string, unknown> = {};
|
||||
if (attachments.length > 0) {
|
||||
options.experimental_attachments = attachments;
|
||||
}
|
||||
|
||||
if (Object.keys(options).length > 0) {
|
||||
baseHandleSubmit(event, options);
|
||||
} else {
|
||||
baseHandleSubmit(event);
|
||||
}
|
||||
setFiles(null);
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = '';
|
||||
}
|
||||
|
||||
// Attendre un peu avant de vider les fichiers pour s'assurer qu'ils sont traités
|
||||
setTimeout(() => {
|
||||
setFiles(null);
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = '';
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box $direction="column" $height="100%" $width="100%">
|
||||
<Box
|
||||
$direction="column"
|
||||
$width="100%"
|
||||
$css={`
|
||||
flex-basis: auto;
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Box
|
||||
$direction="column"
|
||||
ref={chatContainerRef}
|
||||
$gap="1rem"
|
||||
$padding={{ all: 'base' }}
|
||||
$padding={{ all: 'base', left: '13px', bottom: '0', right: '0' }}
|
||||
$width="100%"
|
||||
$flex={1}
|
||||
$overflow="auto"
|
||||
$overflow="scroll"
|
||||
$css={`
|
||||
flex-basis: auto;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
margin-bottom: 0;
|
||||
height: ${messages.length > 1 ? 'calc(100vh - 62px)' : '0'};
|
||||
max-height: ${messages.length > 1 ? 'calc(100vh - 62px)' : '0'};
|
||||
`}
|
||||
>
|
||||
{messages.map((message) => (
|
||||
<Box key={message.id} $direction="row" $gap="1rem">
|
||||
<Text
|
||||
$color="var(--c--theme--colors--greyscale-500)"
|
||||
$minWidth="80px"
|
||||
$variation="600"
|
||||
>
|
||||
{`${message.role === 'user' ? user?.full_name : message.role}:`}
|
||||
</Text>
|
||||
<Box $direction="column" $gap="2">
|
||||
{message.content && (
|
||||
<Markdown
|
||||
remarkPlugins={[remarkGfm, remarkMath]}
|
||||
rehypePlugins={[rehypeKatex]}
|
||||
components={{
|
||||
// Custom components for Markdown rendering
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
p: ({ node, ...props }) => (
|
||||
<Text $display="inline" {...props} />
|
||||
),
|
||||
}}
|
||||
{messages.length > 0 && (
|
||||
<Box>
|
||||
{messages.map((message) => (
|
||||
<Box
|
||||
key={message.id}
|
||||
data-message-id={message.id}
|
||||
$css={`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
padding-left: 12px;
|
||||
max-width: 750px;
|
||||
text-align: ${message.role === 'user' ? 'right' : 'left'};
|
||||
flex-direction: ${message.role === 'user' ? 'row-reverse' : 'row'};
|
||||
`}
|
||||
>
|
||||
<Box
|
||||
$gap="2"
|
||||
$radius="8px"
|
||||
$padding={`${message.role === 'user' ? '12px' : '0'}`}
|
||||
$margin={{ vertical: 'base' }}
|
||||
$background={`${message.role === 'user' ? '#EEF1F4' : 'white'}`}
|
||||
>
|
||||
{message.content}
|
||||
</Markdown>
|
||||
)}
|
||||
<Box $direction="column">
|
||||
{message.parts
|
||||
?.filter(
|
||||
(part) =>
|
||||
part.type === 'reasoning' ||
|
||||
part.type === 'tool-invocation',
|
||||
)
|
||||
.map((part: ReasoningUIPart | ToolInvocationUIPart) =>
|
||||
part.type === 'reasoning' ? (
|
||||
<Box
|
||||
key={part.reasoning}
|
||||
$background="var(--c--theme--colors--greyscale-100)"
|
||||
$color="var(--c--theme--colors--greyscale-500)"
|
||||
$padding={{ all: 'sm' }}
|
||||
$radius="md"
|
||||
$css="font-size: 0.9em;"
|
||||
>
|
||||
{part.reasoning}
|
||||
</Box>
|
||||
) : part.type === 'tool-invocation' ? (
|
||||
<ToolInvocationItem
|
||||
toolInvocation={part.toolInvocation}
|
||||
/>
|
||||
) : null,
|
||||
{message.content && (
|
||||
<Markdown
|
||||
remarkPlugins={[remarkGfm, remarkMath]}
|
||||
rehypePlugins={[rehypeKatex]}
|
||||
components={{
|
||||
// Custom components for Markdown rendering
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
p: ({ node, ...props }) => <Text {...props} />,
|
||||
}}
|
||||
>
|
||||
{message.content}
|
||||
</Markdown>
|
||||
)}
|
||||
{/* Show attachments if present */}
|
||||
{message.experimental_attachments?.map(
|
||||
(attachment: Attachment, index: number) =>
|
||||
attachment.contentType?.includes('image/') ? (
|
||||
<Image
|
||||
key={`${message.id}-${index}`}
|
||||
style={{ width: 96, borderRadius: 8 }}
|
||||
src={attachment.url}
|
||||
alt={attachment.name || ''}
|
||||
width={96}
|
||||
height={96}
|
||||
/>
|
||||
) : attachment.contentType?.includes('text/') ? (
|
||||
<div
|
||||
key={`${message.id}-${index}`}
|
||||
style={{
|
||||
width: 128,
|
||||
height: 96,
|
||||
padding: 8,
|
||||
overflow: 'hidden',
|
||||
fontSize: 12,
|
||||
border: '1px solid #eee',
|
||||
borderRadius: 8,
|
||||
color: '#888',
|
||||
}}
|
||||
>
|
||||
{attachment.url}
|
||||
</div>
|
||||
) : null,
|
||||
)}
|
||||
{/* Show sources if present */}
|
||||
{message.parts && (
|
||||
<SourceItemList
|
||||
parts={message.parts.filter(
|
||||
(part): part is SourceUIPart => part.type === 'source',
|
||||
<Box $direction="column" $gap="2">
|
||||
{message.parts
|
||||
?.filter(
|
||||
(part) =>
|
||||
part.type === 'reasoning' ||
|
||||
part.type === 'tool-invocation',
|
||||
)
|
||||
.map((part: ReasoningUIPart | ToolInvocationUIPart) =>
|
||||
part.type === 'reasoning' ? (
|
||||
<Box
|
||||
key={part.reasoning}
|
||||
$background="var(--c--theme--colors--greyscale-100)"
|
||||
$color="var(--c--theme--colors--greyscale-500)"
|
||||
$padding={{ all: 'sm' }}
|
||||
$radius="md"
|
||||
$css="font-size: 0.9em;"
|
||||
>
|
||||
{part.reasoning}
|
||||
</Box>
|
||||
) : part.type === 'tool-invocation' ? (
|
||||
<ToolInvocationItem
|
||||
toolInvocation={part.toolInvocation}
|
||||
/>
|
||||
) : null,
|
||||
)}
|
||||
{/* Show attachments if present */}
|
||||
{message.experimental_attachments?.map(
|
||||
(attachment: Attachment, index: number) =>
|
||||
attachment.contentType?.includes('text/') ||
|
||||
attachment.contentType?.includes('image/') ? (
|
||||
<div
|
||||
key={`${message.id}-${index}`}
|
||||
style={{
|
||||
display: 'block',
|
||||
width: 'auto',
|
||||
fontSize: 12,
|
||||
borderRadius: 8,
|
||||
color: '#888',
|
||||
}}
|
||||
>
|
||||
{attachment.name}
|
||||
</div>
|
||||
) : null,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
{message.role !== 'user' && (
|
||||
<Box
|
||||
$css="color: #626A80; font-size: 12px;"
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$gap="6px"
|
||||
$margin={{ top: 'base' }}
|
||||
>
|
||||
<Box
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$gap="4px"
|
||||
$css="
|
||||
cursor: pointer;
|
||||
z-index: 100;
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
margin-left: -8px;
|
||||
transition: background-color 0.4s;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: #EEF1F4 !important;
|
||||
}
|
||||
"
|
||||
onClick={() => copyToClipboard(message.content)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
copyToClipboard(message.content);
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<Icon
|
||||
iconName="content_copy"
|
||||
$theme="greyscale"
|
||||
$variation="600"
|
||||
$size="16px"
|
||||
/>
|
||||
{isDesktop && (
|
||||
<Text $color="#626A80" $weight="500">
|
||||
{t('Copy')}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
{message.parts?.some(
|
||||
(part) => part.type === 'source',
|
||||
) && (
|
||||
<Box
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$gap="4px"
|
||||
$css="
|
||||
cursor: pointer;
|
||||
z-index: 100;
|
||||
font-size: 12px;
|
||||
padding: 2px 8px;
|
||||
margin-left: -8px;
|
||||
transition: background-color 0.4s;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: #EEF1F4 !important;
|
||||
}
|
||||
"
|
||||
onClick={() => openSources(message.id)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
openSources(message.id);
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<Icon
|
||||
iconName="book"
|
||||
$theme="greyscale"
|
||||
$variation="600"
|
||||
$size="16px"
|
||||
/>
|
||||
{isDesktop && (
|
||||
<Text $color="#626A80" $weight="500">
|
||||
{t('Show sources')}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
{message.parts && isSourceOpen === message.id && (
|
||||
<SourceItemList
|
||||
parts={message.parts.filter(
|
||||
(part): part is SourceUIPart => part.type === 'source',
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
))}
|
||||
)}
|
||||
{(status === 'streaming' || status === 'submitted') && (
|
||||
<Box
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$justify="center"
|
||||
$gap="1rem"
|
||||
$margin={{ top: 'base' }}
|
||||
$gap="6px"
|
||||
$width="100%"
|
||||
$maxWidth="750px"
|
||||
$margin={{ all: 'auto', top: 'base', bottom: 'md' }}
|
||||
$padding={{ left: '13px' }}
|
||||
>
|
||||
<Loader size="small" />
|
||||
<Text $variation="600">{t('Generating...')}</Text>
|
||||
<Loader />
|
||||
<Text $variation="600" $size="md">
|
||||
{t('Thinking...')}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
$css={`
|
||||
position: relative;
|
||||
bottom: 20px;
|
||||
margin: auto;
|
||||
`}
|
||||
$gap="6px"
|
||||
$height="auto"
|
||||
$width="100%"
|
||||
$margin={{ all: 'auto', top: 'base' }}
|
||||
>
|
||||
<InputChat
|
||||
messagesLength={messages.length}
|
||||
input={input}
|
||||
handleInputChange={handleInputChange}
|
||||
handleSubmit={handleSubmitWrapper}
|
||||
status={status}
|
||||
files={files}
|
||||
setFiles={setFiles}
|
||||
onScrollToBottom={scrollToBottom}
|
||||
containerRef={chatContainerRef}
|
||||
onStop={handleStop}
|
||||
forceWebSearch={forceWebSearch}
|
||||
onToggleWebSearch={toggleWebSearch}
|
||||
/>
|
||||
</Box>
|
||||
<Modal
|
||||
isOpen={!!chatErrorModal}
|
||||
onClose={() => {
|
||||
@@ -348,253 +641,6 @@ export const Chat = ({
|
||||
>
|
||||
<Text>{chatErrorModal?.message}</Text>
|
||||
</Modal>
|
||||
|
||||
{messages.length === 0 && (
|
||||
<Box
|
||||
$padding={{ all: 'base' }}
|
||||
$background="white"
|
||||
$radius="md"
|
||||
$css="box-shadow: 0 2px 8px rgba(0,0,0,0.04);"
|
||||
$margin={{ horizontal: 'base', bottom: 'base' }}
|
||||
>
|
||||
<Text as="h2" $size="lg" $weight="600" $margin={{ bottom: 'xs' }}>
|
||||
{t('Welcome to your assistant!')}
|
||||
</Text>
|
||||
<Text $color="var(--c--theme--colors--greyscale-600)">
|
||||
{t('Start a conversation by typing a message below.')}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* File preview */}
|
||||
{files && files.length > 0 && (
|
||||
<Box
|
||||
$direction="row"
|
||||
$gap="2"
|
||||
$align="center"
|
||||
$margin={{ horizontal: 'base', bottom: 'xs' }}
|
||||
>
|
||||
{Array.from(files).map((file, idx) => {
|
||||
const { type, name } = file;
|
||||
const removeFile = () => {
|
||||
if (!files) {
|
||||
return;
|
||||
}
|
||||
const dt = new DataTransfer();
|
||||
Array.from(files).forEach((f, i) => {
|
||||
if (i !== idx) {
|
||||
dt.items.add(f);
|
||||
}
|
||||
});
|
||||
setFiles(dt.files.length > 0 ? dt.files : null);
|
||||
};
|
||||
if (type.startsWith('image/')) {
|
||||
return (
|
||||
<Box
|
||||
key={name + idx}
|
||||
$direction="column"
|
||||
$align="center"
|
||||
$gap="xs"
|
||||
>
|
||||
<Image
|
||||
style={{ width: 96, borderRadius: 8 }}
|
||||
src={URL.createObjectURL(file)}
|
||||
alt={name}
|
||||
width={96}
|
||||
height={96}
|
||||
/>
|
||||
<Text
|
||||
$size="sm"
|
||||
$color="var(--c--theme--colors--greyscale-500)"
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
<BoxButton
|
||||
aria-label="Remove file"
|
||||
onClick={removeFile}
|
||||
$css="margin-top: 0.25rem;"
|
||||
>
|
||||
<Icon iconName="close" $theme="greyscale" $size="18px" />
|
||||
</BoxButton>
|
||||
</Box>
|
||||
);
|
||||
} else if (type.startsWith('text/')) {
|
||||
return (
|
||||
<Box
|
||||
key={name + idx}
|
||||
$direction="column"
|
||||
$align="center"
|
||||
$gap="xs"
|
||||
>
|
||||
<Box
|
||||
$background="var(--c--theme--colors--greyscale-100)"
|
||||
$width="64px"
|
||||
$height="80px"
|
||||
$radius="md"
|
||||
/>
|
||||
<Text
|
||||
$size="sm"
|
||||
$color="var(--c--theme--colors--greyscale-500)"
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
<BoxButton
|
||||
aria-label="Remove file"
|
||||
onClick={removeFile}
|
||||
$css="margin-top: 0.25rem;"
|
||||
>
|
||||
<Icon iconName="close" $theme="greyscale" $size="18px" />
|
||||
</BoxButton>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
style={{ width: '100%' }}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(true);
|
||||
}}
|
||||
onDragLeave={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(false);
|
||||
}}
|
||||
onDrop={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(false);
|
||||
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
||||
setFiles((prev) => {
|
||||
if (!prev || prev.length === 0) {
|
||||
return e.dataTransfer.files;
|
||||
}
|
||||
const dt = new DataTransfer();
|
||||
Array.from(prev).forEach((f) => dt.items.add(f));
|
||||
Array.from(e.dataTransfer.files).forEach((f) => {
|
||||
if (
|
||||
!Array.from(prev).some(
|
||||
(pf) =>
|
||||
pf.name === f.name &&
|
||||
pf.size === f.size &&
|
||||
pf.lastModified === f.lastModified,
|
||||
)
|
||||
) {
|
||||
dt.items.add(f);
|
||||
}
|
||||
});
|
||||
return dt.files;
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
$direction="row"
|
||||
$gap="2"
|
||||
$align="center"
|
||||
$padding={{ all: 'base' }}
|
||||
$background="white"
|
||||
$css="border-top: 1px solid var(--c--theme--colors--greyscale-200);"
|
||||
>
|
||||
<Box
|
||||
$flex={1}
|
||||
$css={
|
||||
isDragActive
|
||||
? 'border: 2px dashed var(--c--theme--colors--primary-400); background: var(--c--theme--colors--primary-050);'
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<textarea
|
||||
value={input}
|
||||
placeholder={t('Type your message here...')}
|
||||
onChange={handleInputChange}
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '1rem',
|
||||
background: 'transparent',
|
||||
outline: 'none',
|
||||
border: '1px solid var(--c--theme--colors--greyscale-200)',
|
||||
borderRadius: '0.5rem',
|
||||
fontFamily: 'inherit',
|
||||
}}
|
||||
disabled={status !== 'ready'}
|
||||
rows={1}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.ctrlKey && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
// Find the form and submit it
|
||||
const form = e.currentTarget.form;
|
||||
if (form) {
|
||||
form.requestSubmit?.();
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
<DropdownMenu
|
||||
options={[
|
||||
{
|
||||
icon: 'attach_file',
|
||||
label: 'Attach files',
|
||||
callback: () => {
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.click();
|
||||
}
|
||||
},
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Icon
|
||||
iconName="attach_file"
|
||||
$theme="primary"
|
||||
$variation="800"
|
||||
$size="24px"
|
||||
/>
|
||||
</DropdownMenu>
|
||||
<input
|
||||
type="file"
|
||||
onChange={(event) => {
|
||||
const fileList = event.target.files;
|
||||
if (fileList && fileList.length > 0) {
|
||||
setFiles((prev) => {
|
||||
if (!prev || prev.length === 0) {
|
||||
return fileList;
|
||||
}
|
||||
const dt = new DataTransfer();
|
||||
Array.from(prev).forEach((f) => dt.items.add(f));
|
||||
Array.from(fileList).forEach((f) => {
|
||||
if (
|
||||
!Array.from(prev).some(
|
||||
(pf) =>
|
||||
pf.name === f.name &&
|
||||
pf.size === f.size &&
|
||||
pf.lastModified === f.lastModified,
|
||||
)
|
||||
) {
|
||||
dt.items.add(f);
|
||||
}
|
||||
});
|
||||
return dt.files;
|
||||
});
|
||||
}
|
||||
}}
|
||||
multiple
|
||||
ref={fileInputRef}
|
||||
style={{ display: 'none' }}
|
||||
accept={conf?.chat_upload_accept}
|
||||
/>
|
||||
<BoxButton
|
||||
aria-label="Send"
|
||||
disabled={status !== 'ready' || !input.trim()}
|
||||
$css="margin-left: 0.5rem;"
|
||||
>
|
||||
<Icon iconName="send" $theme="primary" $variation="800" />
|
||||
</BoxButton>
|
||||
</Box>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,473 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Box, BoxButton, Icon, Text } from '@/components';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { ScrollDown } from './ScrollDown';
|
||||
import { SendButton } from './SendButton';
|
||||
|
||||
interface InputChatProps {
|
||||
messagesLength: number;
|
||||
input: string | null;
|
||||
handleInputChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
||||
handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
||||
status: string | null;
|
||||
files: FileList | null;
|
||||
setFiles: React.Dispatch<React.SetStateAction<FileList | null>>;
|
||||
onScrollToBottom?: () => void;
|
||||
containerRef?: React.RefObject<HTMLDivElement | null>;
|
||||
forceWebSearch?: boolean;
|
||||
onToggleWebSearch?: () => void;
|
||||
onStop?: () => void;
|
||||
}
|
||||
|
||||
export const InputChat = ({
|
||||
messagesLength,
|
||||
input,
|
||||
handleInputChange,
|
||||
handleSubmit,
|
||||
status,
|
||||
files,
|
||||
setFiles,
|
||||
onScrollToBottom,
|
||||
containerRef,
|
||||
forceWebSearch = false,
|
||||
onToggleWebSearch,
|
||||
onStop,
|
||||
}: InputChatProps) => {
|
||||
const { t } = useTranslation();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [isDragActive, setIsDragActive] = useState(false);
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const [currentSuggestionIndex, setCurrentSuggestionIndex] = useState(0);
|
||||
|
||||
const suggestions = [
|
||||
'Turn this list into bullet points',
|
||||
'Write a short product description',
|
||||
'Find recent news about...',
|
||||
'Ask a question',
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
if (messagesLength === 0) {
|
||||
const interval = setInterval(() => {
|
||||
setCurrentSuggestionIndex((prev) => (prev + 1) % suggestions.length);
|
||||
}, 3000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, [messagesLength, suggestions.length]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
$css={`
|
||||
display: block;
|
||||
position: relative;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
padding: ${isDesktop ? '0' : '0 10px'};
|
||||
max-width: 750px;
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes fadeInDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@keyframes slideOutToBottom {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
}
|
||||
`}
|
||||
>
|
||||
{/* Bouton de scroll vers le bas */}
|
||||
{messagesLength > 1 && containerRef && (
|
||||
<Box
|
||||
$css={`
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
max-width: 750px;
|
||||
opacity: ${onScrollToBottom ? '1' : '0'};
|
||||
transition: opacity 0.4s;
|
||||
`}
|
||||
>
|
||||
<ScrollDown
|
||||
onClick={onScrollToBottom || (() => {})}
|
||||
containerRef={containerRef}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{/* Message de bienvenue */}
|
||||
{messagesLength === 0 && (
|
||||
<Box
|
||||
$padding={{ all: 'base', bottom: 'md' }}
|
||||
$background="white"
|
||||
$align="center"
|
||||
$margin={{ horizontal: 'base', bottom: 'md', top: '0' }}
|
||||
$css={`
|
||||
opacity: 0;
|
||||
animation: fadeIn 0.2s cubic-bezier(1,0,0,1) 0.2s both;
|
||||
`}
|
||||
>
|
||||
<Text as="h2" $size="xl" $weight="600" $margin={{ all: '0' }}>
|
||||
{t('What is on your mind?')}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(true);
|
||||
}}
|
||||
onDragLeave={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(false);
|
||||
}}
|
||||
onDrop={(e) => {
|
||||
e.preventDefault();
|
||||
setIsDragActive(false);
|
||||
if (e.dataTransfer.files?.length) {
|
||||
setFiles((prev) => {
|
||||
const dt = new DataTransfer();
|
||||
if (prev) {
|
||||
Array.from(prev).forEach((f) => dt.items.add(f));
|
||||
}
|
||||
Array.from(e.dataTransfer.files).forEach((f) => {
|
||||
if (
|
||||
!Array.from(prev || []).some(
|
||||
(pf) =>
|
||||
pf.name === f.name &&
|
||||
pf.size === f.size &&
|
||||
pf.lastModified === f.lastModified,
|
||||
)
|
||||
) {
|
||||
dt.items.add(f);
|
||||
}
|
||||
});
|
||||
return dt.files;
|
||||
});
|
||||
}
|
||||
}}
|
||||
style={{ width: '100%' }}
|
||||
>
|
||||
<Box
|
||||
$padding={{ bottom: `${isDesktop ? 'base' : ''}` }}
|
||||
$background="white"
|
||||
$css={
|
||||
messagesLength === 0
|
||||
? `
|
||||
opacity: 0;
|
||||
animation: fadeIn 0.4s cubic-bezier(1,0,0,1) 0s both;
|
||||
`
|
||||
: 'animation: fadeIn 0.4s cubic-bezier(1,0,0,1) 0.4s both;'
|
||||
}
|
||||
>
|
||||
<Box
|
||||
$flex={1}
|
||||
$css={`
|
||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.05);
|
||||
border-radius: 0.5rem;
|
||||
border: ${
|
||||
isDragActive
|
||||
? '2px dashed var(--c--theme--colors--primary-400)'
|
||||
: '1px solid var(--c--theme--colors--greyscale-200)'
|
||||
};
|
||||
position: relative;
|
||||
`}
|
||||
>
|
||||
<textarea
|
||||
value={input ?? ''}
|
||||
name="inputchat-textarea"
|
||||
placeholder={
|
||||
messagesLength === 0
|
||||
? suggestions[currentSuggestionIndex]
|
||||
: t('Ask a question')
|
||||
}
|
||||
onChange={(e) => {
|
||||
handleInputChange(e);
|
||||
const textarea = e.target as HTMLTextAreaElement;
|
||||
textarea.style.height = 'auto';
|
||||
const newHeight = Math.min(textarea.scrollHeight, 200);
|
||||
textarea.style.height = `${newHeight}px`;
|
||||
}}
|
||||
disabled={status !== 'ready'}
|
||||
rows={1}
|
||||
style={{
|
||||
padding: '1rem 1.5rem',
|
||||
background: 'transparent',
|
||||
outline: 'none',
|
||||
fontSize: '1rem',
|
||||
border: 'none',
|
||||
resize: 'none',
|
||||
fontFamily: 'inherit',
|
||||
minHeight: '60px',
|
||||
maxHeight: '200px',
|
||||
overflowY: 'auto',
|
||||
transition: 'all 0.3s ease',
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.ctrlKey && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
const textarea = e.target as HTMLTextAreaElement;
|
||||
textarea.style.height = '0';
|
||||
e.currentTarget.form?.requestSubmit?.();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{messagesLength === 0 && !input && (
|
||||
<Box
|
||||
$css={`
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
left: 1.5rem;
|
||||
right: 1.5rem;
|
||||
pointer-events: none;
|
||||
color: var(--c--theme--colors--greyscale-500);
|
||||
font-size: 1rem;
|
||||
font-family: inherit;
|
||||
line-height: 1.5;
|
||||
`}
|
||||
>
|
||||
{suggestions.map((suggestion, index) => (
|
||||
<Box
|
||||
key={index}
|
||||
$css={`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
opacity: ${index === currentSuggestionIndex ? 1 : 0};
|
||||
&::placeholder {
|
||||
transition: opacity ${index === currentSuggestionIndex ? '0.4s' : '0s'};
|
||||
}
|
||||
`}
|
||||
>
|
||||
{suggestion}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
ref={fileInputRef}
|
||||
style={{ display: 'none' }}
|
||||
onChange={(e) => {
|
||||
const fileList = e.target.files;
|
||||
if (!fileList) {
|
||||
return;
|
||||
}
|
||||
console.log(fileList);
|
||||
setFiles((prev) => {
|
||||
const dt = new DataTransfer();
|
||||
if (prev) {
|
||||
Array.from(prev).forEach((f: File) => dt.items.add(f));
|
||||
}
|
||||
Array.from(fileList).forEach((f: File) => {
|
||||
if (
|
||||
!Array.from(prev || []).some(
|
||||
(pf) =>
|
||||
pf.name === f.name &&
|
||||
pf.size === f.size &&
|
||||
pf.lastModified === f.lastModified,
|
||||
)
|
||||
) {
|
||||
dt.items.add(f);
|
||||
}
|
||||
});
|
||||
return dt.files;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{/*Aperçu des fichiers*/}
|
||||
{files && files.length > 0 && (
|
||||
<Box
|
||||
$direction="row"
|
||||
$gap="0.5rem"
|
||||
$width="100%"
|
||||
$css={`
|
||||
overflow-x: scroll;
|
||||
`}
|
||||
$margin={{ horizontal: '0', bottom: 'xs', top: 'xs' }}
|
||||
$padding={{ horizontal: 'base' }}
|
||||
>
|
||||
{Array.from(files).map((file, idx) => {
|
||||
const { type: _type, name } = file;
|
||||
const removeFile = () => {
|
||||
const dt = new DataTransfer();
|
||||
Array.from(files).forEach((f, i) => {
|
||||
if (i !== idx) {
|
||||
dt.items.add(f);
|
||||
}
|
||||
});
|
||||
setFiles(dt.files.length > 0 ? dt.files : null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
key={name + idx}
|
||||
$direction="column"
|
||||
$align="center"
|
||||
$gap="xs"
|
||||
>
|
||||
{/*{type.startsWith('image/') ? (
|
||||
<Image
|
||||
style={{ width: 96, borderRadius: 8 }}
|
||||
src={URL.createObjectURL(file)}
|
||||
alt={name}
|
||||
width={96}
|
||||
height={96}
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
$background="var(--c--theme--colors--greyscale-100)"
|
||||
$width="64px"
|
||||
$height="80px"
|
||||
$radius="md"
|
||||
/>
|
||||
)}*/}
|
||||
<Box
|
||||
$background="var(--c--theme--colors--greyscale-050)"
|
||||
$width="200px"
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$padding="xs"
|
||||
$css={`
|
||||
border: 1px solid var(--c--theme--colors--greyscale-200);
|
||||
border-radius: 8px;
|
||||
|
||||
`}
|
||||
>
|
||||
<Text
|
||||
$size="sm"
|
||||
$color="var(--c--theme--colors--greyscale-850)"
|
||||
$css={`
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: initial;
|
||||
display: -webkit-box;
|
||||
line-clamp: 1;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
`}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
<BoxButton
|
||||
aria-label="Remove file"
|
||||
onClick={removeFile}
|
||||
>
|
||||
<Icon
|
||||
iconName="close"
|
||||
$theme="greyscale"
|
||||
$size="18px"
|
||||
/>
|
||||
</BoxButton>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
)}
|
||||
<Box
|
||||
$flex="1"
|
||||
$direction="row"
|
||||
$padding={{ bottom: 'base' }}
|
||||
$align="space-between"
|
||||
>
|
||||
<Box $flex="1" $direction="row" $padding={{ horizontal: 'base' }}>
|
||||
<Button
|
||||
size="small"
|
||||
type="button"
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
aria-label={t('Add attach file')}
|
||||
color="tertiary-text"
|
||||
icon={
|
||||
<Icon
|
||||
iconName="attach_file"
|
||||
$theme="greyscale"
|
||||
$variation="600"
|
||||
$size="24px"
|
||||
/>
|
||||
}
|
||||
>
|
||||
{isDesktop && <Text $weight="500">{t('Attach file')}</Text>}
|
||||
</Button>
|
||||
{onToggleWebSearch && (
|
||||
<Box
|
||||
$css={
|
||||
forceWebSearch
|
||||
? `
|
||||
.c__button {
|
||||
background-color: var(--c--theme--colors--primary-100) !important;
|
||||
}
|
||||
`
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<Button
|
||||
size="small"
|
||||
type="button"
|
||||
onClick={onToggleWebSearch}
|
||||
aria-label={t('Research on the web')}
|
||||
color="tertiary-text"
|
||||
icon={
|
||||
<Icon
|
||||
iconName="language"
|
||||
$theme={forceWebSearch ? 'primary' : 'greyscale'}
|
||||
$variation={forceWebSearch ? '800' : '600'}
|
||||
$size="24px"
|
||||
/>
|
||||
}
|
||||
>
|
||||
{isDesktop && (
|
||||
<Text
|
||||
$color={forceWebSearch ? 'primary' : 'greyscale'}
|
||||
$weight="500"
|
||||
>
|
||||
{t('Research on the web')}
|
||||
</Text>
|
||||
)}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
<Box $padding={{ horizontal: 'sm' }}>
|
||||
<SendButton
|
||||
status={status}
|
||||
disabled={!input || !input.trim()}
|
||||
onClick={onStop}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</form>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { Box, Icon } from '@/components';
|
||||
|
||||
interface ScrollDownProps {
|
||||
onClick: () => void;
|
||||
containerRef: React.RefObject<HTMLDivElement | null>;
|
||||
}
|
||||
|
||||
export const ScrollDown: React.FC<ScrollDownProps> = ({
|
||||
onClick,
|
||||
containerRef,
|
||||
}) => {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
if (containerRef.current) {
|
||||
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
||||
const isAtBottom = scrollTop + clientHeight >= scrollHeight;
|
||||
setIsVisible(!isAtBottom);
|
||||
}
|
||||
};
|
||||
|
||||
const container = containerRef.current;
|
||||
if (container) {
|
||||
container.addEventListener('scroll', handleScroll, { passive: true });
|
||||
setTimeout(handleScroll, 100);
|
||||
|
||||
return () => container.removeEventListener('scroll', handleScroll);
|
||||
}
|
||||
}, [containerRef]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
$css={`
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1000;
|
||||
opacity: ${isVisible ? '1' : '0'};
|
||||
transition: opacity 0.3s ease;
|
||||
animation: fadeIn 0.3s ease;
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
className="c__button--bordered"
|
||||
aria-label="See more"
|
||||
onClick={onClick}
|
||||
icon={
|
||||
<Icon $variation="800" $theme="primary" iconName="arrow_downward" />
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Box, Icon, Text } from '@/components';
|
||||
|
||||
interface SendButtonProps {
|
||||
status: string | null;
|
||||
disabled?: boolean;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export const SendButton = ({
|
||||
status,
|
||||
disabled = false,
|
||||
onClick,
|
||||
}: SendButtonProps) => {
|
||||
const { t } = useTranslation();
|
||||
const isStopMode = status === 'submitted' || status === 'streaming';
|
||||
console.log(status);
|
||||
|
||||
return (
|
||||
<>
|
||||
{status === 'error' ? (
|
||||
<Box
|
||||
$css={`
|
||||
font-size: 14px;
|
||||
font-style: italic;
|
||||
`}
|
||||
>
|
||||
<Text $color="greyscale" $weight="500" $variation="500">
|
||||
{t('An error occurred. Please try again.')}
|
||||
</Text>
|
||||
</Box>
|
||||
) : (
|
||||
<Button
|
||||
size="small"
|
||||
type={status === 'ready' ? 'submit' : 'button'}
|
||||
aria-label={status === 'ready' ? t('Send') : t('Stop')}
|
||||
disabled={(disabled && !isStopMode) || status === 'error'}
|
||||
color="primary"
|
||||
onClick={isStopMode && onClick ? onClick : undefined}
|
||||
icon={
|
||||
<Icon
|
||||
$variation={isStopMode ? '100' : '800'}
|
||||
$theme={isStopMode ? 'greyscale' : 'primary-text'}
|
||||
iconName={status === 'ready' ? 'arrow_upward' : 'crop_square'}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{isStopMode && <Text $color="white">{t('Stop')}</Text>}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -5,7 +5,8 @@ import { Box, StyledLink } from '@/components';
|
||||
|
||||
const styles: Record<string, React.CSSProperties> = {
|
||||
title: {
|
||||
color: 'var(--c-gray-700, #495057)',
|
||||
color: '#222631',
|
||||
fontWeight: '500',
|
||||
whiteSpace: 'nowrap',
|
||||
},
|
||||
};
|
||||
@@ -14,7 +15,7 @@ interface SourceItemProps {
|
||||
url: string;
|
||||
}
|
||||
|
||||
const SourceItem: React.FC<SourceItemProps> = ({ url }) => {
|
||||
export const SourceItem: React.FC<SourceItemProps> = ({ url }) => {
|
||||
const [title, setTitle] = useState<string | null>(null);
|
||||
const [favicon, setFavicon] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -35,12 +36,35 @@ const SourceItem: React.FC<SourceItemProps> = ({ url }) => {
|
||||
// We should ideally have a backend endpoint for this
|
||||
// but for demonstration, we'll use a simplified approach
|
||||
const parser = new DOMParser();
|
||||
const response = await fetch(url, { mode: 'cors' });
|
||||
|
||||
// Try to fetch with CORS, but handle errors gracefully
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(url, {
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (compatible; ChatBot/1.0)',
|
||||
},
|
||||
});
|
||||
} catch {
|
||||
console.log('CORS fetch failed, using fallback for:', url);
|
||||
// If CORS fails, just use the URL as title
|
||||
setTitle(new URL(url).hostname);
|
||||
setFavicon(null);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}`);
|
||||
}
|
||||
|
||||
const html = await response.text();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
|
||||
// Get the title
|
||||
const pageTitle = doc.querySelector('title')?.textContent || url;
|
||||
const pageTitle =
|
||||
doc.querySelector('title')?.textContent || new URL(url).hostname;
|
||||
setTitle(pageTitle);
|
||||
|
||||
// Get the favicon
|
||||
@@ -63,9 +87,9 @@ const SourceItem: React.FC<SourceItemProps> = ({ url }) => {
|
||||
|
||||
setFavicon(faviconUrl || null);
|
||||
} catch (err) {
|
||||
console.error('Error fetching metadata:', err);
|
||||
console.log('Error fetching metadata for:', url, err);
|
||||
setError(true);
|
||||
setTitle(url);
|
||||
setTitle(new URL(url).hostname);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -99,9 +123,9 @@ const SourceItem: React.FC<SourceItemProps> = ({ url }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Box $direction="row" $gap="0.25rem" $align="center">
|
||||
<Box $direction="row" $gap="4px" $align="center">
|
||||
{renderFavicon()}
|
||||
<Box $direction="row" $gap="0.25rem" $align="center">
|
||||
<Box $direction="row" $gap="4px" $align="center" $css="font-size: 14px;">
|
||||
{url.startsWith('http') ? (
|
||||
<StyledLink
|
||||
href={url}
|
||||
@@ -116,19 +140,22 @@ const SourceItem: React.FC<SourceItemProps> = ({ url }) => {
|
||||
`}
|
||||
>
|
||||
{new URL(url).hostname}
|
||||
|
||||
<Box
|
||||
$direction="row"
|
||||
$padding={{ left: '4px' }}
|
||||
$align="center"
|
||||
style={styles.title}
|
||||
>
|
||||
{title && title.length > 100
|
||||
? `${title.substring(0, 50)}...${title.substring(title.length - 20)}`
|
||||
: title}
|
||||
</Box>
|
||||
</StyledLink>
|
||||
) : (
|
||||
<Box>{url}</Box>
|
||||
)}
|
||||
<Box $direction="row" $align="center" style={styles.title}>
|
||||
{/* Need to better manage the text ellipsis */}
|
||||
{title && title.length > 100
|
||||
? `${title.substring(0, 50)}...${title.substring(title.length - 20)}`
|
||||
: title}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default SourceItem;
|
||||
|
||||
@@ -2,13 +2,13 @@ import { SourceUIPart } from '@ai-sdk/ui-utils';
|
||||
import React from 'react';
|
||||
|
||||
import { Box } from '@/components';
|
||||
import SourceItem from '@/features/chat/components/SourceItem';
|
||||
import { SourceItem } from '@/features/chat/components/SourceItem';
|
||||
|
||||
interface SourceItemListProps {
|
||||
parts: readonly SourceUIPart[];
|
||||
}
|
||||
|
||||
const SourceItemList: React.FC<SourceItemListProps> = ({ parts }) => {
|
||||
export const SourceItemList: React.FC<SourceItemListProps> = ({ parts }) => {
|
||||
if (parts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -16,13 +16,26 @@ const SourceItemList: React.FC<SourceItemListProps> = ({ parts }) => {
|
||||
return (
|
||||
<Box
|
||||
$direction="column"
|
||||
$gap="0.1rem"
|
||||
$padding="0.5rem"
|
||||
$background="var(--c-gray-100, #f8f9fa)"
|
||||
$padding={{ all: 'sm' }}
|
||||
$gap="4px"
|
||||
$css={`
|
||||
border: 1px solid var(--c--theme--colors--greyscale-200);
|
||||
border-radius: 8px;
|
||||
margin-top: 0.5rem;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
animation: slideInFade 0.3s ease-out forwards;
|
||||
|
||||
@keyframes slideInFade {
|
||||
from {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
`}
|
||||
>
|
||||
{parts.map((part) => (
|
||||
@@ -31,5 +44,3 @@ const SourceItemList: React.FC<SourceItemListProps> = ({ parts }) => {
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default SourceItemList;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { useChatScroll } from './useChatScroll';
|
||||
@@ -0,0 +1,47 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
// Ref globale pour le conteneur de chat
|
||||
let chatContainerRef: React.RefObject<HTMLDivElement | null> = {
|
||||
current: null,
|
||||
};
|
||||
|
||||
export const setChatContainerRef = (
|
||||
ref: React.RefObject<HTMLDivElement | null>,
|
||||
) => {
|
||||
chatContainerRef = ref;
|
||||
console.log('Chat container ref set:', ref.current);
|
||||
};
|
||||
|
||||
export const useChatScroll = () => {
|
||||
const [isAtTop, setIsAtTop] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
if (chatContainerRef.current) {
|
||||
const scrollTop = chatContainerRef.current.scrollTop;
|
||||
const newIsAtTop = scrollTop <= 0;
|
||||
console.log('Scroll detected:', scrollTop, 'isAtTop:', newIsAtTop);
|
||||
setIsAtTop(newIsAtTop);
|
||||
}
|
||||
};
|
||||
|
||||
// Vérifier si le conteneur existe
|
||||
if (chatContainerRef.current) {
|
||||
console.log('Setting up scroll listener for container');
|
||||
const container = chatContainerRef.current;
|
||||
container.addEventListener('scroll', handleScroll, { passive: true });
|
||||
|
||||
// Vérifier la position initiale
|
||||
handleScroll();
|
||||
|
||||
return () => {
|
||||
console.log('Removing scroll listener');
|
||||
container.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
} else {
|
||||
console.log('No chat container found');
|
||||
}
|
||||
}, []);
|
||||
|
||||
return { isAtTop };
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import LeftPanelIcon from '@/assets/icons/left-panel-bold.svg';
|
||||
import { useLeftPanelStore } from '@/features/left-panel';
|
||||
|
||||
export const ButtonToggleLeftPanel = () => {
|
||||
const { t } = useTranslation();
|
||||
const { isPanelOpen: _isPanelOpen, togglePanel } = useLeftPanelStore();
|
||||
|
||||
return (
|
||||
<Button
|
||||
size="medium"
|
||||
onClick={() => togglePanel()}
|
||||
aria-label={t('Open the header menu')}
|
||||
color="tertiary-text"
|
||||
icon={<LeftPanelIcon />}
|
||||
className="--docs--button-toggle-panel"
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -14,13 +14,7 @@ export const ButtonTogglePanel = () => {
|
||||
onClick={() => togglePanel()}
|
||||
aria-label={t('Open the header menu')}
|
||||
color="tertiary-text"
|
||||
icon={
|
||||
<Icon
|
||||
$variation="800"
|
||||
$theme="primary"
|
||||
iconName={isPanelOpen ? 'close' : 'menu'}
|
||||
/>
|
||||
}
|
||||
icon={<Icon $theme="primary" iconName={isPanelOpen ? 'close' : 'menu'} />}
|
||||
className="--docs--button-toggle-panel"
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,68 +1,94 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect as _useEffect, useState as _useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import IconDocs from '@/assets/icons/icon-docs.svg';
|
||||
import NewChatIcon from '@/assets/icons/new-message-bold.svg';
|
||||
import Logo from '@/assets/logo/logo-assistant.svg';
|
||||
import { Box, StyledLink } from '@/components/';
|
||||
import { productName } from '@/core';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { ButtonLogin } from '@/features/auth';
|
||||
import { useChatScroll } from '@/features/chat/hooks';
|
||||
import { LanguagePicker } from '@/features/language';
|
||||
import { useLeftPanelStore } from '@/features/left-panel/stores';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { HEADER_HEIGHT } from '../conf';
|
||||
|
||||
import { ButtonToggleLeftPanel } from './ButtonToggleLeftPanel';
|
||||
import { ButtonTogglePanel } from './ButtonTogglePanel';
|
||||
import { LaGaufre } from './LaGaufre';
|
||||
import { Title } from './Title';
|
||||
|
||||
export const Header = () => {
|
||||
const { t } = useTranslation();
|
||||
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const { togglePanel } = useLeftPanelStore();
|
||||
const { isAtTop } = useChatScroll();
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<Box
|
||||
as="header"
|
||||
$css={css`
|
||||
position: fixed;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: ${HEADER_HEIGHT}px;
|
||||
height: ${isDesktop ? HEADER_HEIGHT : '52'}px;
|
||||
padding: 0 ${spacingsTokens['base']};
|
||||
background-color: ${colorsTokens['greyscale-000']};
|
||||
border-bottom: 1px solid ${colorsTokens['greyscale-200']};
|
||||
border-bottom: ${isDesktop && isAtTop
|
||||
? `1px solid transparent`
|
||||
: `1px solid ${colorsTokens['greyscale-200']}`};
|
||||
transition: border-bottom 0.2s ease;
|
||||
`}
|
||||
className="--docs--header"
|
||||
>
|
||||
{!isDesktop && <ButtonTogglePanel />}
|
||||
<StyledLink href="/">
|
||||
<Box
|
||||
$align="center"
|
||||
$gap={spacingsTokens['3xs']}
|
||||
$direction="row"
|
||||
$position="relative"
|
||||
$height="fit-content"
|
||||
$margin={{ top: 'auto' }}
|
||||
>
|
||||
<IconDocs
|
||||
<Box
|
||||
$align="center"
|
||||
$gap={spacingsTokens['xs']}
|
||||
$direction="row"
|
||||
$position="relative"
|
||||
$height="fit-content"
|
||||
>
|
||||
{isDesktop && <ButtonToggleLeftPanel />}
|
||||
<StyledLink href="/">
|
||||
<Logo
|
||||
aria-label={t('{{productName}} Logo', { productName })}
|
||||
width={32}
|
||||
width={188}
|
||||
color={colorsTokens['primary-text']}
|
||||
/>
|
||||
<Title />
|
||||
</Box>
|
||||
</StyledLink>
|
||||
</StyledLink>
|
||||
</Box>
|
||||
{!isDesktop ? (
|
||||
<Box $direction="row" $gap={spacingsTokens['sm']}>
|
||||
<LaGaufre />
|
||||
<Button
|
||||
size="medium"
|
||||
onClick={() => {
|
||||
router.push('/');
|
||||
togglePanel(false);
|
||||
}}
|
||||
aria-label={t('New chat')}
|
||||
color="primary-text"
|
||||
icon={<NewChatIcon />}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
<Box $align="center" $gap={spacingsTokens['sm']} $direction="row">
|
||||
<Box
|
||||
$align="center"
|
||||
$gap={spacingsTokens['sm']}
|
||||
$direction="row"
|
||||
$css={css`
|
||||
height: '52px';
|
||||
`}
|
||||
>
|
||||
<ButtonLogin />
|
||||
<LanguagePicker />
|
||||
<LaGaufre />
|
||||
|
||||
@@ -9,6 +9,16 @@ import { useCunninghamTheme } from '@/cunningham';
|
||||
const GaufreStyle = createGlobalStyle`
|
||||
.lasuite-gaufre-btn{
|
||||
box-shadow: inset 0 0 0 0 !important;
|
||||
border-radius: 4px !important;
|
||||
&:focus {
|
||||
box-shadow: box-shadow: inset 0 0 0 0 !important;
|
||||
}
|
||||
.lasuite-gaufre-btn.lasuite--gaufre-opened {
|
||||
box-shadow: box-shadow: inset 0 0 0 0 !important;
|
||||
}
|
||||
&:before {
|
||||
background-color: #304DDF !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const HEADER_HEIGHT = 52;
|
||||
export const HEADER_HEIGHT = 65;
|
||||
|
||||
|
Before Width: | Height: | Size: 407 KiB |
@@ -0,0 +1,213 @@
|
||||
<svg width="471" height="470" viewBox="0 0 471 470" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_12246_5573)" filter="url(#filter0_n_12246_5573)">
|
||||
<g clip-path="url(#clip1_12246_5573)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M337.127 28.3754C430.353 72.9816 458.816 188.662 438.308 290.043C419.834 381.368 342.416 446.884 250.058 458.804C163.028 470.037 80.2623 420.577 43.1799 341.041C8.70873 267.106 -0.103391 201.696 55.8013 142.231C121.752 72.0802 250.346 -13.1469 337.127 28.3754Z" fill="#EBEEF2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M337.127 28.3754C430.353 72.9816 458.816 188.662 438.308 290.043C419.834 381.368 342.416 446.884 250.058 458.804C163.028 470.037 80.2623 420.577 43.1799 341.041C8.70873 267.106 -0.103391 201.696 55.8013 142.231C121.752 72.0802 250.346 -13.1469 337.127 28.3754Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M405.228 367.015C370.166 416.975 313.654 450.595 250.058 458.804C172.946 468.756 99.183 431.061 57.5776 367.015H405.228Z" fill="#626B81"/>
|
||||
<path d="M405.228 367.015C370.166 416.975 313.654 450.595 250.058 458.804C172.946 468.756 99.183 431.061 57.5776 367.015H405.228Z" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
</g>
|
||||
<path d="M359.943 265.412C362.615 265.412 364.781 267.578 364.781 270.25V293.381C365.432 297.21 367.477 300.937 372.265 302.336C373.009 302.553 372.963 303.615 372.187 303.602C369.178 303.55 365.58 303.455 364.532 303.285C363.408 303.102 362.383 302.796 361.458 302.38C360.981 302.538 360.473 302.625 359.943 302.625H167.073C164.401 302.625 162.235 300.459 162.235 297.787V270.25C162.236 267.578 164.401 265.412 167.073 265.412H359.943Z" fill="#626B81"/>
|
||||
<path d="M359.943 265.412C362.615 265.412 364.781 267.578 364.781 270.25V293.381C365.432 297.21 367.477 300.937 372.265 302.336C373.009 302.553 372.963 303.615 372.187 303.602C369.178 303.55 365.58 303.455 364.532 303.285C363.408 303.102 362.383 302.796 361.458 302.38C360.981 302.538 360.473 302.625 359.943 302.625H167.073C164.401 302.625 162.235 300.459 162.235 297.787V270.25C162.236 267.578 164.401 265.412 167.073 265.412H359.943Z" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path d="M359.943 265.412L359.943 264.893H359.943V265.412ZM364.781 270.25H365.3V270.25L364.781 270.25ZM364.781 293.381H364.263V293.425L364.27 293.468L364.781 293.381ZM372.265 302.336L372.41 301.838L372.41 301.838L372.265 302.336ZM372.187 303.602L372.179 304.12L372.179 304.12L372.187 303.602ZM364.532 303.285L364.449 303.796L364.449 303.796L364.532 303.285ZM361.458 302.38L361.67 301.908L361.487 301.825L361.296 301.888L361.458 302.38ZM359.943 302.625V303.143H359.943L359.943 302.625ZM167.073 302.625L167.073 303.143H167.073V302.625ZM162.235 297.787H161.717V297.787L162.235 297.787ZM162.235 270.25L161.717 270.25V270.25H162.235ZM167.073 265.412V264.893H167.073L167.073 265.412ZM359.943 265.412L359.943 265.93C362.329 265.93 364.263 267.864 364.263 270.25L364.781 270.25L365.3 270.25C365.299 267.292 362.902 264.893 359.943 264.893L359.943 265.412ZM364.781 270.25H364.263V293.381H364.781H365.3V270.25H364.781ZM364.781 293.381L364.27 293.468C364.942 297.421 367.081 301.361 372.119 302.833L372.265 302.336L372.41 301.838C367.874 300.512 365.921 296.998 365.292 293.295L364.781 293.381ZM372.265 302.336L372.119 302.833C372.19 302.854 372.226 302.888 372.247 302.918C372.27 302.953 372.28 302.993 372.278 303.028C372.278 303.044 372.274 303.056 372.271 303.063C372.27 303.067 372.268 303.069 372.267 303.071C372.267 303.072 372.266 303.072 372.266 303.073C372.266 303.073 372.266 303.073 372.265 303.073C372.265 303.073 372.263 303.075 372.259 303.076C372.252 303.079 372.233 303.084 372.196 303.084L372.187 303.602L372.179 304.12C372.498 304.126 372.786 304.017 372.997 303.808C373.201 303.605 373.3 303.339 373.314 303.083C373.341 302.569 373.03 302.019 372.41 301.838L372.265 302.336ZM372.187 303.602L372.196 303.084C370.693 303.058 369.045 303.021 367.643 302.97C366.227 302.918 365.101 302.852 364.615 302.773L364.532 303.285L364.449 303.796C365.012 303.888 366.209 303.955 367.605 304.006C369.017 304.058 370.673 304.095 372.179 304.12L372.187 303.602ZM364.532 303.285L364.615 302.773C363.532 302.597 362.552 302.304 361.67 301.908L361.458 302.38L361.245 302.853C362.215 303.289 363.283 303.607 364.449 303.796L364.532 303.285ZM361.458 302.38L361.296 301.888C360.869 302.029 360.415 302.106 359.943 302.106L359.943 302.625L359.943 303.143C360.53 303.143 361.093 303.046 361.62 302.873L361.458 302.38ZM359.943 302.625V302.106H167.073V302.625V303.143H359.943V302.625ZM167.073 302.625L167.073 302.106C164.688 302.106 162.754 300.172 162.754 297.787L162.235 297.787L161.717 297.787C161.717 300.745 164.115 303.143 167.073 303.143L167.073 302.625ZM162.235 297.787H162.754V270.25H162.235H161.717V297.787H162.235ZM162.235 270.25L162.754 270.25C162.754 267.864 164.688 265.93 167.073 265.93L167.073 265.412L167.073 264.893C164.115 264.893 161.717 267.292 161.717 270.25L162.235 270.25ZM167.073 265.412V265.93H359.943V265.412V264.893H167.073V265.412Z" fill="#626B81"/>
|
||||
<path d="M359.943 265.412L359.943 264.893H359.943V265.412ZM364.781 270.25H365.3V270.25L364.781 270.25ZM364.781 293.381H364.263V293.425L364.27 293.468L364.781 293.381ZM372.265 302.336L372.41 301.838L372.41 301.838L372.265 302.336ZM372.187 303.602L372.179 304.12L372.179 304.12L372.187 303.602ZM364.532 303.285L364.449 303.796L364.449 303.796L364.532 303.285ZM361.458 302.38L361.67 301.908L361.487 301.825L361.296 301.888L361.458 302.38ZM359.943 302.625V303.143H359.943L359.943 302.625ZM167.073 302.625L167.073 303.143H167.073V302.625ZM162.235 297.787H161.717V297.787L162.235 297.787ZM162.235 270.25L161.717 270.25V270.25H162.235ZM167.073 265.412V264.893H167.073L167.073 265.412ZM359.943 265.412L359.943 265.93C362.329 265.93 364.263 267.864 364.263 270.25L364.781 270.25L365.3 270.25C365.299 267.292 362.902 264.893 359.943 264.893L359.943 265.412ZM364.781 270.25H364.263V293.381H364.781H365.3V270.25H364.781ZM364.781 293.381L364.27 293.468C364.942 297.421 367.081 301.361 372.119 302.833L372.265 302.336L372.41 301.838C367.874 300.512 365.921 296.998 365.292 293.295L364.781 293.381ZM372.265 302.336L372.119 302.833C372.19 302.854 372.226 302.888 372.247 302.918C372.27 302.953 372.28 302.993 372.278 303.028C372.278 303.044 372.274 303.056 372.271 303.063C372.27 303.067 372.268 303.069 372.267 303.071C372.267 303.072 372.266 303.072 372.266 303.073C372.266 303.073 372.266 303.073 372.265 303.073C372.265 303.073 372.263 303.075 372.259 303.076C372.252 303.079 372.233 303.084 372.196 303.084L372.187 303.602L372.179 304.12C372.498 304.126 372.786 304.017 372.997 303.808C373.201 303.605 373.3 303.339 373.314 303.083C373.341 302.569 373.03 302.019 372.41 301.838L372.265 302.336ZM372.187 303.602L372.196 303.084C370.693 303.058 369.045 303.021 367.643 302.97C366.227 302.918 365.101 302.852 364.615 302.773L364.532 303.285L364.449 303.796C365.012 303.888 366.209 303.955 367.605 304.006C369.017 304.058 370.673 304.095 372.179 304.12L372.187 303.602ZM364.532 303.285L364.615 302.773C363.532 302.597 362.552 302.304 361.67 301.908L361.458 302.38L361.245 302.853C362.215 303.289 363.283 303.607 364.449 303.796L364.532 303.285ZM361.458 302.38L361.296 301.888C360.869 302.029 360.415 302.106 359.943 302.106L359.943 302.625L359.943 303.143C360.53 303.143 361.093 303.046 361.62 302.873L361.458 302.38ZM359.943 302.625V302.106H167.073V302.625V303.143H359.943V302.625ZM167.073 302.625L167.073 302.106C164.688 302.106 162.754 300.172 162.754 297.787L162.235 297.787L161.717 297.787C161.717 300.745 164.115 303.143 167.073 303.143L167.073 302.625ZM162.235 297.787H162.754V270.25H162.235H161.717V297.787H162.235ZM162.235 270.25L162.754 270.25C162.754 267.864 164.688 265.93 167.073 265.93L167.073 265.412L167.073 264.893C164.115 264.893 161.717 267.292 161.717 270.25L162.235 270.25ZM167.073 265.412V265.93H359.943V265.412V264.893H167.073V265.412Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M307.147 290.642C307.911 290.642 308.53 291.261 308.53 292.025V293.055C308.53 293.818 307.911 294.438 307.147 294.438H177.156C176.393 294.438 175.773 293.818 175.773 293.055V292.025C175.773 291.261 176.393 290.642 177.156 290.642H307.147ZM349.862 282.12C350.626 282.12 351.244 282.74 351.244 283.503V284.533C351.244 285.297 350.626 285.916 349.862 285.916H177.156C176.393 285.916 175.773 285.297 175.773 284.533V283.503C175.773 282.74 176.393 282.12 177.156 282.12H349.862ZM349.862 273.599C350.626 273.599 351.244 274.218 351.244 274.982V276.012C351.244 276.775 350.626 277.395 349.862 277.395H177.156C176.393 277.395 175.773 276.775 175.773 276.012V274.982C175.773 274.218 176.393 273.599 177.156 273.599H349.862Z" fill="#626B81"/>
|
||||
<path d="M307.147 290.642C307.911 290.642 308.53 291.261 308.53 292.025V293.055C308.53 293.818 307.911 294.438 307.147 294.438H177.156C176.393 294.438 175.773 293.818 175.773 293.055V292.025C175.773 291.261 176.393 290.642 177.156 290.642H307.147ZM349.862 282.12C350.626 282.12 351.244 282.74 351.244 283.503V284.533C351.244 285.297 350.626 285.916 349.862 285.916H177.156C176.393 285.916 175.773 285.297 175.773 284.533V283.503C175.773 282.74 176.393 282.12 177.156 282.12H349.862ZM349.862 273.599C350.626 273.599 351.244 274.218 351.244 274.982V276.012C351.244 276.775 350.626 277.395 349.862 277.395H177.156C176.393 277.395 175.773 276.775 175.773 276.012V274.982C175.773 274.218 176.393 273.599 177.156 273.599H349.862Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<mask id="path-6-inside-1_12246_5573" fill="white">
|
||||
<path d="M364.782 78.7941C367.454 78.7941 369.619 80.96 369.619 83.632V146.161C370.27 149.99 372.316 153.717 377.103 155.115C377.847 155.333 377.801 156.395 377.026 156.382C374.017 156.33 370.419 156.234 369.37 156.064C368.246 155.881 367.223 155.575 366.298 155.159C365.821 155.317 365.312 155.404 364.782 155.404H171.911C169.24 155.404 167.074 153.238 167.074 150.566V83.632C167.074 80.9602 169.24 78.7943 171.911 78.7941H364.782Z"/>
|
||||
</mask>
|
||||
<path d="M364.782 78.7941C367.454 78.7941 369.619 80.96 369.619 83.632V146.161C370.27 149.99 372.316 153.717 377.103 155.115C377.847 155.333 377.801 156.395 377.026 156.382C374.017 156.33 370.419 156.234 369.37 156.064C368.246 155.881 367.223 155.575 366.298 155.159C365.821 155.317 365.312 155.404 364.782 155.404H171.911C169.24 155.404 167.074 153.238 167.074 150.566V83.632C167.074 80.9602 169.24 78.7943 171.911 78.7941H364.782Z" fill="#626B81"/>
|
||||
<path d="M364.782 78.7941C367.454 78.7941 369.619 80.96 369.619 83.632V146.161C370.27 149.99 372.316 153.717 377.103 155.115C377.847 155.333 377.801 156.395 377.026 156.382C374.017 156.33 370.419 156.234 369.37 156.064C368.246 155.881 367.223 155.575 366.298 155.159C365.821 155.317 365.312 155.404 364.782 155.404H171.911C169.24 155.404 167.074 153.238 167.074 150.566V83.632C167.074 80.9602 169.24 78.7943 171.911 78.7941H364.782Z" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path d="M369.619 83.632H370.656V83.6319L369.619 83.632ZM369.619 146.161H368.583V146.249L368.597 146.335L369.619 146.161ZM377.103 155.115L377.394 154.12L377.394 154.12L377.103 155.115ZM377.026 156.382L377.008 157.419L377.009 157.419L377.026 156.382ZM369.37 156.064L369.204 157.087L369.204 157.087L369.37 156.064ZM366.298 155.159L366.723 154.214L366.356 154.049L365.973 154.175L366.298 155.159ZM171.911 155.404L171.911 156.441H171.911V155.404ZM167.074 83.632L166.037 83.6319V83.632H167.074ZM171.911 78.7941V77.7573H171.911L171.911 78.7941ZM364.782 78.7941V79.8308C366.881 79.8308 368.583 81.5326 368.583 83.632L369.619 83.632L370.656 83.6319C370.656 80.3875 368.026 77.7573 364.782 77.7573V78.7941ZM369.619 83.632H368.583V146.161H369.619H370.656V83.632H369.619ZM369.619 146.161L368.597 146.335C369.29 150.412 371.523 154.565 376.812 156.111L377.103 155.115L377.394 154.12C373.109 152.868 371.25 149.567 370.642 145.988L369.619 146.161ZM377.103 155.115L376.812 156.11C376.689 156.075 376.591 155.934 376.599 155.78C376.603 155.704 376.635 155.588 376.739 155.485C376.855 155.369 376.985 155.344 377.043 155.345L377.026 156.382L377.009 157.419C377.454 157.426 377.881 157.273 378.2 156.955C378.508 156.65 378.65 156.257 378.67 155.89C378.709 155.154 378.261 154.374 377.394 154.12L377.103 155.115ZM377.026 156.382L377.044 155.345C375.542 155.32 373.898 155.283 372.501 155.231C371.074 155.178 369.984 155.113 369.536 155.04L369.37 156.064L369.204 157.087C369.805 157.184 371.038 157.252 372.425 157.303C373.841 157.355 375.501 157.393 377.008 157.419L377.026 156.382ZM369.37 156.064L369.537 155.04C368.496 154.871 367.56 154.59 366.723 154.214L366.298 155.159L365.873 156.105C366.886 156.56 367.997 156.891 369.204 157.087L369.37 156.064ZM366.298 155.159L365.973 154.175C365.596 154.299 365.196 154.368 364.782 154.368V155.404V156.441C365.427 156.441 366.046 156.334 366.623 156.144L366.298 155.159ZM364.782 155.404V154.368H171.911V155.404V156.441H364.782V155.404ZM171.911 155.404L171.912 154.368C169.812 154.368 168.11 152.665 168.11 150.566H167.074H166.037C166.037 153.81 168.667 156.441 171.911 156.441L171.911 155.404ZM167.074 150.566H168.11V83.632H167.074H166.037V150.566H167.074ZM167.074 83.632L168.11 83.632C168.11 81.5328 169.812 79.831 171.912 79.8308L171.911 78.7941L171.911 77.7573C168.667 77.7575 166.037 80.3875 166.037 83.6319L167.074 83.632ZM171.911 78.7941V79.8308H364.782V78.7941V77.7573H171.911V78.7941Z" fill="#626B81" mask="url(#path-6-inside-1_12246_5573)"/>
|
||||
<path d="M369.619 83.632H370.656V83.6319L369.619 83.632ZM369.619 146.161H368.583V146.249L368.597 146.335L369.619 146.161ZM377.103 155.115L377.394 154.12L377.394 154.12L377.103 155.115ZM377.026 156.382L377.008 157.419L377.009 157.419L377.026 156.382ZM369.37 156.064L369.204 157.087L369.204 157.087L369.37 156.064ZM366.298 155.159L366.723 154.214L366.356 154.049L365.973 154.175L366.298 155.159ZM171.911 155.404L171.911 156.441H171.911V155.404ZM167.074 83.632L166.037 83.6319V83.632H167.074ZM171.911 78.7941V77.7573H171.911L171.911 78.7941ZM364.782 78.7941V79.8308C366.881 79.8308 368.583 81.5326 368.583 83.632L369.619 83.632L370.656 83.6319C370.656 80.3875 368.026 77.7573 364.782 77.7573V78.7941ZM369.619 83.632H368.583V146.161H369.619H370.656V83.632H369.619ZM369.619 146.161L368.597 146.335C369.29 150.412 371.523 154.565 376.812 156.111L377.103 155.115L377.394 154.12C373.109 152.868 371.25 149.567 370.642 145.988L369.619 146.161ZM377.103 155.115L376.812 156.11C376.689 156.075 376.591 155.934 376.599 155.78C376.603 155.704 376.635 155.588 376.739 155.485C376.855 155.369 376.985 155.344 377.043 155.345L377.026 156.382L377.009 157.419C377.454 157.426 377.881 157.273 378.2 156.955C378.508 156.65 378.65 156.257 378.67 155.89C378.709 155.154 378.261 154.374 377.394 154.12L377.103 155.115ZM377.026 156.382L377.044 155.345C375.542 155.32 373.898 155.283 372.501 155.231C371.074 155.178 369.984 155.113 369.536 155.04L369.37 156.064L369.204 157.087C369.805 157.184 371.038 157.252 372.425 157.303C373.841 157.355 375.501 157.393 377.008 157.419L377.026 156.382ZM369.37 156.064L369.537 155.04C368.496 154.871 367.56 154.59 366.723 154.214L366.298 155.159L365.873 156.105C366.886 156.56 367.997 156.891 369.204 157.087L369.37 156.064ZM366.298 155.159L365.973 154.175C365.596 154.299 365.196 154.368 364.782 154.368V155.404V156.441C365.427 156.441 366.046 156.334 366.623 156.144L366.298 155.159ZM364.782 155.404V154.368H171.911V155.404V156.441H364.782V155.404ZM171.911 155.404L171.912 154.368C169.812 154.368 168.11 152.665 168.11 150.566H167.074H166.037C166.037 153.81 168.667 156.441 171.911 156.441L171.911 155.404ZM167.074 150.566H168.11V83.632H167.074H166.037V150.566H167.074ZM167.074 83.632L168.11 83.632C168.11 81.5328 169.812 79.831 171.912 79.8308L171.911 78.7941L171.911 77.7573C168.667 77.7575 166.037 80.3875 166.037 83.6319L167.074 83.632ZM171.911 78.7941V79.8308H364.782V78.7941V77.7573H171.911V78.7941Z" fill="#F7F8FA" fill-opacity="0.75" mask="url(#path-6-inside-1_12246_5573)"/>
|
||||
<path d="M345.457 143.419C346.221 143.42 346.839 144.038 346.839 144.801V145.838C346.839 146.602 346.221 147.22 345.457 147.22H181.994C181.231 147.22 180.612 146.602 180.612 145.838V144.801C180.612 144.038 181.231 143.419 181.994 143.419H345.457ZM354.7 134.9C355.464 134.9 356.082 135.519 356.082 136.283V137.313C356.082 138.076 355.464 138.696 354.7 138.696H181.994C181.231 138.696 180.612 138.076 180.612 137.313V136.283C180.612 135.519 181.231 134.9 181.994 134.9H354.7Z" fill="#626B81"/>
|
||||
<path d="M345.457 143.419C346.221 143.42 346.839 144.038 346.839 144.801V145.838C346.839 146.602 346.221 147.22 345.457 147.22H181.994C181.231 147.22 180.612 146.602 180.612 145.838V144.801C180.612 144.038 181.231 143.419 181.994 143.419H345.457ZM354.7 134.9C355.464 134.9 356.082 135.519 356.082 136.283V137.313C356.082 138.076 355.464 138.696 354.7 138.696H181.994C181.231 138.696 180.612 138.076 180.612 137.313V136.283C180.612 135.519 181.231 134.9 181.994 134.9H354.7Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 127.982C180.612 128.746 181.23 129.365 181.994 129.365H354.7C355.464 129.365 356.083 128.746 356.083 127.982V126.951C356.083 126.188 355.464 125.569 354.7 125.569H181.994C181.23 125.569 180.612 126.188 180.612 126.951V127.982Z" fill="#626B81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 127.982C180.612 128.746 181.23 129.365 181.994 129.365H354.7C355.464 129.365 356.083 128.746 356.083 127.982V126.951C356.083 126.188 355.464 125.569 354.7 125.569H181.994C181.23 125.569 180.612 126.188 180.612 126.951V127.982Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 118.651C180.612 119.415 181.23 120.034 181.994 120.034H354.7C355.464 120.034 356.083 119.415 356.083 118.651V117.621C356.083 116.857 355.464 116.238 354.7 116.238H181.994C181.23 116.238 180.612 116.857 180.612 117.621V118.651Z" fill="#626B81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 118.651C180.612 119.415 181.23 120.034 181.994 120.034H354.7C355.464 120.034 356.083 119.415 356.083 118.651V117.621C356.083 116.857 355.464 116.238 354.7 116.238H181.994C181.23 116.238 180.612 116.857 180.612 117.621V118.651Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 99.9896C180.612 100.753 181.23 101.372 181.994 101.372H354.7C355.464 101.372 356.083 100.753 356.083 99.9896V98.9588C356.083 98.1953 355.464 97.5764 354.7 97.5764H181.994C181.23 97.5764 180.612 98.1953 180.612 98.9588V99.9896Z" fill="#626B81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 99.9896C180.612 100.753 181.23 101.372 181.994 101.372H354.7C355.464 101.372 356.083 100.753 356.083 99.9896V98.9588C356.083 98.1953 355.464 97.5764 354.7 97.5764H181.994C181.23 97.5764 180.612 98.1953 180.612 98.9588V99.9896Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 90.6587C180.612 91.4221 181.23 92.041 181.994 92.041H354.7C355.464 92.041 356.083 91.4221 356.083 90.6587V89.6278C356.083 88.8644 355.464 88.2455 354.7 88.2455H181.994C181.23 88.2455 180.612 88.8644 180.612 89.6278V90.6587Z" fill="#626B81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.612 90.6587C180.612 91.4221 181.23 92.041 181.994 92.041H354.7C355.464 92.041 356.083 91.4221 356.083 90.6587V89.6278C356.083 88.8644 355.464 88.2455 354.7 88.2455H181.994C181.23 88.2455 180.612 88.8644 180.612 89.6278V90.6587Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.551 109.206C180.551 109.969 181.17 110.588 181.934 110.588H263.838C264.602 110.588 265.221 109.969 265.221 109.206V108.169C265.221 107.406 264.602 106.787 263.838 106.787H181.934C181.17 106.787 180.551 107.406 180.551 108.169V109.206Z" fill="#626B81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.551 109.206C180.551 109.969 181.17 110.588 181.934 110.588H263.838C264.602 110.588 265.221 109.969 265.221 109.206V108.169C265.221 107.406 264.602 106.787 263.838 106.787H181.934C181.17 106.787 180.551 107.406 180.551 108.169V109.206Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path d="M306.376 176.596C309.048 176.596 311.214 178.762 311.214 181.433V244.221C311.214 246.893 309.048 249.058 306.376 249.058H113.506C110.835 249.058 108.669 246.892 108.668 244.221V181.433C108.669 178.762 110.835 176.596 113.506 176.596H306.376Z" fill="#626B81"/>
|
||||
<path d="M306.376 176.596C309.048 176.596 311.214 178.762 311.214 181.433V244.221C311.214 246.893 309.048 249.058 306.376 249.058H113.506C110.835 249.058 108.669 246.892 108.668 244.221V181.433C108.669 178.762 110.835 176.596 113.506 176.596H306.376Z" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path d="M311.214 181.433H311.733V181.433L311.214 181.433ZM311.214 244.221L311.733 244.221V244.221H311.214ZM113.506 249.058L113.506 249.577H113.506V249.058ZM108.668 244.221H108.15V244.221L108.668 244.221ZM108.668 181.433L108.15 181.433V181.433H108.668ZM113.506 176.596V176.077H113.506L113.506 176.596ZM306.376 176.596V177.114C308.762 177.114 310.696 179.048 310.696 181.434L311.214 181.433L311.733 181.433C311.733 178.475 309.335 176.077 306.376 176.077V176.596ZM311.214 181.433H310.696V244.221H311.214H311.733V181.433H311.214ZM311.214 244.221L310.696 244.221C310.696 246.606 308.762 248.54 306.376 248.54V249.058V249.577C309.335 249.577 311.733 247.179 311.733 244.221L311.214 244.221ZM306.376 249.058V248.54H113.506V249.058V249.577H306.376V249.058ZM113.506 249.058L113.506 248.54C111.121 248.54 109.187 246.606 109.187 244.221L108.668 244.221L108.15 244.221C108.15 247.179 110.548 249.577 113.506 249.577L113.506 249.058ZM108.668 244.221H109.187V181.433H108.668H108.15V244.221H108.668ZM108.668 181.433L109.187 181.434C109.187 179.048 111.121 177.114 113.506 177.114L113.506 176.596L113.506 176.077C110.548 176.077 108.15 178.475 108.15 181.433L108.668 181.433ZM113.506 176.596V177.114H306.376V176.596V176.077H113.506V176.596Z" fill="#626B81"/>
|
||||
<path d="M311.214 181.433H311.733V181.433L311.214 181.433ZM311.214 244.221L311.733 244.221V244.221H311.214ZM113.506 249.058L113.506 249.577H113.506V249.058ZM108.668 244.221H108.15V244.221L108.668 244.221ZM108.668 181.433L108.15 181.433V181.433H108.668ZM113.506 176.596V176.077H113.506L113.506 176.596ZM306.376 176.596V177.114C308.762 177.114 310.696 179.048 310.696 181.434L311.214 181.433L311.733 181.433C311.733 178.475 309.335 176.077 306.376 176.077V176.596ZM311.214 181.433H310.696V244.221H311.214H311.733V181.433H311.214ZM311.214 244.221L310.696 244.221C310.696 246.606 308.762 248.54 306.376 248.54V249.058V249.577C309.335 249.577 311.733 247.179 311.733 244.221L311.214 244.221ZM306.376 249.058V248.54H113.506V249.058V249.577H306.376V249.058ZM113.506 249.058L113.506 248.54C111.121 248.54 109.187 246.606 109.187 244.221L108.668 244.221L108.15 244.221C108.15 247.179 110.548 249.577 113.506 249.577L113.506 249.058ZM108.668 244.221H109.187V181.433H108.668H108.15V244.221H108.668ZM108.668 181.433L109.187 181.434C109.187 179.048 111.121 177.114 113.506 177.114L113.506 176.596L113.506 176.077C110.548 176.077 108.15 178.475 108.15 181.433L108.668 181.433ZM113.506 176.596V177.114H306.376V176.596V176.077H113.506V176.596Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M208.198 236.383C208.961 236.383 209.581 237.001 209.581 237.765V238.802C209.581 239.565 208.961 240.183 208.198 240.183H121.456C120.692 240.183 120.073 239.565 120.073 238.802V237.765C120.073 237.001 120.692 236.383 121.456 236.383H208.198ZM294.25 228.088C295.013 228.088 295.631 228.707 295.631 229.471V230.508C295.631 231.271 295.013 231.889 294.25 231.89H121.456C120.692 231.89 120.073 231.271 120.073 230.508V229.471C120.073 228.707 120.692 228.088 121.456 228.088H294.25ZM294.162 219.676C294.925 219.676 295.544 220.295 295.544 221.058V222.089C295.544 222.852 294.925 223.471 294.162 223.472H121.456C120.692 223.472 120.073 222.852 120.073 222.089V221.058C120.073 220.295 120.692 219.676 121.456 219.676H294.162ZM294.162 211.154C294.925 211.154 295.544 211.774 295.544 212.537V213.567C295.544 214.331 294.925 214.95 294.162 214.95H121.456C120.692 214.95 120.073 214.331 120.073 213.567V212.537C120.073 211.774 120.692 211.154 121.456 211.154H294.162ZM294.25 202.515C295.013 202.515 295.631 203.134 295.631 203.897V204.933C295.631 205.697 295.013 206.316 294.25 206.316H121.456C120.692 206.316 120.073 205.697 120.073 204.933V203.897C120.073 203.134 120.692 202.515 121.456 202.515H294.25ZM294.162 194.102C294.925 194.103 295.544 194.722 295.544 195.485V196.516C295.544 197.279 294.925 197.898 294.162 197.898H121.456C120.692 197.898 120.073 197.279 120.073 196.516V195.485C120.073 194.722 120.692 194.102 121.456 194.102H294.162ZM294.162 185.581C294.925 185.581 295.544 186.2 295.544 186.964V187.994C295.544 188.757 294.925 189.377 294.162 189.377H121.456C120.692 189.377 120.073 188.757 120.073 187.994V186.964C120.073 186.2 120.692 185.581 121.456 185.581H294.162Z" fill="#626B81"/>
|
||||
<path d="M208.198 236.383C208.961 236.383 209.581 237.001 209.581 237.765V238.802C209.581 239.565 208.961 240.183 208.198 240.183H121.456C120.692 240.183 120.073 239.565 120.073 238.802V237.765C120.073 237.001 120.692 236.383 121.456 236.383H208.198ZM294.25 228.088C295.013 228.088 295.631 228.707 295.631 229.471V230.508C295.631 231.271 295.013 231.889 294.25 231.89H121.456C120.692 231.89 120.073 231.271 120.073 230.508V229.471C120.073 228.707 120.692 228.088 121.456 228.088H294.25ZM294.162 219.676C294.925 219.676 295.544 220.295 295.544 221.058V222.089C295.544 222.852 294.925 223.471 294.162 223.472H121.456C120.692 223.472 120.073 222.852 120.073 222.089V221.058C120.073 220.295 120.692 219.676 121.456 219.676H294.162ZM294.162 211.154C294.925 211.154 295.544 211.774 295.544 212.537V213.567C295.544 214.331 294.925 214.95 294.162 214.95H121.456C120.692 214.95 120.073 214.331 120.073 213.567V212.537C120.073 211.774 120.692 211.154 121.456 211.154H294.162ZM294.25 202.515C295.013 202.515 295.631 203.134 295.631 203.897V204.933C295.631 205.697 295.013 206.316 294.25 206.316H121.456C120.692 206.316 120.073 205.697 120.073 204.933V203.897C120.073 203.134 120.692 202.515 121.456 202.515H294.25ZM294.162 194.102C294.925 194.103 295.544 194.722 295.544 195.485V196.516C295.544 197.279 294.925 197.898 294.162 197.898H121.456C120.692 197.898 120.073 197.279 120.073 196.516V195.485C120.073 194.722 120.692 194.102 121.456 194.102H294.162ZM294.162 185.581C294.925 185.581 295.544 186.2 295.544 186.964V187.994C295.544 188.757 294.925 189.377 294.162 189.377H121.456C120.692 189.377 120.073 188.757 120.073 187.994V186.964C120.073 186.2 120.692 185.581 121.456 185.581H294.162Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<rect x="228.918" y="279.698" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(-2.23745 228.918 279.698)" fill="#3E5DE7"/>
|
||||
<rect x="228.918" y="279.698" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(-2.23745 228.918 279.698)" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M233.802 288.691C233.778 288.071 234.26 287.549 234.88 287.524L244.981 287.13C245.601 287.106 246.123 287.588 246.147 288.208C246.171 288.828 245.688 289.35 245.069 289.374L234.968 289.769C234.348 289.793 233.826 289.31 233.802 288.691Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M233.802 288.691C233.778 288.071 234.26 287.549 234.88 287.524L244.981 287.13C245.601 287.106 246.123 287.588 246.147 288.208C246.171 288.828 245.688 289.35 245.069 289.374L234.968 289.769C234.348 289.793 233.826 289.31 233.802 288.691Z" fill="#F7F8FA" fill-opacity="0.45"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M233.95 292.486C233.926 291.866 234.409 291.344 235.028 291.32L254.036 290.577C254.656 290.553 255.178 291.036 255.203 291.656C255.227 292.276 254.744 292.798 254.124 292.822L235.116 293.565C234.496 293.589 233.974 293.106 233.95 292.486ZM234.082 295.853C234.057 295.233 234.54 294.711 235.16 294.687L254.168 293.944C254.788 293.92 255.31 294.403 255.334 295.023C255.358 295.642 254.875 296.165 254.256 296.189L235.248 296.931C234.628 296.956 234.106 296.473 234.082 295.853ZM234.213 299.22C234.189 298.6 234.672 298.078 235.292 298.054L254.299 297.311C254.919 297.287 255.441 297.77 255.466 298.39C255.49 299.009 255.007 299.531 254.387 299.556L235.379 300.298C234.759 300.323 234.237 299.84 234.213 299.22ZM234.345 302.587C234.32 301.967 234.803 301.445 235.423 301.421L254.431 300.678C255.051 300.654 255.573 301.137 255.597 301.756C255.621 302.376 255.139 302.898 254.519 302.923L235.511 303.665C234.891 303.689 234.369 303.207 234.345 302.587Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M233.95 292.486C233.926 291.866 234.409 291.344 235.028 291.32L254.036 290.577C254.656 290.553 255.178 291.036 255.203 291.656C255.227 292.276 254.744 292.798 254.124 292.822L235.116 293.565C234.496 293.589 233.974 293.106 233.95 292.486ZM234.082 295.853C234.057 295.233 234.54 294.711 235.16 294.687L254.168 293.944C254.788 293.92 255.31 294.403 255.334 295.023C255.358 295.642 254.875 296.165 254.256 296.189L235.248 296.931C234.628 296.956 234.106 296.473 234.082 295.853ZM234.213 299.22C234.189 298.6 234.672 298.078 235.292 298.054L254.299 297.311C254.919 297.287 255.441 297.77 255.466 298.39C255.49 299.009 255.007 299.531 254.387 299.556L235.379 300.298C234.759 300.323 234.237 299.84 234.213 299.22ZM234.345 302.587C234.32 301.967 234.803 301.445 235.423 301.421L254.431 300.678C255.051 300.654 255.573 301.137 255.597 301.756C255.621 302.376 255.139 302.898 254.519 302.923L235.511 303.665C234.891 303.689 234.369 303.207 234.345 302.587Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M234.478 305.993C234.454 305.374 234.936 304.851 235.556 304.827L254.564 304.085C255.184 304.06 255.706 304.543 255.73 305.163C255.755 305.783 255.272 306.305 254.652 306.329L235.644 307.072C235.024 307.096 234.502 306.613 234.478 305.993ZM234.609 309.36C234.585 308.741 235.068 308.218 235.688 308.194L254.696 307.452C255.316 307.427 255.838 307.91 255.862 308.53C255.886 309.15 255.403 309.672 254.783 309.696L235.775 310.439C235.156 310.463 234.633 309.98 234.609 309.36ZM234.741 312.727C234.717 312.107 235.199 311.585 235.819 311.561L254.827 310.818C255.447 310.794 255.969 311.277 255.993 311.897C256.018 312.517 255.535 313.039 254.915 313.063L235.907 313.806C235.287 313.83 234.765 313.347 234.741 312.727ZM234.872 316.094C234.848 315.474 235.331 314.952 235.951 314.928L254.959 314.185C255.579 314.161 256.101 314.644 256.125 315.264C256.149 315.884 255.666 316.406 255.046 316.43L236.039 317.173C235.419 317.197 234.897 316.714 234.872 316.094Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M234.478 305.993C234.454 305.374 234.936 304.851 235.556 304.827L254.564 304.085C255.184 304.06 255.706 304.543 255.73 305.163C255.755 305.783 255.272 306.305 254.652 306.329L235.644 307.072C235.024 307.096 234.502 306.613 234.478 305.993ZM234.609 309.36C234.585 308.741 235.068 308.218 235.688 308.194L254.696 307.452C255.316 307.427 255.838 307.91 255.862 308.53C255.886 309.15 255.403 309.672 254.783 309.696L235.775 310.439C235.156 310.463 234.633 309.98 234.609 309.36ZM234.741 312.727C234.717 312.107 235.199 311.585 235.819 311.561L254.827 310.818C255.447 310.794 255.969 311.277 255.993 311.897C256.018 312.517 255.535 313.039 254.915 313.063L235.907 313.806C235.287 313.83 234.765 313.347 234.741 312.727ZM234.872 316.094C234.848 315.474 235.331 314.952 235.951 314.928L254.959 314.185C255.579 314.161 256.101 314.644 256.125 315.264C256.149 315.884 255.666 316.406 255.046 316.43L236.039 317.173C235.419 317.197 234.897 316.714 234.872 316.094Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<rect x="228.589" y="279.315" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-2.23745 228.589 279.315)" fill="#3E5DE7"/>
|
||||
<rect x="228.589" y="279.315" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-2.23745 228.589 279.315)" fill="#F7F8FA" fill-opacity="0.975"/>
|
||||
<rect x="228.589" y="279.315" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-2.23745 228.589 279.315)" stroke="#3E5DE7" stroke-width="1.36294"/>
|
||||
<rect x="228.589" y="279.315" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-2.23745 228.589 279.315)" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="1.36294"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M232.765 287.654C232.741 287.034 233.224 286.512 233.843 286.488L243.944 286.093C244.564 286.069 245.086 286.552 245.11 287.171C245.135 287.791 244.652 288.313 244.032 288.338L233.931 288.732C233.311 288.756 232.789 288.274 232.765 287.654Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M232.765 287.654C232.741 287.034 233.224 286.512 233.843 286.488L243.944 286.093C244.564 286.069 245.086 286.552 245.11 287.171C245.135 287.791 244.652 288.313 244.032 288.338L233.931 288.732C233.311 288.756 232.789 288.274 232.765 287.654Z" fill="#F7F8FA" fill-opacity="0.45"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M232.913 291.449C232.889 290.829 233.372 290.307 233.992 290.283L253 289.541C253.619 289.516 254.142 289.999 254.166 290.619C254.19 291.239 253.707 291.761 253.087 291.785L234.079 292.528C233.46 292.552 232.937 292.069 232.913 291.449ZM233.045 294.816C233.021 294.196 233.503 293.674 234.123 293.65L253.131 292.907C253.751 292.883 254.273 293.366 254.297 293.986C254.322 294.606 253.839 295.128 253.219 295.152L234.211 295.895C233.591 295.919 233.069 295.436 233.045 294.816ZM233.176 298.183C233.152 297.563 233.635 297.041 234.255 297.017L253.263 296.274C253.883 296.25 254.405 296.733 254.429 297.353C254.453 297.973 253.97 298.495 253.35 298.519L234.342 299.262C233.723 299.286 233.201 298.803 233.176 298.183ZM233.308 301.55C233.284 300.93 233.767 300.408 234.386 300.384L253.394 299.641C254.014 299.617 254.536 300.1 254.56 300.72C254.585 301.34 254.102 301.862 253.482 301.886L234.474 302.629C233.854 302.653 233.332 302.17 233.308 301.55Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M232.913 291.449C232.889 290.829 233.372 290.307 233.992 290.283L253 289.541C253.619 289.516 254.142 289.999 254.166 290.619C254.19 291.239 253.707 291.761 253.087 291.785L234.079 292.528C233.46 292.552 232.937 292.069 232.913 291.449ZM233.045 294.816C233.021 294.196 233.503 293.674 234.123 293.65L253.131 292.907C253.751 292.883 254.273 293.366 254.297 293.986C254.322 294.606 253.839 295.128 253.219 295.152L234.211 295.895C233.591 295.919 233.069 295.436 233.045 294.816ZM233.176 298.183C233.152 297.563 233.635 297.041 234.255 297.017L253.263 296.274C253.883 296.25 254.405 296.733 254.429 297.353C254.453 297.973 253.97 298.495 253.35 298.519L234.342 299.262C233.723 299.286 233.201 298.803 233.176 298.183ZM233.308 301.55C233.284 300.93 233.767 300.408 234.386 300.384L253.394 299.641C254.014 299.617 254.536 300.1 254.56 300.72C254.585 301.34 254.102 301.862 253.482 301.886L234.474 302.629C233.854 302.653 233.332 302.17 233.308 301.55Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M233.441 304.957C233.417 304.337 233.9 303.815 234.519 303.791L253.527 303.048C254.147 303.024 254.669 303.506 254.694 304.126C254.718 304.746 254.235 305.268 253.615 305.292L234.607 306.035C233.987 306.059 233.465 305.577 233.441 304.957ZM233.573 308.324C233.548 307.704 234.031 307.182 234.651 307.157L253.659 306.415C254.279 306.391 254.801 306.873 254.825 307.493C254.849 308.113 254.366 308.635 253.747 308.659L234.739 309.402C234.119 309.426 233.597 308.943 233.573 308.324ZM233.704 311.691C233.68 311.071 234.163 310.549 234.783 310.524L253.79 309.782C254.41 309.757 254.932 310.24 254.957 310.86C254.981 311.48 254.498 312.002 253.878 312.026L234.87 312.769C234.25 312.793 233.728 312.31 233.704 311.691ZM233.836 315.057C233.811 314.438 234.294 313.915 234.914 313.891L253.922 313.149C254.542 313.124 255.064 313.607 255.088 314.227C255.112 314.847 254.63 315.369 254.01 315.393L235.002 316.136C234.382 316.16 233.86 315.677 233.836 315.057Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M233.441 304.957C233.417 304.337 233.9 303.815 234.519 303.791L253.527 303.048C254.147 303.024 254.669 303.506 254.694 304.126C254.718 304.746 254.235 305.268 253.615 305.292L234.607 306.035C233.987 306.059 233.465 305.577 233.441 304.957ZM233.573 308.324C233.548 307.704 234.031 307.182 234.651 307.157L253.659 306.415C254.279 306.391 254.801 306.873 254.825 307.493C254.849 308.113 254.366 308.635 253.747 308.659L234.739 309.402C234.119 309.426 233.597 308.943 233.573 308.324ZM233.704 311.691C233.68 311.071 234.163 310.549 234.783 310.524L253.79 309.782C254.41 309.757 254.932 310.24 254.957 310.86C254.981 311.48 254.498 312.002 253.878 312.026L234.87 312.769C234.25 312.793 233.728 312.31 233.704 311.691ZM233.836 315.057C233.811 314.438 234.294 313.915 234.914 313.891L253.922 313.149C254.542 313.124 255.064 313.607 255.088 314.227C255.112 314.847 254.63 315.369 254.01 315.393L235.002 316.136C234.382 316.16 233.86 315.677 233.836 315.057Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<circle cx="243.181" cy="278.892" r="3.80147" fill="#3E5DE7"/>
|
||||
<circle cx="243.181" cy="278.892" r="3.80147" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<circle cx="241.798" cy="278.201" r="3.80147" fill="#3E5DE7"/>
|
||||
<circle cx="241.798" cy="278.201" r="3.80147" fill="#F7F8FA" fill-opacity="0.35"/>
|
||||
<g clip-path="url(#clip2_12246_5573)">
|
||||
<rect x="155.072" y="94.2147" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(11.3678 155.072 94.2147)" fill="#3E5DE7"/>
|
||||
<rect x="155.072" y="94.2147" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(11.3678 155.072 94.2147)" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M157.703 104.104C157.825 103.496 158.417 103.102 159.025 103.224L168.935 105.217C169.543 105.339 169.937 105.931 169.815 106.539C169.693 107.147 169.101 107.541 168.493 107.419L158.582 105.426C157.974 105.304 157.58 104.712 157.703 104.104Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M157.703 104.104C157.825 103.496 158.417 103.102 159.025 103.224L168.935 105.217C169.543 105.339 169.937 105.931 169.815 106.539C169.693 107.147 169.101 107.541 168.493 107.419L158.582 105.426C157.974 105.304 157.58 104.712 157.703 104.104Z" fill="#F7F8FA" fill-opacity="0.45"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M156.954 107.828C157.076 107.22 157.668 106.826 158.276 106.948L176.926 110.697C177.534 110.82 177.928 111.412 177.805 112.02C177.683 112.628 177.091 113.022 176.483 112.9L157.834 109.15C157.226 109.028 156.832 108.436 156.954 107.828ZM156.29 111.131C156.412 110.523 157.004 110.129 157.612 110.251L176.262 114.001C176.87 114.123 177.264 114.715 177.141 115.323C177.019 115.931 176.427 116.325 175.819 116.203L157.17 112.454C156.561 112.331 156.168 111.739 156.29 111.131ZM155.626 114.434C155.748 113.826 156.34 113.432 156.948 113.555L175.597 117.304C176.206 117.426 176.599 118.019 176.477 118.627C176.355 119.235 175.763 119.629 175.155 119.506L156.505 115.757C155.897 115.635 155.503 115.043 155.626 114.434ZM154.962 117.738C155.084 117.13 155.676 116.736 156.284 116.858L174.933 120.608C175.541 120.73 175.935 121.322 175.813 121.93C175.691 122.538 175.099 122.932 174.491 122.81L155.841 119.06C155.233 118.938 154.839 118.346 154.962 117.738Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M156.954 107.828C157.076 107.22 157.668 106.826 158.276 106.948L176.926 110.697C177.534 110.82 177.928 111.412 177.805 112.02C177.683 112.628 177.091 113.022 176.483 112.9L157.834 109.15C157.226 109.028 156.832 108.436 156.954 107.828ZM156.29 111.131C156.412 110.523 157.004 110.129 157.612 110.251L176.262 114.001C176.87 114.123 177.264 114.715 177.141 115.323C177.019 115.931 176.427 116.325 175.819 116.203L157.17 112.454C156.561 112.331 156.168 111.739 156.29 111.131ZM155.626 114.434C155.748 113.826 156.34 113.432 156.948 113.555L175.597 117.304C176.206 117.426 176.599 118.019 176.477 118.627C176.355 119.235 175.763 119.629 175.155 119.506L156.505 115.757C155.897 115.635 155.503 115.043 155.626 114.434ZM154.962 117.738C155.084 117.13 155.676 116.736 156.284 116.858L174.933 120.608C175.541 120.73 175.935 121.322 175.813 121.93C175.691 122.538 175.099 122.932 174.491 122.81L155.841 119.06C155.233 118.938 154.839 118.346 154.962 117.738Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M154.29 121.08C154.412 120.472 155.004 120.078 155.612 120.2L174.261 123.95C174.869 124.072 175.263 124.664 175.141 125.272C175.019 125.881 174.427 126.274 173.819 126.152L155.169 122.403C154.561 122.28 154.167 121.688 154.29 121.08ZM153.625 124.384C153.748 123.775 154.34 123.382 154.948 123.504L173.597 127.253C174.205 127.376 174.599 127.968 174.477 128.576C174.355 129.184 173.763 129.578 173.154 129.456L154.505 125.706C153.897 125.584 153.503 124.992 153.625 124.384ZM152.961 127.687C153.084 127.079 153.676 126.685 154.284 126.807L172.933 130.557C173.541 130.679 173.935 131.271 173.813 131.879C173.691 132.487 173.098 132.881 172.49 132.759L153.841 129.009C153.233 128.887 152.839 128.295 152.961 127.687ZM152.297 130.99C152.419 130.382 153.011 129.988 153.62 130.111L172.269 133.86C172.877 133.982 173.271 134.574 173.149 135.183C173.026 135.791 172.434 136.185 171.826 136.062L153.177 132.313C152.569 132.191 152.175 131.598 152.297 130.99Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M154.29 121.08C154.412 120.472 155.004 120.078 155.612 120.2L174.261 123.95C174.869 124.072 175.263 124.664 175.141 125.272C175.019 125.881 174.427 126.274 173.819 126.152L155.169 122.403C154.561 122.28 154.167 121.688 154.29 121.08ZM153.625 124.384C153.748 123.775 154.34 123.382 154.948 123.504L173.597 127.253C174.205 127.376 174.599 127.968 174.477 128.576C174.355 129.184 173.763 129.578 173.154 129.456L154.505 125.706C153.897 125.584 153.503 124.992 153.625 124.384ZM152.961 127.687C153.084 127.079 153.676 126.685 154.284 126.807L172.933 130.557C173.541 130.679 173.935 131.271 173.813 131.879C173.691 132.487 173.098 132.881 172.49 132.759L153.841 129.009C153.233 128.887 152.839 128.295 152.961 127.687ZM152.297 130.99C152.419 130.382 153.011 129.988 153.62 130.111L172.269 133.86C172.877 133.982 173.271 134.574 173.149 135.183C173.026 135.791 172.434 136.185 171.826 136.062L153.177 132.313C152.569 132.191 152.175 131.598 152.297 130.99Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
</g>
|
||||
<g clip-path="url(#clip3_12246_5573)">
|
||||
<rect x="154.308" y="92.9633" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(11.3678 154.308 92.9633)" fill="#3E5DE7"/>
|
||||
<rect x="154.308" y="92.9633" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(11.3678 154.308 92.9633)" fill="#F7F8FA" fill-opacity="0.975"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M156.939 102.852C157.061 102.244 157.653 101.85 158.261 101.973L168.172 103.965C168.78 104.087 169.174 104.679 169.051 105.288C168.929 105.896 168.337 106.29 167.729 106.167L157.819 104.175C157.211 104.053 156.817 103.46 156.939 102.852Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M156.939 102.852C157.061 102.244 157.653 101.85 158.261 101.973L168.172 103.965C168.78 104.087 169.174 104.679 169.051 105.288C168.929 105.896 168.337 106.29 167.729 106.167L157.819 104.175C157.211 104.053 156.817 103.46 156.939 102.852Z" fill="#F7F8FA" fill-opacity="0.45"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M156.19 106.576C156.312 105.968 156.905 105.574 157.513 105.696L176.162 109.446C176.77 109.568 177.164 110.16 177.042 110.768C176.919 111.377 176.327 111.77 175.719 111.648L157.07 107.899C156.462 107.776 156.068 107.184 156.19 106.576ZM155.526 109.88C155.648 109.271 156.24 108.878 156.849 109L175.498 112.749C176.106 112.872 176.5 113.464 176.378 114.072C176.255 114.68 175.663 115.074 175.055 114.952L156.406 111.202C155.798 111.08 155.404 110.488 155.526 109.88ZM154.862 113.183C154.984 112.575 155.576 112.181 156.184 112.303L174.834 116.053C175.442 116.175 175.836 116.767 175.713 117.375C175.591 117.983 174.999 118.377 174.391 118.255L155.742 114.505C155.133 114.383 154.74 113.791 154.862 113.183ZM154.198 116.486C154.32 115.878 154.912 115.484 155.52 115.607L174.17 119.356C174.778 119.478 175.172 120.07 175.049 120.679C174.927 121.287 174.335 121.681 173.727 121.558L155.077 117.809C154.469 117.687 154.075 117.095 154.198 116.486Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M156.19 106.576C156.312 105.968 156.905 105.574 157.513 105.696L176.162 109.446C176.77 109.568 177.164 110.16 177.042 110.768C176.919 111.377 176.327 111.77 175.719 111.648L157.07 107.899C156.462 107.776 156.068 107.184 156.19 106.576ZM155.526 109.88C155.648 109.271 156.24 108.878 156.849 109L175.498 112.749C176.106 112.872 176.5 113.464 176.378 114.072C176.255 114.68 175.663 115.074 175.055 114.952L156.406 111.202C155.798 111.08 155.404 110.488 155.526 109.88ZM154.862 113.183C154.984 112.575 155.576 112.181 156.184 112.303L174.834 116.053C175.442 116.175 175.836 116.767 175.713 117.375C175.591 117.983 174.999 118.377 174.391 118.255L155.742 114.505C155.133 114.383 154.74 113.791 154.862 113.183ZM154.198 116.486C154.32 115.878 154.912 115.484 155.52 115.607L174.17 119.356C174.778 119.478 175.172 120.07 175.049 120.679C174.927 121.287 174.335 121.681 173.727 121.558L155.077 117.809C154.469 117.687 154.075 117.095 154.198 116.486Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M153.526 119.829C153.648 119.221 154.24 118.827 154.848 118.949L173.498 122.698C174.106 122.821 174.5 123.413 174.377 124.021C174.255 124.629 173.663 125.023 173.055 124.901L154.405 121.151C153.797 121.029 153.403 120.437 153.526 119.829ZM152.862 123.132C152.984 122.524 153.576 122.13 154.184 122.252L172.833 126.002C173.442 126.124 173.835 126.716 173.713 127.324C173.591 127.932 172.999 128.326 172.391 128.204L153.741 124.455C153.133 124.332 152.739 123.74 152.862 123.132ZM152.197 126.435C152.32 125.827 152.912 125.433 153.52 125.556L172.169 129.305C172.777 129.427 173.171 130.02 173.049 130.628C172.927 131.236 172.335 131.63 171.726 131.507L153.077 127.758C152.469 127.636 152.075 127.044 152.197 126.435ZM151.533 129.739C151.656 129.131 152.248 128.737 152.856 128.859L171.505 132.609C172.113 132.731 172.507 133.323 172.385 133.931C172.263 134.539 171.67 134.933 171.062 134.811L152.413 131.061C151.805 130.939 151.411 130.347 151.533 129.739Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M153.526 119.829C153.648 119.221 154.24 118.827 154.848 118.949L173.498 122.698C174.106 122.821 174.5 123.413 174.377 124.021C174.255 124.629 173.663 125.023 173.055 124.901L154.405 121.151C153.797 121.029 153.403 120.437 153.526 119.829ZM152.862 123.132C152.984 122.524 153.576 122.13 154.184 122.252L172.833 126.002C173.442 126.124 173.835 126.716 173.713 127.324C173.591 127.932 172.999 128.326 172.391 128.204L153.741 124.455C153.133 124.332 152.739 123.74 152.862 123.132ZM152.197 126.435C152.32 125.827 152.912 125.433 153.52 125.556L172.169 129.305C172.777 129.427 173.171 130.02 173.049 130.628C172.927 131.236 172.335 131.63 171.726 131.507L153.077 127.758C152.469 127.636 152.075 127.044 152.197 126.435ZM151.533 129.739C151.656 129.131 152.248 128.737 152.856 128.859L171.505 132.609C172.113 132.731 172.507 133.323 172.385 133.931C172.263 134.539 171.67 134.933 171.062 134.811L152.413 131.061C151.805 130.939 151.411 130.347 151.533 129.739Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
</g>
|
||||
<rect x="154.842" y="93.7657" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(11.3678 154.842 93.7657)" stroke="#3E5DE7" stroke-width="1.36294"/>
|
||||
<rect x="154.842" y="93.7657" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(11.3678 154.842 93.7657)" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="1.36294"/>
|
||||
<circle cx="170.607" cy="97.1124" r="3.80147" fill="#3E5DE7"/>
|
||||
<circle cx="170.607" cy="97.1124" r="3.80147" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<circle cx="169.225" cy="96.4212" r="3.80147" fill="#3E5DE7"/>
|
||||
<circle cx="169.225" cy="96.4212" r="3.80147" fill="#F7F8FA" fill-opacity="0.35"/>
|
||||
<rect x="324.343" y="135.537" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(-4.33133 324.343 135.537)" fill="#3E5DE7"/>
|
||||
<rect x="324.343" y="135.537" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(-4.33133 324.343 135.537)" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M329.552 144.345C329.505 143.727 329.968 143.187 330.587 143.141L340.666 142.377C341.285 142.33 341.824 142.794 341.871 143.412C341.918 144.031 341.455 144.57 340.836 144.617L330.756 145.381C330.138 145.427 329.598 144.964 329.552 144.345Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M329.552 144.345C329.505 143.727 329.968 143.187 330.587 143.141L340.666 142.377C341.285 142.33 341.824 142.794 341.871 143.412C341.918 144.031 341.455 144.57 340.836 144.617L330.756 145.381C330.138 145.427 329.598 144.964 329.552 144.345Z" fill="#F7F8FA" fill-opacity="0.45"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M329.838 148.133C329.792 147.514 330.255 146.975 330.874 146.928L349.842 145.492C350.46 145.445 351 145.908 351.047 146.527C351.093 147.145 350.63 147.685 350.011 147.731L331.043 149.168C330.425 149.215 329.885 148.752 329.838 148.133ZM330.093 151.493C330.046 150.874 330.51 150.335 331.128 150.288L350.096 148.851C350.715 148.805 351.254 149.268 351.301 149.887C351.348 150.505 350.884 151.045 350.266 151.091L331.298 152.528C330.679 152.575 330.14 152.111 330.093 151.493ZM330.347 154.853C330.301 154.234 330.764 153.695 331.383 153.648L350.351 152.211C350.969 152.164 351.509 152.628 351.555 153.246C351.602 153.865 351.139 154.404 350.52 154.451L331.552 155.888C330.934 155.935 330.394 155.471 330.347 154.853ZM330.602 158.213C330.555 157.594 331.019 157.055 331.637 157.008L350.605 155.571C351.224 155.524 351.763 155.988 351.81 156.606C351.857 157.225 351.393 157.764 350.775 157.811L331.807 159.248C331.188 159.295 330.649 158.831 330.602 158.213Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M329.838 148.133C329.792 147.514 330.255 146.975 330.874 146.928L349.842 145.492C350.46 145.445 351 145.908 351.047 146.527C351.093 147.145 350.63 147.685 350.011 147.731L331.043 149.168C330.425 149.215 329.885 148.752 329.838 148.133ZM330.093 151.493C330.046 150.874 330.51 150.335 331.128 150.288L350.096 148.851C350.715 148.805 351.254 149.268 351.301 149.887C351.348 150.505 350.884 151.045 350.266 151.091L331.298 152.528C330.679 152.575 330.14 152.111 330.093 151.493ZM330.347 154.853C330.301 154.234 330.764 153.695 331.383 153.648L350.351 152.211C350.969 152.164 351.509 152.628 351.555 153.246C351.602 153.865 351.139 154.404 350.52 154.451L331.552 155.888C330.934 155.935 330.394 155.471 330.347 154.853ZM330.602 158.213C330.555 157.594 331.019 157.055 331.637 157.008L350.605 155.571C351.224 155.524 351.763 155.988 351.81 156.606C351.857 157.225 351.393 157.764 350.775 157.811L331.807 159.248C331.188 159.295 330.649 158.831 330.602 158.213Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M330.859 161.612C330.813 160.994 331.276 160.454 331.895 160.407L350.863 158.971C351.481 158.924 352.021 159.387 352.067 160.006C352.114 160.624 351.651 161.164 351.032 161.211L332.064 162.647C331.446 162.694 330.906 162.231 330.859 161.612ZM331.114 164.972C331.067 164.353 331.53 163.814 332.149 163.767L351.117 162.33C351.736 162.284 352.275 162.747 352.322 163.366C352.369 163.984 351.905 164.524 351.287 164.57L332.319 166.007C331.7 166.054 331.161 165.59 331.114 164.972ZM331.368 168.332C331.322 167.713 331.785 167.174 332.403 167.127L351.372 165.69C351.99 165.644 352.53 166.107 352.576 166.725C352.623 167.344 352.16 167.883 351.541 167.93L332.573 169.367C331.955 169.414 331.415 168.95 331.368 168.332ZM331.623 171.692C331.576 171.073 332.039 170.534 332.658 170.487L351.626 169.05C352.245 169.003 352.784 169.467 352.831 170.085C352.878 170.704 352.414 171.243 351.796 171.29L332.828 172.727C332.209 172.774 331.67 172.31 331.623 171.692Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M330.859 161.612C330.813 160.994 331.276 160.454 331.895 160.407L350.863 158.971C351.481 158.924 352.021 159.387 352.067 160.006C352.114 160.624 351.651 161.164 351.032 161.211L332.064 162.647C331.446 162.694 330.906 162.231 330.859 161.612ZM331.114 164.972C331.067 164.353 331.53 163.814 332.149 163.767L351.117 162.33C351.736 162.284 352.275 162.747 352.322 163.366C352.369 163.984 351.905 164.524 351.287 164.57L332.319 166.007C331.7 166.054 331.161 165.59 331.114 164.972ZM331.368 168.332C331.322 167.713 331.785 167.174 332.403 167.127L351.372 165.69C351.99 165.644 352.53 166.107 352.576 166.725C352.623 167.344 352.16 167.883 351.541 167.93L332.573 169.367C331.955 169.414 331.415 168.95 331.368 168.332ZM331.623 171.692C331.576 171.073 332.039 170.534 332.658 170.487L351.626 169.05C352.245 169.003 352.784 169.467 352.831 170.085C352.878 170.704 352.414 171.243 351.796 171.29L332.828 172.727C332.209 172.774 331.67 172.31 331.623 171.692Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<rect x="323.816" y="135.412" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-4.33133 323.816 135.412)" fill="#3E5DE7"/>
|
||||
<rect x="323.816" y="135.412" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-4.33133 323.816 135.412)" fill="#F7F8FA" fill-opacity="0.975"/>
|
||||
<rect x="323.816" y="135.412" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-4.33133 323.816 135.412)" stroke="#3E5DE7" stroke-width="1.36294"/>
|
||||
<rect x="323.816" y="135.412" width="28.9624" height="39.0709" rx="3.81118" transform="rotate(-4.33133 323.816 135.412)" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="1.36294"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M328.294 143.592C328.247 142.973 328.711 142.434 329.329 142.387L339.409 141.623C340.027 141.577 340.567 142.04 340.614 142.659C340.66 143.277 340.197 143.816 339.578 143.863L329.499 144.627C328.88 144.674 328.341 144.21 328.294 143.592Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M328.294 143.592C328.247 142.973 328.711 142.434 329.329 142.387L339.409 141.623C340.027 141.577 340.567 142.04 340.614 142.659C340.66 143.277 340.197 143.816 339.578 143.863L329.499 144.627C328.88 144.674 328.341 144.21 328.294 143.592Z" fill="#F7F8FA" fill-opacity="0.45"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M328.581 147.379C328.534 146.761 328.998 146.221 329.616 146.174L348.584 144.738C349.203 144.691 349.742 145.154 349.789 145.773C349.836 146.391 349.372 146.931 348.754 146.978L329.786 148.414C329.167 148.461 328.628 147.998 328.581 147.379ZM328.835 150.739C328.789 150.121 329.252 149.581 329.871 149.534L348.839 148.098C349.457 148.051 349.997 148.514 350.043 149.133C350.09 149.751 349.627 150.291 349.008 150.338L330.04 151.774C329.422 151.821 328.882 151.358 328.835 150.739ZM329.09 154.099C329.043 153.48 329.506 152.941 330.125 152.894L349.093 151.458C349.712 151.411 350.251 151.874 350.298 152.493C350.345 153.111 349.881 153.651 349.263 153.697L330.295 155.134C329.676 155.181 329.137 154.717 329.09 154.099ZM329.344 157.459C329.298 156.84 329.761 156.301 330.379 156.254L349.348 154.817C349.966 154.771 350.506 155.234 350.552 155.853C350.599 156.471 350.136 157.01 349.517 157.057L330.549 158.494C329.931 158.541 329.391 158.077 329.344 157.459Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M328.581 147.379C328.534 146.761 328.998 146.221 329.616 146.174L348.584 144.738C349.203 144.691 349.742 145.154 349.789 145.773C349.836 146.391 349.372 146.931 348.754 146.978L329.786 148.414C329.167 148.461 328.628 147.998 328.581 147.379ZM328.835 150.739C328.789 150.121 329.252 149.581 329.871 149.534L348.839 148.098C349.457 148.051 349.997 148.514 350.043 149.133C350.09 149.751 349.627 150.291 349.008 150.338L330.04 151.774C329.422 151.821 328.882 151.358 328.835 150.739ZM329.09 154.099C329.043 153.48 329.506 152.941 330.125 152.894L349.093 151.458C349.712 151.411 350.251 151.874 350.298 152.493C350.345 153.111 349.881 153.651 349.263 153.697L330.295 155.134C329.676 155.181 329.137 154.717 329.09 154.099ZM329.344 157.459C329.298 156.84 329.761 156.301 330.379 156.254L349.348 154.817C349.966 154.771 350.506 155.234 350.552 155.853C350.599 156.471 350.136 157.01 349.517 157.057L330.549 158.494C329.931 158.541 329.391 158.077 329.344 157.459Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M329.602 160.858C329.555 160.24 330.018 159.7 330.637 159.654L349.605 158.217C350.224 158.17 350.763 158.633 350.81 159.252C350.857 159.871 350.393 160.41 349.775 160.457L330.807 161.893C330.188 161.94 329.649 161.477 329.602 160.858ZM329.856 164.218C329.809 163.6 330.273 163.06 330.891 163.013L349.86 161.577C350.478 161.53 351.017 161.993 351.064 162.612C351.111 163.23 350.648 163.77 350.029 163.817L331.061 165.253C330.443 165.3 329.903 164.837 329.856 164.218ZM330.111 167.578C330.064 166.959 330.527 166.42 331.146 166.373L350.114 164.937C350.733 164.89 351.272 165.353 351.319 165.972C351.366 166.59 350.902 167.13 350.284 167.176L331.316 168.613C330.697 168.66 330.158 168.197 330.111 167.578ZM330.365 170.938C330.318 170.319 330.782 169.78 331.4 169.733L350.369 168.296C350.987 168.25 351.526 168.713 351.573 169.332C351.62 169.95 351.157 170.489 350.538 170.536L331.57 171.973C330.952 172.02 330.412 171.556 330.365 170.938Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M329.602 160.858C329.555 160.24 330.018 159.7 330.637 159.654L349.605 158.217C350.224 158.17 350.763 158.633 350.81 159.252C350.857 159.871 350.393 160.41 349.775 160.457L330.807 161.893C330.188 161.94 329.649 161.477 329.602 160.858ZM329.856 164.218C329.809 163.6 330.273 163.06 330.891 163.013L349.86 161.577C350.478 161.53 351.017 161.993 351.064 162.612C351.111 163.23 350.648 163.77 350.029 163.817L331.061 165.253C330.443 165.3 329.903 164.837 329.856 164.218ZM330.111 167.578C330.064 166.959 330.527 166.42 331.146 166.373L350.114 164.937C350.733 164.89 351.272 165.353 351.319 165.972C351.366 166.59 350.902 167.13 350.284 167.176L331.316 168.613C330.697 168.66 330.158 168.197 330.111 167.578ZM330.365 170.938C330.318 170.319 330.782 169.78 331.4 169.733L350.369 168.296C350.987 168.25 351.526 168.713 351.573 169.332C351.62 169.95 351.157 170.489 350.538 170.536L331.57 171.973C330.952 172.02 330.412 171.556 330.365 170.938Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<circle cx="339.328" cy="135.153" r="3.80147" fill="#3E5DE7"/>
|
||||
<circle cx="339.328" cy="135.153" r="3.80147" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<circle cx="337.945" cy="134.462" r="3.80147" fill="#3E5DE7"/>
|
||||
<circle cx="337.945" cy="134.462" r="3.80147" fill="#F7F8FA" fill-opacity="0.35"/>
|
||||
<path d="M98.8177 178.272C98.9277 178.767 99.2164 179.015 99.6838 179.015C100.151 179.015 100.426 178.767 100.509 178.272C100.839 176.54 101.127 175.193 101.375 174.231C101.65 173.241 102.021 172.498 102.488 172.003C102.983 171.481 103.726 171.082 104.715 170.807C105.733 170.532 107.135 170.216 108.922 169.859C109.445 169.749 109.706 169.46 109.706 168.993C109.706 168.525 109.445 168.237 108.922 168.127C107.135 167.769 105.747 167.439 104.757 167.137C103.794 166.834 103.066 166.436 102.571 165.941C102.103 165.446 101.732 164.717 101.457 163.755C101.21 162.765 100.894 161.418 100.509 159.713C100.426 159.218 100.151 158.971 99.6838 158.971C99.2164 158.971 98.9277 159.218 98.8177 159.713C98.4603 161.418 98.1441 162.765 97.8691 163.755C97.6216 164.717 97.2505 165.446 96.7555 165.941C96.2881 166.436 95.5595 166.834 94.5697 167.137C93.6073 167.439 92.2326 167.769 90.4454 168.127C89.9229 168.237 89.6617 168.525 89.6617 168.993C89.6617 169.46 89.9229 169.749 90.4454 169.859C92.2326 170.216 93.6211 170.546 94.6109 170.849C95.6007 171.124 96.3431 171.522 96.838 172.045C97.3329 172.54 97.7041 173.268 97.9516 174.231C98.1991 175.193 98.4878 176.54 98.8177 178.272Z" fill="#3E5DE7"/>
|
||||
<path d="M98.8177 178.272C98.9277 178.767 99.2164 179.015 99.6838 179.015C100.151 179.015 100.426 178.767 100.509 178.272C100.839 176.54 101.127 175.193 101.375 174.231C101.65 173.241 102.021 172.498 102.488 172.003C102.983 171.481 103.726 171.082 104.715 170.807C105.733 170.532 107.135 170.216 108.922 169.859C109.445 169.749 109.706 169.46 109.706 168.993C109.706 168.525 109.445 168.237 108.922 168.127C107.135 167.769 105.747 167.439 104.757 167.137C103.794 166.834 103.066 166.436 102.571 165.941C102.103 165.446 101.732 164.717 101.457 163.755C101.21 162.765 100.894 161.418 100.509 159.713C100.426 159.218 100.151 158.971 99.6838 158.971C99.2164 158.971 98.9277 159.218 98.8177 159.713C98.4603 161.418 98.1441 162.765 97.8691 163.755C97.6216 164.717 97.2505 165.446 96.7555 165.941C96.2881 166.436 95.5595 166.834 94.5697 167.137C93.6073 167.439 92.2326 167.769 90.4454 168.127C89.9229 168.237 89.6617 168.525 89.6617 168.993C89.6617 169.46 89.9229 169.749 90.4454 169.859C92.2326 170.216 93.6211 170.546 94.6109 170.849C95.6007 171.124 96.3431 171.522 96.838 172.045C97.3329 172.54 97.7041 173.268 97.9516 174.231C98.1991 175.193 98.4878 176.54 98.8177 178.272Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M85.9541 192.326C86.03 192.668 86.2291 192.838 86.5514 192.838C86.8738 192.838 87.0634 192.668 87.1203 192.326C87.3478 191.132 87.5469 190.202 87.7176 189.539C87.9072 188.856 88.1632 188.344 88.4856 188.003C88.8269 187.643 89.3389 187.368 90.0215 187.178C90.7231 186.988 91.6902 186.77 92.9228 186.524C93.283 186.448 93.4632 186.249 93.4632 185.926C93.4632 185.604 93.283 185.405 92.9228 185.329C91.6902 185.083 90.7326 184.855 90.05 184.646C89.3863 184.438 88.8838 184.163 88.5425 183.822C88.2201 183.48 87.9641 182.978 87.7745 182.314C87.6038 181.631 87.3858 180.702 87.1203 179.527C87.0634 179.185 86.8738 179.015 86.5514 179.015C86.2291 179.015 86.03 179.185 85.9541 179.527C85.7076 180.702 85.4895 181.631 85.2999 182.314C85.1292 182.978 84.8732 183.48 84.5319 183.822C84.2096 184.163 83.7071 184.438 83.0244 184.646C82.3607 184.855 81.4126 185.083 80.1801 185.329C79.8198 185.405 79.6396 185.604 79.6396 185.926C79.6396 186.249 79.8198 186.448 80.1801 186.524C81.4126 186.77 82.3702 186.998 83.0529 187.206C83.7355 187.396 84.2475 187.671 84.5888 188.031C84.9301 188.373 85.1861 188.875 85.3568 189.539C85.5274 190.202 85.7266 191.132 85.9541 192.326Z" fill="#3E5DE7"/>
|
||||
<path d="M85.9541 192.326C86.03 192.668 86.2291 192.838 86.5514 192.838C86.8738 192.838 87.0634 192.668 87.1203 192.326C87.3478 191.132 87.5469 190.202 87.7176 189.539C87.9072 188.856 88.1632 188.344 88.4856 188.003C88.8269 187.643 89.3389 187.368 90.0215 187.178C90.7231 186.988 91.6902 186.77 92.9228 186.524C93.283 186.448 93.4632 186.249 93.4632 185.926C93.4632 185.604 93.283 185.405 92.9228 185.329C91.6902 185.083 90.7326 184.855 90.05 184.646C89.3863 184.438 88.8838 184.163 88.5425 183.822C88.2201 183.48 87.9641 182.978 87.7745 182.314C87.6038 181.631 87.3858 180.702 87.1203 179.527C87.0634 179.185 86.8738 179.015 86.5514 179.015C86.2291 179.015 86.03 179.185 85.9541 179.527C85.7076 180.702 85.4895 181.631 85.2999 182.314C85.1292 182.978 84.8732 183.48 84.5319 183.822C84.2096 184.163 83.7071 184.438 83.0244 184.646C82.3607 184.855 81.4126 185.083 80.1801 185.329C79.8198 185.405 79.6396 185.604 79.6396 185.926C79.6396 186.249 79.8198 186.448 80.1801 186.524C81.4126 186.77 82.3702 186.998 83.0529 187.206C83.7355 187.396 84.2475 187.671 84.5888 188.031C84.9301 188.373 85.1861 188.875 85.3568 189.539C85.5274 190.202 85.7266 191.132 85.9541 192.326Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M123.606 259.306C123.64 259.46 123.73 259.537 123.875 259.537C124.02 259.537 124.105 259.46 124.131 259.306C124.233 258.769 124.323 258.351 124.4 258.052C124.485 257.745 124.6 257.514 124.745 257.361C124.899 257.199 125.129 257.075 125.436 256.99C125.752 256.904 126.187 256.806 126.742 256.695C126.904 256.661 126.985 256.572 126.985 256.426C126.985 256.281 126.904 256.192 126.742 256.158C126.187 256.047 125.756 255.944 125.449 255.85C125.151 255.757 124.925 255.633 124.771 255.479C124.626 255.326 124.511 255.1 124.425 254.801C124.349 254.494 124.25 254.076 124.131 253.547C124.105 253.393 124.02 253.316 123.875 253.316C123.73 253.316 123.64 253.393 123.606 253.547C123.495 254.076 123.397 254.494 123.312 254.801C123.235 255.1 123.12 255.326 122.966 255.479C122.821 255.633 122.595 255.757 122.288 255.85C121.989 255.944 121.562 256.047 121.008 256.158C120.846 256.192 120.765 256.281 120.765 256.426C120.765 256.572 120.846 256.661 121.008 256.695C121.562 256.806 121.993 256.909 122.301 257.002C122.608 257.088 122.838 257.211 122.992 257.374C123.145 257.527 123.261 257.753 123.337 258.052C123.414 258.351 123.504 258.769 123.606 259.306Z" fill="#3E5DE7"/>
|
||||
<path d="M123.606 259.306C123.64 259.46 123.73 259.537 123.875 259.537C124.02 259.537 124.105 259.46 124.131 259.306C124.233 258.769 124.323 258.351 124.4 258.052C124.485 257.745 124.6 257.514 124.745 257.361C124.899 257.199 125.129 257.075 125.436 256.99C125.752 256.904 126.187 256.806 126.742 256.695C126.904 256.661 126.985 256.572 126.985 256.426C126.985 256.281 126.904 256.192 126.742 256.158C126.187 256.047 125.756 255.944 125.449 255.85C125.151 255.757 124.925 255.633 124.771 255.479C124.626 255.326 124.511 255.1 124.425 254.801C124.349 254.494 124.25 254.076 124.131 253.547C124.105 253.393 124.02 253.316 123.875 253.316C123.73 253.316 123.64 253.393 123.606 253.547C123.495 254.076 123.397 254.494 123.312 254.801C123.235 255.1 123.12 255.326 122.966 255.479C122.821 255.633 122.595 255.757 122.288 255.85C121.989 255.944 121.562 256.047 121.008 256.158C120.846 256.192 120.765 256.281 120.765 256.426C120.765 256.572 120.846 256.661 121.008 256.695C121.562 256.806 121.993 256.909 122.301 257.002C122.608 257.088 122.838 257.211 122.992 257.374C123.145 257.527 123.261 257.753 123.337 258.052C123.414 258.351 123.504 258.769 123.606 259.306Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M133.283 262.417C133.317 262.57 133.406 262.647 133.551 262.647C133.697 262.647 133.782 262.57 133.807 262.417C133.91 261.879 133.999 261.461 134.076 261.162C134.162 260.855 134.277 260.625 134.422 260.471C134.575 260.309 134.806 260.185 135.113 260.1C135.429 260.015 135.864 259.917 136.419 259.806C136.581 259.771 136.662 259.682 136.662 259.537C136.662 259.392 136.581 259.302 136.419 259.268C135.864 259.157 135.433 259.055 135.126 258.961C134.827 258.867 134.601 258.743 134.447 258.59C134.302 258.436 134.187 258.21 134.102 257.911C134.025 257.604 133.927 257.186 133.807 256.657C133.782 256.503 133.697 256.427 133.551 256.427C133.406 256.427 133.317 256.503 133.283 256.657C133.172 257.186 133.074 257.604 132.988 257.911C132.911 258.21 132.796 258.436 132.643 258.59C132.498 258.743 132.271 258.867 131.964 258.961C131.666 259.055 131.239 259.157 130.684 259.268C130.522 259.302 130.441 259.392 130.441 259.537C130.441 259.682 130.522 259.771 130.684 259.806C131.239 259.917 131.67 260.019 131.977 260.113C132.284 260.198 132.515 260.322 132.668 260.484C132.822 260.638 132.937 260.864 133.014 261.162C133.091 261.461 133.18 261.879 133.283 262.417Z" fill="#3E5DE7"/>
|
||||
<path d="M133.283 262.417C133.317 262.57 133.406 262.647 133.551 262.647C133.697 262.647 133.782 262.57 133.807 262.417C133.91 261.879 133.999 261.461 134.076 261.162C134.162 260.855 134.277 260.625 134.422 260.471C134.575 260.309 134.806 260.185 135.113 260.1C135.429 260.015 135.864 259.917 136.419 259.806C136.581 259.771 136.662 259.682 136.662 259.537C136.662 259.392 136.581 259.302 136.419 259.268C135.864 259.157 135.433 259.055 135.126 258.961C134.827 258.867 134.601 258.743 134.447 258.59C134.302 258.436 134.187 258.21 134.102 257.911C134.025 257.604 133.927 257.186 133.807 256.657C133.782 256.503 133.697 256.427 133.551 256.427C133.406 256.427 133.317 256.503 133.283 256.657C133.172 257.186 133.074 257.604 132.988 257.911C132.911 258.21 132.796 258.436 132.643 258.59C132.498 258.743 132.271 258.867 131.964 258.961C131.666 259.055 131.239 259.157 130.684 259.268C130.522 259.302 130.441 259.392 130.441 259.537C130.441 259.682 130.522 259.771 130.684 259.806C131.239 259.917 131.67 260.019 131.977 260.113C132.284 260.198 132.515 260.322 132.668 260.484C132.822 260.638 132.937 260.864 133.014 261.162C133.091 261.461 133.18 261.879 133.283 262.417Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M98.4764 197.395C98.52 197.583 98.6345 197.676 98.8198 197.676C99.0052 197.676 99.1142 197.583 99.1469 197.395C99.2778 196.738 99.3923 196.227 99.4904 195.862C99.5994 195.486 99.7466 195.205 99.932 195.017C100.128 194.819 100.423 194.668 100.815 194.563C101.219 194.459 101.775 194.339 102.483 194.203C102.691 194.162 102.794 194.052 102.794 193.875C102.794 193.698 102.691 193.588 102.483 193.546C101.775 193.411 101.224 193.286 100.832 193.171C100.45 193.056 100.161 192.905 99.9647 192.717C99.7793 192.53 99.6321 192.253 99.5231 191.888C99.425 191.513 99.2996 191.002 99.1469 190.355C99.1142 190.167 99.0052 190.073 98.8198 190.073C98.6345 190.073 98.52 190.167 98.4764 190.355C98.3346 191.002 98.2093 191.513 98.1002 191.888C98.0021 192.253 97.8549 192.53 97.6586 192.717C97.4733 192.905 97.1843 193.056 96.7918 193.171C96.4102 193.286 95.865 193.411 95.1563 193.546C94.9492 193.588 94.8456 193.698 94.8456 193.875C94.8456 194.052 94.9492 194.162 95.1563 194.203C95.865 194.339 96.4157 194.464 96.8082 194.579C97.2007 194.683 97.4951 194.834 97.6914 195.033C97.8876 195.22 98.0348 195.497 98.1329 195.862C98.2311 196.227 98.3456 196.738 98.4764 197.395Z" fill="#3E5DE7"/>
|
||||
<path d="M98.4764 197.395C98.52 197.583 98.6345 197.676 98.8198 197.676C99.0052 197.676 99.1142 197.583 99.1469 197.395C99.2778 196.738 99.3923 196.227 99.4904 195.862C99.5994 195.486 99.7466 195.205 99.932 195.017C100.128 194.819 100.423 194.668 100.815 194.563C101.219 194.459 101.775 194.339 102.483 194.203C102.691 194.162 102.794 194.052 102.794 193.875C102.794 193.698 102.691 193.588 102.483 193.546C101.775 193.411 101.224 193.286 100.832 193.171C100.45 193.056 100.161 192.905 99.9647 192.717C99.7793 192.53 99.6321 192.253 99.5231 191.888C99.425 191.513 99.2996 191.002 99.1469 190.355C99.1142 190.167 99.0052 190.073 98.8198 190.073C98.6345 190.073 98.52 190.167 98.4764 190.355C98.3346 191.002 98.2093 191.513 98.1002 191.888C98.0021 192.253 97.8549 192.53 97.6586 192.717C97.4733 192.905 97.1843 193.056 96.7918 193.171C96.4102 193.286 95.865 193.411 95.1563 193.546C94.9492 193.588 94.8456 193.698 94.8456 193.875C94.8456 194.052 94.9492 194.162 95.1563 194.203C95.865 194.339 96.4157 194.464 96.8082 194.579C97.2007 194.683 97.4951 194.834 97.6914 195.033C97.8876 195.22 98.0348 195.497 98.1329 195.862C98.2311 196.227 98.3456 196.738 98.4764 197.395Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M301.239 258.615C301.273 258.769 301.362 258.846 301.507 258.846C301.652 258.846 301.738 258.769 301.763 258.615C301.866 258.078 301.955 257.659 302.032 257.361C302.118 257.054 302.233 256.823 302.378 256.67C302.531 256.508 302.762 256.384 303.069 256.298C303.385 256.213 303.82 256.115 304.374 256.004C304.537 255.97 304.618 255.88 304.618 255.735C304.618 255.59 304.537 255.501 304.374 255.467C303.82 255.356 303.389 255.253 303.082 255.159C302.783 255.065 302.557 254.942 302.403 254.788C302.258 254.635 302.143 254.408 302.058 254.11C301.981 253.803 301.883 253.384 301.763 252.855C301.738 252.702 301.652 252.625 301.507 252.625C301.362 252.625 301.273 252.702 301.239 252.855C301.128 253.384 301.03 253.803 300.944 254.11C300.867 254.408 300.752 254.635 300.599 254.788C300.454 254.942 300.227 255.065 299.92 255.159C299.622 255.253 299.195 255.356 298.64 255.467C298.478 255.501 298.397 255.59 298.397 255.735C298.397 255.88 298.478 255.97 298.64 256.004C299.195 256.115 299.626 256.217 299.933 256.311C300.24 256.397 300.471 256.52 300.624 256.682C300.778 256.836 300.893 257.062 300.97 257.361C301.047 257.659 301.136 258.078 301.239 258.615Z" fill="#3E5DE7"/>
|
||||
<path d="M301.239 258.615C301.273 258.769 301.362 258.846 301.507 258.846C301.652 258.846 301.738 258.769 301.763 258.615C301.866 258.078 301.955 257.659 302.032 257.361C302.118 257.054 302.233 256.823 302.378 256.67C302.531 256.508 302.762 256.384 303.069 256.298C303.385 256.213 303.82 256.115 304.374 256.004C304.537 255.97 304.618 255.88 304.618 255.735C304.618 255.59 304.537 255.501 304.374 255.467C303.82 255.356 303.389 255.253 303.082 255.159C302.783 255.065 302.557 254.942 302.403 254.788C302.258 254.635 302.143 254.408 302.058 254.11C301.981 253.803 301.883 253.384 301.763 252.855C301.738 252.702 301.652 252.625 301.507 252.625C301.362 252.625 301.273 252.702 301.239 252.855C301.128 253.384 301.03 253.803 300.944 254.11C300.867 254.408 300.752 254.635 300.599 254.788C300.454 254.942 300.227 255.065 299.92 255.159C299.622 255.253 299.195 255.356 298.64 255.467C298.478 255.501 298.397 255.59 298.397 255.735C298.397 255.88 298.478 255.97 298.64 256.004C299.195 256.115 299.626 256.217 299.933 256.311C300.24 256.397 300.471 256.52 300.624 256.682C300.778 256.836 300.893 257.062 300.97 257.361C301.047 257.659 301.136 258.078 301.239 258.615Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M310.915 261.726C310.949 261.879 311.039 261.956 311.184 261.956C311.329 261.956 311.414 261.879 311.44 261.726C311.542 261.188 311.632 260.77 311.709 260.471C311.794 260.164 311.909 259.934 312.054 259.78C312.208 259.618 312.438 259.494 312.745 259.409C313.061 259.323 313.496 259.225 314.051 259.114C314.213 259.08 314.294 258.991 314.294 258.846C314.294 258.701 314.213 258.611 314.051 258.577C313.496 258.466 313.065 258.364 312.758 258.27C312.459 258.176 312.233 258.052 312.08 257.898C311.935 257.745 311.819 257.519 311.734 257.22C311.657 256.913 311.559 256.495 311.44 255.966C311.414 255.812 311.329 255.735 311.184 255.735C311.039 255.735 310.949 255.812 310.915 255.966C310.804 256.495 310.706 256.913 310.621 257.22C310.544 257.519 310.429 257.745 310.275 257.898C310.13 258.052 309.904 258.176 309.597 258.27C309.298 258.364 308.871 258.466 308.317 258.577C308.155 258.611 308.073 258.701 308.073 258.846C308.073 258.991 308.155 259.08 308.317 259.114C308.871 259.225 309.302 259.328 309.609 259.422C309.917 259.507 310.147 259.631 310.301 259.793C310.454 259.946 310.569 260.173 310.646 260.471C310.723 260.77 310.813 261.188 310.915 261.726Z" fill="#3E5DE7"/>
|
||||
<path d="M310.915 261.726C310.949 261.879 311.039 261.956 311.184 261.956C311.329 261.956 311.414 261.879 311.44 261.726C311.542 261.188 311.632 260.77 311.709 260.471C311.794 260.164 311.909 259.934 312.054 259.78C312.208 259.618 312.438 259.494 312.745 259.409C313.061 259.323 313.496 259.225 314.051 259.114C314.213 259.08 314.294 258.991 314.294 258.846C314.294 258.701 314.213 258.611 314.051 258.577C313.496 258.466 313.065 258.364 312.758 258.27C312.459 258.176 312.233 258.052 312.08 257.898C311.935 257.745 311.819 257.519 311.734 257.22C311.657 256.913 311.559 256.495 311.44 255.966C311.414 255.812 311.329 255.735 311.184 255.735C311.039 255.735 310.949 255.812 310.915 255.966C310.804 256.495 310.706 256.913 310.621 257.22C310.544 257.519 310.429 257.745 310.275 257.898C310.13 258.052 309.904 258.176 309.597 258.27C309.298 258.364 308.871 258.466 308.317 258.577C308.155 258.611 308.073 258.701 308.073 258.846C308.073 258.991 308.155 259.08 308.317 259.114C308.871 259.225 309.302 259.328 309.609 259.422C309.917 259.507 310.147 259.631 310.301 259.793C310.454 259.946 310.569 260.173 310.646 260.471C310.723 260.77 310.813 261.188 310.915 261.726Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M305.731 173.255C305.765 173.408 305.855 173.485 306 173.485C306.145 173.485 306.23 173.408 306.256 173.255C306.358 172.717 306.448 172.299 306.525 172C306.61 171.693 306.725 171.463 306.87 171.309C307.024 171.147 307.254 171.023 307.562 170.938C307.877 170.853 308.312 170.755 308.867 170.644C309.029 170.61 309.11 170.52 309.11 170.375C309.11 170.23 309.029 170.14 308.867 170.106C308.312 169.995 307.882 169.893 307.574 169.799C307.276 169.705 307.05 169.581 306.896 169.428C306.751 169.274 306.636 169.048 306.55 168.749C306.474 168.442 306.375 168.024 306.256 167.495C306.23 167.341 306.145 167.265 306 167.265C305.855 167.265 305.765 167.341 305.731 167.495C305.62 168.024 305.522 168.442 305.437 168.749C305.36 169.048 305.245 169.274 305.091 169.428C304.946 169.581 304.72 169.705 304.413 169.799C304.114 169.893 303.688 169.995 303.133 170.106C302.971 170.14 302.89 170.23 302.89 170.375C302.89 170.52 302.971 170.61 303.133 170.644C303.688 170.755 304.118 170.857 304.426 170.951C304.733 171.036 304.963 171.16 305.117 171.322C305.27 171.476 305.386 171.702 305.462 172C305.539 172.299 305.629 172.717 305.731 173.255Z" fill="#3E5DE7"/>
|
||||
<path d="M305.731 173.255C305.765 173.408 305.855 173.485 306 173.485C306.145 173.485 306.23 173.408 306.256 173.255C306.358 172.717 306.448 172.299 306.525 172C306.61 171.693 306.725 171.463 306.87 171.309C307.024 171.147 307.254 171.023 307.562 170.938C307.877 170.853 308.312 170.755 308.867 170.644C309.029 170.61 309.11 170.52 309.11 170.375C309.11 170.23 309.029 170.14 308.867 170.106C308.312 169.995 307.882 169.893 307.574 169.799C307.276 169.705 307.05 169.581 306.896 169.428C306.751 169.274 306.636 169.048 306.55 168.749C306.474 168.442 306.375 168.024 306.256 167.495C306.23 167.341 306.145 167.265 306 167.265C305.855 167.265 305.765 167.341 305.731 167.495C305.62 168.024 305.522 168.442 305.437 168.749C305.36 169.048 305.245 169.274 305.091 169.428C304.946 169.581 304.72 169.705 304.413 169.799C304.114 169.893 303.688 169.995 303.133 170.106C302.971 170.14 302.89 170.23 302.89 170.375C302.89 170.52 302.971 170.61 303.133 170.644C303.688 170.755 304.118 170.857 304.426 170.951C304.733 171.036 304.963 171.16 305.117 171.322C305.27 171.476 305.386 171.702 305.462 172C305.539 172.299 305.629 172.717 305.731 173.255Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M317.933 255.3C317.998 255.59 318.167 255.735 318.441 255.735C318.715 255.735 318.876 255.59 318.925 255.3C319.118 254.285 319.287 253.495 319.432 252.931C319.594 252.351 319.811 251.915 320.085 251.625C320.375 251.319 320.811 251.085 321.391 250.924C321.987 250.763 322.809 250.578 323.857 250.368C324.163 250.304 324.316 250.134 324.316 249.86C324.316 249.586 324.163 249.417 323.857 249.353C322.809 249.143 321.995 248.95 321.415 248.772C320.851 248.595 320.424 248.361 320.134 248.071C319.86 247.781 319.642 247.354 319.481 246.79C319.336 246.21 319.15 245.42 318.925 244.421C318.876 244.13 318.715 243.985 318.441 243.985C318.167 243.985 317.998 244.13 317.933 244.421C317.724 245.42 317.539 246.21 317.377 246.79C317.232 247.354 317.015 247.781 316.725 248.071C316.451 248.361 316.023 248.595 315.443 248.772C314.879 248.95 314.073 249.143 313.026 249.353C312.719 249.417 312.566 249.586 312.566 249.86C312.566 250.134 312.719 250.304 313.026 250.368C314.073 250.578 314.887 250.771 315.467 250.948C316.048 251.109 316.483 251.343 316.773 251.649C317.063 251.94 317.281 252.367 317.426 252.931C317.571 253.495 317.74 254.285 317.933 255.3Z" fill="#3E5DE7"/>
|
||||
<path d="M317.933 255.3C317.998 255.59 318.167 255.735 318.441 255.735C318.715 255.735 318.876 255.59 318.925 255.3C319.118 254.285 319.287 253.495 319.432 252.931C319.594 252.351 319.811 251.915 320.085 251.625C320.375 251.319 320.811 251.085 321.391 250.924C321.987 250.763 322.809 250.578 323.857 250.368C324.163 250.304 324.316 250.134 324.316 249.86C324.316 249.586 324.163 249.417 323.857 249.353C322.809 249.143 321.995 248.95 321.415 248.772C320.851 248.595 320.424 248.361 320.134 248.071C319.86 247.781 319.642 247.354 319.481 246.79C319.336 246.21 319.15 245.42 318.925 244.421C318.876 244.13 318.715 243.985 318.441 243.985C318.167 243.985 317.998 244.13 317.933 244.421C317.724 245.42 317.539 246.21 317.377 246.79C317.232 247.354 317.015 247.781 316.725 248.071C316.451 248.361 316.023 248.595 315.443 248.772C314.879 248.95 314.073 249.143 313.026 249.353C312.719 249.417 312.566 249.586 312.566 249.86C312.566 250.134 312.719 250.304 313.026 250.368C314.073 250.578 314.887 250.771 315.467 250.948C316.048 251.109 316.483 251.343 316.773 251.649C317.063 251.94 317.281 252.367 317.426 252.931C317.571 253.495 317.74 254.285 317.933 255.3Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path d="M296.507 171.668C296.571 171.958 296.741 172.103 297.015 172.103C297.289 172.103 297.45 171.958 297.498 171.668C297.692 170.652 297.861 169.863 298.006 169.298C298.167 168.718 298.385 168.283 298.659 167.993C298.949 167.687 299.384 167.453 299.964 167.292C300.561 167.131 301.383 166.945 302.43 166.736C302.737 166.671 302.89 166.502 302.89 166.228C302.89 165.954 302.737 165.785 302.43 165.72C301.383 165.511 300.569 165.317 299.988 165.14C299.424 164.963 298.997 164.729 298.707 164.439C298.433 164.149 298.215 163.722 298.054 163.157C297.909 162.577 297.724 161.787 297.498 160.788C297.45 160.498 297.289 160.353 297.015 160.353C296.741 160.353 296.571 160.498 296.507 160.788C296.297 161.787 296.112 162.577 295.951 163.157C295.806 163.722 295.588 164.149 295.298 164.439C295.024 164.729 294.597 164.963 294.017 165.14C293.453 165.317 292.647 165.511 291.599 165.72C291.293 165.785 291.14 165.954 291.14 166.228C291.14 166.502 291.293 166.671 291.599 166.736C292.647 166.945 293.461 167.139 294.041 167.316C294.621 167.477 295.056 167.711 295.346 168.017C295.637 168.307 295.854 168.734 295.999 169.298C296.144 169.863 296.314 170.652 296.507 171.668Z" fill="#3E5DE7"/>
|
||||
<path d="M296.507 171.668C296.571 171.958 296.741 172.103 297.015 172.103C297.289 172.103 297.45 171.958 297.498 171.668C297.692 170.652 297.861 169.863 298.006 169.298C298.167 168.718 298.385 168.283 298.659 167.993C298.949 167.687 299.384 167.453 299.964 167.292C300.561 167.131 301.383 166.945 302.43 166.736C302.737 166.671 302.89 166.502 302.89 166.228C302.89 165.954 302.737 165.785 302.43 165.72C301.383 165.511 300.569 165.317 299.988 165.14C299.424 164.963 298.997 164.729 298.707 164.439C298.433 164.149 298.215 163.722 298.054 163.157C297.909 162.577 297.724 161.787 297.498 160.788C297.45 160.498 297.289 160.353 297.015 160.353C296.741 160.353 296.571 160.498 296.507 160.788C296.297 161.787 296.112 162.577 295.951 163.157C295.806 163.722 295.588 164.149 295.298 164.439C295.024 164.729 294.597 164.963 294.017 165.14C293.453 165.317 292.647 165.511 291.599 165.72C291.293 165.785 291.14 165.954 291.14 166.228C291.14 166.502 291.293 166.671 291.599 166.736C292.647 166.945 293.461 167.139 294.041 167.316C294.621 167.477 295.056 167.711 295.346 168.017C295.637 168.307 295.854 168.734 295.999 169.298C296.144 169.863 296.314 170.652 296.507 171.668Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<circle cx="123.184" cy="191.11" r="13.4779" fill="#626B81"/>
|
||||
<circle cx="123.184" cy="191.11" r="13.4779" fill="#F7F8FA" fill-opacity="0.9"/>
|
||||
<path d="M126.88 184.465C126.88 184.01 126.88 183.782 126.833 183.574C126.745 183.19 126.541 182.842 126.247 182.579C126.088 182.437 125.889 182.327 125.491 182.106L124.473 181.541C124.097 181.333 123.909 181.228 123.715 181.17C123.356 181.061 122.973 181.061 122.615 181.17C122.421 181.228 122.232 181.333 121.856 181.541L121.436 181.774C120.927 182.057 120.672 182.198 120.556 182.362C120.337 182.67 120.338 183.082 120.556 183.389C120.673 183.554 120.928 183.695 121.438 183.977L121.777 184.165C122.176 184.385 122.376 184.496 122.535 184.638C122.829 184.901 123.034 185.249 123.122 185.633C123.169 185.841 123.169 186.069 123.169 186.525V186.914C123.169 187.467 123.169 187.743 123.252 187.921C123.407 188.254 123.751 188.456 124.117 188.431C124.313 188.417 124.555 188.283 125.038 188.015L125.49 187.765C125.889 187.544 126.088 187.433 126.247 187.291C126.541 187.028 126.745 186.681 126.833 186.296C126.88 186.088 126.88 185.861 126.88 185.405V184.465Z" fill="#3E5DE7"/>
|
||||
<path d="M119.267 184.57C118.873 184.342 118.676 184.228 118.472 184.165C118.096 184.049 117.692 184.052 117.318 184.175C117.115 184.242 116.92 184.359 116.53 184.594L115.532 185.193C115.163 185.414 114.979 185.525 114.831 185.664C114.557 185.92 114.366 186.251 114.281 186.616C114.235 186.814 114.231 187.029 114.223 187.459L114.215 187.939C114.205 188.521 114.2 188.812 114.284 188.996C114.441 189.339 114.798 189.544 115.174 189.509C115.374 189.49 115.624 189.34 116.123 189.039L116.456 188.839C116.846 188.604 117.042 188.486 117.244 188.42C117.619 188.296 118.023 188.293 118.4 188.409C118.604 188.472 118.801 188.586 119.196 188.814L119.533 189.009C120.011 189.285 120.25 189.423 120.446 189.44C120.812 189.472 121.16 189.275 121.32 188.945C121.406 188.769 121.411 188.493 121.421 187.94L121.43 187.423C121.438 186.968 121.442 186.74 121.398 186.531C121.318 186.146 121.119 185.794 120.83 185.527C120.673 185.382 120.476 185.268 120.082 185.04L119.267 184.57Z" fill="#3E5DE7"/>
|
||||
<path d="M115.552 191.215C115.157 191.443 114.96 191.557 114.804 191.702C114.515 191.97 114.316 192.321 114.235 192.706C114.192 192.915 114.196 193.143 114.203 193.598L114.223 194.762C114.231 195.192 114.235 195.407 114.281 195.604C114.366 195.969 114.557 196.301 114.831 196.557C114.979 196.696 115.163 196.806 115.532 197.028L115.943 197.275C116.443 197.575 116.692 197.725 116.893 197.744C117.269 197.779 117.625 197.573 117.782 197.23C117.866 197.047 117.861 196.755 117.85 196.173L117.843 195.785C117.835 195.329 117.831 195.101 117.874 194.892C117.955 194.506 118.154 194.154 118.443 193.886C118.599 193.741 118.797 193.627 119.192 193.399L119.529 193.205C120.007 192.929 120.246 192.79 120.359 192.63C120.57 192.329 120.573 191.929 120.368 191.625C120.258 191.462 120.021 191.32 119.547 191.035L119.104 190.769C118.714 190.535 118.519 190.417 118.316 190.351C117.942 190.228 117.538 190.224 117.162 190.341C116.958 190.404 116.761 190.517 116.366 190.745L115.552 191.215Z" fill="#3E5DE7"/>
|
||||
<path d="M119.449 197.756C119.449 198.211 119.449 198.439 119.496 198.647C119.584 199.031 119.789 199.379 120.082 199.641C120.241 199.784 120.44 199.894 120.838 200.115L121.856 200.679C122.232 200.888 122.421 200.992 122.615 201.051C122.973 201.159 123.356 201.159 123.715 201.051C123.909 200.992 124.097 200.888 124.473 200.679L124.893 200.447C125.402 200.164 125.657 200.023 125.774 199.858C125.992 199.551 125.992 199.139 125.773 198.831C125.656 198.667 125.401 198.526 124.892 198.244L124.552 198.056C124.153 197.835 123.954 197.725 123.795 197.583C123.5 197.32 123.295 196.972 123.208 196.587C123.16 196.379 123.16 196.151 123.16 195.696V195.307C123.16 194.754 123.16 194.478 123.077 194.3C122.922 193.967 122.578 193.764 122.212 193.79C122.016 193.804 121.774 193.938 121.291 194.205L120.839 194.456C120.441 194.677 120.241 194.787 120.082 194.929C119.789 195.192 119.584 195.54 119.496 195.924C119.449 196.132 119.449 196.36 119.449 196.816V197.756Z" fill="#3E5DE7"/>
|
||||
<path d="M127.062 197.651C127.456 197.878 127.654 197.992 127.857 198.055C128.234 198.172 128.637 198.168 129.012 198.045C129.214 197.979 129.409 197.862 129.8 197.627L130.797 197.028C131.166 196.806 131.351 196.696 131.499 196.557C131.772 196.301 131.963 195.969 132.049 195.604C132.095 195.407 132.098 195.192 132.106 194.762L132.114 194.282C132.124 193.699 132.129 193.408 132.045 193.225C131.888 192.882 131.531 192.676 131.156 192.712C130.955 192.731 130.705 192.881 130.206 193.181L129.873 193.382C129.483 193.617 129.288 193.734 129.085 193.801C128.71 193.924 128.306 193.928 127.93 193.812C127.726 193.748 127.528 193.635 127.134 193.407L126.797 193.212C126.318 192.936 126.079 192.798 125.883 192.781C125.517 192.749 125.17 192.945 125.009 193.275C124.923 193.452 124.918 193.728 124.908 194.28L124.899 194.797C124.891 195.253 124.887 195.48 124.931 195.689C125.012 196.075 125.21 196.426 125.5 196.694C125.656 196.839 125.853 196.953 126.248 197.181L127.062 197.651Z" fill="#3E5DE7"/>
|
||||
<path d="M130.777 191.005C131.172 190.778 131.369 190.664 131.525 190.519C131.815 190.251 132.013 189.9 132.094 189.514C132.138 189.306 132.134 189.078 132.126 188.623L132.106 187.459C132.098 187.029 132.095 186.814 132.049 186.616C131.963 186.251 131.772 185.92 131.499 185.664C131.351 185.525 131.166 185.414 130.797 185.193L130.386 184.946C129.887 184.646 129.637 184.496 129.436 184.477C129.061 184.442 128.704 184.648 128.547 184.991C128.463 185.174 128.468 185.465 128.479 186.048L128.486 186.436C128.494 186.892 128.499 187.12 128.455 187.329C128.374 187.715 128.176 188.066 127.886 188.334C127.73 188.479 127.533 188.593 127.138 188.821L126.801 189.016C126.322 189.292 126.083 189.43 125.97 189.591C125.76 189.892 125.756 190.291 125.962 190.596C126.072 190.758 126.308 190.901 126.782 191.185L127.225 191.451C127.615 191.686 127.811 191.803 128.013 191.87C128.388 191.993 128.791 191.997 129.168 191.88C129.372 191.817 129.569 191.703 129.963 191.475L130.777 191.005Z" fill="#3E5DE7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M168.96 271.693L174.451 269.61L170.142 240.228L178.631 223.659L167.226 216.697C167.226 216.697 161.044 232.681 160.733 237.954C160.194 247.19 168.96 271.693 168.96 271.693Z" fill="#EAC7B2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M163.767 219.969L179.051 225.658L184.151 207.603L172.152 203.571L163.767 219.969Z" fill="#C83F49"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M163.767 219.969L179.051 225.658L184.151 207.603L172.152 203.571L163.767 219.969Z" fill="black" fill-opacity="0.2"/>
|
||||
<path d="M249.896 205.112L248.148 221.171" stroke="#3E5DE7" stroke-width="3.55566" stroke-linecap="round"/>
|
||||
<path d="M250.335 201.52L249.77 206.256" stroke="#3E5DE7" stroke-width="2.22229" stroke-linecap="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M250.79 200.774C246.464 200.533 243.196 196.038 243.491 190.733C243.785 185.427 247.531 181.322 251.858 181.562C256.184 181.803 259.452 186.298 259.157 191.603C258.863 196.908 255.117 201.014 250.79 200.774Z" stroke="#3E5DE7" stroke-width="3.55566" stroke-linecap="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M187.409 413.727H154.096L155.288 394.101L164.884 397.332L163.824 404.291C163.824 404.291 179.599 408.051 187.409 413.727Z" fill="#3B3B59"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M210.051 413.727H178.64L179.832 394.101L189.431 397.332L188.369 404.291C188.369 404.291 202.241 408.051 210.051 413.727Z" fill="#3B3B59"/>
|
||||
<path d="M164.721 398.508L163.824 404.287L154.683 404.038L155.071 395.616L164.721 398.508ZM189.269 398.508L188.368 404.287L179.227 404.038L179.615 395.616L189.269 398.508Z" fill="#EAC7B2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M203.963 225.704C203.963 225.704 219.447 242.405 226.744 240.241C236.291 237.421 249.189 216.258 249.189 216.258L242.961 213.214L225.436 228.327L209.286 213.554L203.963 225.704Z" fill="#EAC7B2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M221.485 220.525L213.734 237.611L204.367 228.76C204.367 228.76 203.973 231.238 201.728 235.253C199.563 239.231 197.75 243.39 196.311 247.684L165.763 245.168C165.763 245.168 168.082 235.799 168.479 229.015C168.928 221.384 167.81 201.668 176.476 198.709C183.97 196.151 186.014 198.774 196.444 200.809C206.266 202.731 221.485 220.525 221.485 220.525Z" fill="#C83F49"/>
|
||||
<path d="M175.392 245.954L175.387 245.839L196.32 247.684C196.331 247.705 199.071 253.196 200.36 268.276C202.699 295.909 201.06 322.135 201.056 322.203L192.276 396.565L194.24 396.618L194.091 402.294L174.192 401.77L174.342 396.093L176.644 396.154L178.776 322.726L178.126 308.005L176.412 326.571L168.062 395.975L169.843 396.023L169.693 401.701L149.794 401.175L149.943 395.499L152.534 395.566L155.41 324.739C155.41 324.739 155.908 286.589 157.068 270.999C158.457 252.322 165.736 245.206 165.766 245.177L175.392 245.954Z" fill="#3B3B59"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M196.825 200.544C196.825 200.544 205.972 199.704 207.904 197.126C213.336 189.864 206.201 170.39 206.201 170.39L185.113 183.057C185.113 183.057 181.728 200.589 181.786 200.606L195.307 204.421L196.825 200.544Z" fill="#EAC7B2"/>
|
||||
<path d="M180.417 145.147C186.389 145.147 191.231 149.989 191.231 155.963C191.231 157.37 190.958 158.714 190.469 159.948C191.111 159.894 191.763 159.869 192.422 159.875C197.251 159.885 201.921 161.613 205.594 164.75C209.434 168.071 211.811 172.81 211.76 178.053C211.754 178.741 211.705 179.427 211.614 180.108C210.819 186.093 206.843 191.159 201.312 193.844L199.58 218.897L179.212 217.514C174.128 217.169 170.307 212.497 170.684 207.057L172.763 176.994C172.774 176.774 172.788 176.554 172.808 176.337L172.826 176.089H172.835C173.232 172.385 174.843 169.015 177.294 166.318C172.845 164.977 169.603 160.85 169.603 155.963C169.604 149.989 174.445 145.147 180.417 145.147Z" fill="#3B3B59"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M174.09 269.826L176.221 328.16L177.646 309.575L174.09 269.826Z" fill="black" fill-opacity="0.2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M202.787 188.934C202.787 188.934 204.463 185.361 201.65 184.537C199.554 183.923 198.349 185.597 197.984 186.663C196.75 190.255 200.797 192.041 201.379 195.078" fill="#EAC7B2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M241.783 214.361L242.722 212.497C242.722 212.497 244.337 209.183 245.306 207.92C246.873 205.865 248.859 207.351 248.859 207.351C248.859 207.351 252.648 205.287 253.591 205.716C256.195 206.905 255.739 216.513 253.268 217.421C251.356 218.122 250.171 219.013 247.703 219.646C246.657 219.914 245.303 219.404 244.518 219.453" fill="#EAC7B2"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M214.729 235.424L220.139 223.487L217.18 237.156L214.729 235.424Z" fill="black" fill-opacity="0.2"/>
|
||||
<path d="M308.729 320.36C308.729 320.36 310.796 322.503 312.455 325.792C314.198 322.569 316.291 320.486 316.291 320.486C316.291 320.486 318.542 324.533 318.439 329.692C321.408 326.806 324.32 325.112 324.324 325.11C324.332 325.168 325.136 330.9 321.669 336.747C320.208 339.211 318.219 341.303 316.403 342.903C317.03 345.372 316.986 347.08 316.986 347.08C316.96 347.068 315.56 346.371 313.648 345.097C312.483 345.935 311.703 346.392 311.703 346.392C311.703 346.392 311.553 345.34 311.652 343.677C309.717 342.203 307.596 340.287 305.919 338.005C301.755 332.335 301.907 326.548 301.907 326.548C301.93 326.559 303.88 327.529 306.328 329.281C306.442 324.261 308.714 320.386 308.729 320.36Z" fill="#626B81"/>
|
||||
<path d="M308.729 320.36C308.729 320.36 310.796 322.503 312.455 325.792C314.198 322.569 316.291 320.486 316.291 320.486C316.291 320.486 318.542 324.533 318.439 329.692C321.408 326.806 324.32 325.112 324.324 325.11C324.332 325.168 325.136 330.9 321.669 336.747C320.208 339.211 318.219 341.303 316.403 342.903C317.03 345.372 316.986 347.08 316.986 347.08C316.96 347.068 315.56 346.371 313.648 345.097C312.483 345.935 311.703 346.392 311.703 346.392C311.703 346.392 311.553 345.34 311.652 343.677C309.717 342.203 307.596 340.287 305.919 338.005C301.755 332.335 301.907 326.548 301.907 326.548C301.93 326.559 303.88 327.529 306.328 329.281C306.442 324.261 308.714 320.386 308.729 320.36Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M345.889 355.501C345.889 367.955 331.235 378.051 313.158 378.051C295.081 378.051 280.426 367.955 280.426 355.501C280.426 343.047 295.081 332.951 313.158 332.951C331.235 332.951 345.889 343.047 345.889 355.501Z" fill="#626B81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M345.889 355.501C345.889 367.955 331.235 378.051 313.158 378.051C295.081 378.051 280.426 367.955 280.426 355.501C280.426 343.047 295.081 332.951 313.158 332.951C331.235 332.951 345.889 343.047 345.889 355.501Z" fill="#F7F8FA" fill-opacity="0.75"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M333.432 395.699H296.202C290.488 395.699 285.856 391.067 285.856 385.353V383.57C285.856 377.856 290.488 373.224 296.202 373.224H333.432C339.145 373.224 343.777 377.856 343.777 383.57V385.353C343.777 391.067 339.145 395.699 333.432 395.699Z" fill="#626B81"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M333.432 395.699H296.202C290.488 395.699 285.856 391.067 285.856 385.353V383.57C285.856 377.856 290.488 373.224 296.202 373.224H333.432C339.145 373.224 343.777 377.856 343.777 383.57V385.353C343.777 391.067 339.145 395.699 333.432 395.699Z" fill="#F7F8FA" fill-opacity="0.65"/>
|
||||
<path d="M294.454 339.588L288.421 334.912" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M294.454 339.588L288.421 334.912" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="2.03096"/>
|
||||
<path d="M285.857 363.782L280.426 367.501" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M285.857 363.782L280.426 367.501" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="2.03096"/>
|
||||
<path d="M301.638 361.753L311.009 363.274" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M301.638 361.753L311.009 363.274" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="2.03096"/>
|
||||
<path d="M325.6 338.827L331.258 331.875" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M325.6 338.827L331.258 331.875" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="2.03096"/>
|
||||
<path d="M335.934 346.392L342.118 342.453" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M335.934 346.392L342.118 342.453" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="2.03096"/>
|
||||
<path d="M337.141 366.738L343.023 370.509" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M337.141 366.738L343.023 370.509" stroke="#F7F8FA" stroke-opacity="0.65" stroke-width="2.03096"/>
|
||||
<path d="M304.358 347.949L301.559 341.478" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M304.358 347.949L301.559 341.478" stroke="#F7F8FA" stroke-opacity="0.975" stroke-width="2.03096"/>
|
||||
<path d="M331.137 355.007L324.41 358.191" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M331.137 355.007L324.41 358.191" stroke="#F7F8FA" stroke-opacity="0.975" stroke-width="2.03096"/>
|
||||
<path d="M298.597 351.305L292.193 347.069" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M298.597 351.305L292.193 347.069" stroke="#F7F8FA" stroke-opacity="0.975" stroke-width="2.03096"/>
|
||||
<path d="M285.856 382.203L297.44 386.719L309.024 382.203L320.607 386.719L332.192 382.203L343.777 386.719" stroke="#626B81" stroke-width="2.03096"/>
|
||||
<path d="M285.856 382.203L297.44 386.719L309.024 382.203L320.607 386.719L332.192 382.203L343.777 386.719" stroke="#F7F8FA" stroke-opacity="0.75" stroke-width="2.03096"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_n_12246_5573" x="0.5" y="0" width="470" height="470" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feTurbulence type="fractalNoise" baseFrequency="2.8936169147491455 2.8936169147491455" stitchTiles="stitch" numOctaves="3" result="noise" seed="1493" />
|
||||
<feColorMatrix in="noise" type="luminanceToAlpha" result="alphaNoise" />
|
||||
<feComponentTransfer in="alphaNoise" result="coloredNoise1">
|
||||
<feFuncA type="discrete" tableValues="0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "/>
|
||||
</feComponentTransfer>
|
||||
<feComposite operator="in" in2="shape" in="coloredNoise1" result="noise1Clipped" />
|
||||
<feFlood flood-color="rgba(255, 255, 255, 0.2)" result="color1Flood" />
|
||||
<feComposite operator="in" in2="noise1Clipped" in="color1Flood" result="color1" />
|
||||
<feMerge result="effect1_noise_12246_5573">
|
||||
<feMergeNode in="shape" />
|
||||
<feMergeNode in="color1" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
<clipPath id="clip0_12246_5573">
|
||||
<rect width="470" height="470" fill="white" transform="translate(0.5)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_12246_5573">
|
||||
<rect width="470" height="470" fill="white" transform="translate(0.5)"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip2_12246_5573">
|
||||
<rect x="155.072" y="94.2147" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(11.3678 155.072 94.2147)" fill="white"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip3_12246_5573">
|
||||
<rect x="154.308" y="92.9633" width="30.3254" height="40.4338" rx="4.49265" transform="rotate(11.3678 154.308 92.9633)" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 97 KiB |
@@ -1,16 +1,16 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import Image from 'next/image';
|
||||
import _Image from 'next/image';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import IconDocs from '@/assets/icons/icon-docs.svg';
|
||||
import IconAssistant from '@/assets/logo/assistant.svg';
|
||||
import { Box, Icon, Text } from '@/components';
|
||||
import { productName } from '@/core';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { ProConnectButton, gotoLogin } from '@/features/auth';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import banner from '../assets/banner.jpg';
|
||||
import Banner from '../assets/banner.svg';
|
||||
|
||||
import { getHeaderHeight } from './HomeHeader';
|
||||
|
||||
@@ -44,11 +44,12 @@ export default function HomeBanner() {
|
||||
>
|
||||
<Box
|
||||
$width={!isMobile ? '50%' : '100%'}
|
||||
$maxWidth="400px"
|
||||
$justify="center"
|
||||
$align="center"
|
||||
$gap={spacingsTokens['sm']}
|
||||
$gap={spacingsTokens['md']}
|
||||
>
|
||||
<IconDocs
|
||||
<IconAssistant
|
||||
aria-label={t('{{productName}} Logo', { productName })}
|
||||
width={64}
|
||||
color={colorsTokens['primary-text']}
|
||||
@@ -64,15 +65,17 @@ export default function HomeBanner() {
|
||||
line-height: ${!isMobile ? '56px' : '45px'};
|
||||
`}
|
||||
>
|
||||
{t('Conversation with AI, simplified.')}
|
||||
{t('Your digital assistant')}
|
||||
</Text>
|
||||
<Text
|
||||
$padding={{ horizontal: 'base' }}
|
||||
$size="lg"
|
||||
$variation="700"
|
||||
$textAlign="center"
|
||||
$margin={{ bottom: 'small' }}
|
||||
>
|
||||
{t('Talk with an AI agent with all your collaborative tools.')}
|
||||
{t(
|
||||
'Ask questions, get help with writing, or find reliable information online — Assistant simplifies your work while keeping your data secure.',
|
||||
)}
|
||||
</Text>
|
||||
{withProConnect ? (
|
||||
<ProConnectButton />
|
||||
@@ -85,23 +88,9 @@ export default function HomeBanner() {
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
{!isMobile && (
|
||||
<Image
|
||||
className="c__image-system-filter"
|
||||
src={banner}
|
||||
alt={t('Banner image')}
|
||||
priority
|
||||
style={{
|
||||
width: 'auto',
|
||||
maxWidth: '100%',
|
||||
height: 'fit-content',
|
||||
overflow: 'auto',
|
||||
maxHeight: '100%',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{!isMobile && <Banner />}
|
||||
</Box>
|
||||
<Box $css="bottom: 3rem" $position="absolute">
|
||||
{/* <Box $css="bottom: 3rem" $position="absolute">
|
||||
<Button
|
||||
color="secondary"
|
||||
icon={
|
||||
@@ -116,7 +105,7 @@ export default function HomeBanner() {
|
||||
>
|
||||
{t('Show more')}
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>*/}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import IconDocs from '@/assets/icons/icon-docs.svg';
|
||||
import IconAssistant from '@/assets/logo/assistant.svg';
|
||||
import { Box, Text } from '@/components';
|
||||
import { productName } from '@/core';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
@@ -45,7 +45,7 @@ function HomeProConnect() {
|
||||
$height="fit-content"
|
||||
$css="zoom: 1.9;"
|
||||
>
|
||||
<IconDocs
|
||||
<IconAssistant
|
||||
aria-label={t('{{productName}} Logo', { productName })}
|
||||
width={34}
|
||||
color={colorsTokens['primary-text']}
|
||||
@@ -53,7 +53,7 @@ function HomeProConnect() {
|
||||
<Title />
|
||||
</Box>
|
||||
<Text $size="md" $variation="1000" $textAlign="center">
|
||||
{t('Conversations is already available, log in to use it now.')}
|
||||
{t('Assistant is already available, log in to use it now.')}
|
||||
</Text>
|
||||
<ProConnectButton />
|
||||
</Box>
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import { Box, Text } from '@/components';
|
||||
import { productName } from '@/core';
|
||||
import { Box } from '@/components';
|
||||
import { productName as _productName } from '@/core';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { Footer } from '@/features/footer';
|
||||
import { LeftPanel } from '@/features/left-panel';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import SC5 from '../assets/SC5.png';
|
||||
import GithubIcon from '../assets/github.svg';
|
||||
|
||||
import HomeBanner from './HomeBanner';
|
||||
import { HomeBottom } from './HomeBottom';
|
||||
import { HomeHeader, getHeaderHeight } from './HomeHeader';
|
||||
import { HomeSection } from './HomeSection';
|
||||
// import { HomeSection } from './HomeSection';
|
||||
|
||||
export function HomeContent() {
|
||||
const { t } = useTranslation();
|
||||
const { colorsTokens } = useCunninghamTheme();
|
||||
const { isMobile, isSmallMobile, isTablet } = useResponsiveStore();
|
||||
const { t: _t } = useTranslation();
|
||||
const { colorsTokens: _colorsTokens } = useCunninghamTheme();
|
||||
const {
|
||||
isMobile: _isMobile,
|
||||
isSmallMobile,
|
||||
isTablet: _isTablet,
|
||||
} = useResponsiveStore();
|
||||
|
||||
return (
|
||||
<Box as="main" className="--docs--home-content">
|
||||
@@ -45,7 +44,7 @@ export function HomeContent() {
|
||||
$margin="auto"
|
||||
>
|
||||
<HomeBanner />
|
||||
<Box
|
||||
{/* <Box
|
||||
id="docs-app-info"
|
||||
$maxWidth="100%"
|
||||
$gap={isMobile ? '115px' : '230px'}
|
||||
@@ -152,9 +151,9 @@ export function HomeContent() {
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
<HomeBottom />
|
||||
</Box>
|
||||
</Box>*/}
|
||||
{/* <HomeBottom />
|
||||
</Box>*/}
|
||||
</Box>
|
||||
<Footer />
|
||||
</Box>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import Image from 'next/image';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import IconDocs from '@/assets/icons/icon-docs.svg';
|
||||
import Logo from '@/assets/logo/logo-assistant.svg';
|
||||
import { Box } from '@/components';
|
||||
import { productName } from '@/core';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { ButtonTogglePanel, Title } from '@/features/header/';
|
||||
import { ButtonTogglePanel, Title as _Title } from '@/features/header/';
|
||||
import { LaGaufre } from '@/features/header/components/LaGaufre';
|
||||
import { LanguagePicker } from '@/features/language';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
@@ -62,12 +62,11 @@ export const HomeHeader = () => {
|
||||
$position="relative"
|
||||
$height="fit-content"
|
||||
>
|
||||
<IconDocs
|
||||
<Logo
|
||||
aria-label={t('{{productName}} Logo', { productName })}
|
||||
width={32}
|
||||
width={188}
|
||||
color={colorsTokens['primary-text']}
|
||||
/>
|
||||
<Title />
|
||||
</Box>
|
||||
</Box>
|
||||
{!isSmallMobile && (
|
||||
|
||||
@@ -9,12 +9,14 @@ import {
|
||||
getMatchingLocales,
|
||||
useSynchronizedLanguage,
|
||||
} from '@/features/language';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
export const LanguagePicker = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { data: conf } = useConfig();
|
||||
const { data: user } = useAuthQuery();
|
||||
const { changeLanguageSynchronized } = useSynchronizedLanguage();
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const language = i18n.language;
|
||||
|
||||
// Compute options for dropdown
|
||||
@@ -38,7 +40,7 @@ export const LanguagePicker = () => {
|
||||
return (
|
||||
<DropdownMenu
|
||||
options={optionsPicker}
|
||||
showArrow
|
||||
showArrow={isDesktop}
|
||||
buttonCss={css`
|
||||
&:hover {
|
||||
background-color: var(
|
||||
@@ -58,13 +60,14 @@ export const LanguagePicker = () => {
|
||||
>
|
||||
<Text
|
||||
$theme="primary"
|
||||
$size="md"
|
||||
aria-label={t('Language')}
|
||||
$direction="row"
|
||||
$gap="0.5rem"
|
||||
className="--docs--language-picker-text"
|
||||
>
|
||||
<Icon iconName="translate" $color="inherit" $size="xl" />
|
||||
{currentLanguageLabel}
|
||||
{isDesktop ? currentLanguageLabel : ''}
|
||||
</Text>
|
||||
</DropdownMenu>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.17334 8.58659C8.27636 8.58665 8.36372 8.62392 8.43506 8.69922C8.51036 8.77056 8.54763 8.85792 8.54769 8.96094C8.54769 9.06395 8.51026 9.1513 8.43506 9.22266C8.36372 9.294 8.27637 9.33002 8.17334 9.33008H4.97477C4.87164 9.33008 4.78445 9.29405 4.71305 9.22266C4.64171 9.15127 4.60563 9.06403 4.60563 8.96094C4.60569 8.85792 4.63982 8.77056 4.70719 8.69922C4.77856 8.624 4.86778 8.58659 4.97477 8.58659H8.17334Z" fill="#4A6AEF"/>
|
||||
<path d="M10.9598 6.68815C11.0669 6.68815 11.1566 6.72607 11.228 6.80143C11.2994 6.87677 11.3348 6.96213 11.3348 7.05729C11.3348 7.1643 11.2993 7.2535 11.228 7.32487C11.1566 7.39627 11.0669 7.43229 10.9598 7.43229H4.97477C4.87165 7.43229 4.78445 7.39626 4.71305 7.32487C4.64166 7.25348 4.60564 7.16438 4.60563 7.05729C4.60563 6.9621 4.63976 6.8768 4.70719 6.80143C4.77857 6.72616 4.86774 6.68815 4.97477 6.68815H10.9598Z" fill="#4A6AEF"/>
|
||||
<path d="M10.9598 4.80208C11.0669 4.80208 11.1566 4.83811 11.228 4.90951C11.2993 4.98087 11.3348 5.06626 11.3348 5.16536C11.3348 5.26839 11.2993 5.35763 11.228 5.43294C11.1566 5.50434 11.0669 5.54036 10.9598 5.54036H4.97477C4.87167 5.54036 4.78444 5.5043 4.71305 5.43294C4.64168 5.3576 4.60566 5.26845 4.60563 5.16536C4.60563 5.0662 4.63976 4.9809 4.70719 4.90951C4.77858 4.83817 4.86772 4.80208 4.97477 4.80208H10.9598Z" fill="#4A6AEF"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.8706 2C12.4694 2.00002 12.977 2.11126 13.3934 2.33333C13.8059 2.55543 14.1212 2.87461 14.3394 3.29102C14.5575 3.7035 14.6668 4.20528 14.6668 4.79622V9.41341C14.6668 10.0044 14.5575 10.508 14.3394 10.9245C14.1172 11.337 13.8019 11.6542 13.3934 11.8763C12.9809 12.0984 12.4873 12.2096 11.9123 12.2096H11.5907V13.6732C11.5907 13.9389 11.5255 14.1494 11.3947 14.304C11.2599 14.4587 11.0733 14.5358 10.8354 14.5358C10.6689 14.5358 10.5121 14.4922 10.3654 14.4049C10.2186 14.3217 10.0436 14.1909 9.84131 14.0124L7.8068 12.2096H4.12972C3.53481 12.2096 3.02924 12.0984 2.61279 11.8763C2.19632 11.6542 1.87912 11.337 1.66097 10.9245C1.44282 10.508 1.3335 10.0044 1.3335 9.41341V4.79622C1.33351 4.20528 1.44283 3.7035 1.66097 3.29102C1.87912 2.87461 2.19637 2.55543 2.61279 2.33333C3.02924 2.11124 3.53482 2.00002 4.12972 2H11.8706ZM4.16553 3.17188C3.60237 3.17188 3.1859 3.31285 2.91618 3.5944C2.6425 3.87205 2.50538 4.28468 2.50537 4.83203V9.37175C2.50538 9.92307 2.6425 10.3395 2.91618 10.6211C3.18589 10.8987 3.6023 11.0378 4.16553 11.0378H7.86605C8.04851 11.0378 8.19574 11.0592 8.3068 11.1029C8.41386 11.1425 8.53084 11.226 8.65772 11.3529L10.5438 13.2214V11.5254C10.5438 11.347 10.5836 11.2218 10.6629 11.1504C10.7383 11.0752 10.8592 11.0378 11.0256 11.0378H11.8407C12.3999 11.0378 12.8163 10.8987 13.09 10.6211C13.3597 10.3395 13.4949 9.92307 13.495 9.37175V4.83203C13.4949 4.28468 13.3597 3.87205 13.09 3.5944C12.8163 3.31287 12.3998 3.17188 11.8407 3.17188H4.16553Z" fill="#4A6AEF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.56201 2.00008C9.4316 2.36896 9.35366 2.76241 9.3374 3.17196H4.16553C3.60237 3.17196 3.1859 3.31293 2.91618 3.59448C2.6425 3.87213 2.50538 4.28476 2.50537 4.83211V9.37183C2.50538 9.92315 2.6425 10.3396 2.91618 10.6212C3.18589 10.8988 3.6023 11.0378 4.16553 11.0378H7.86605C8.04851 11.0378 8.19574 11.0593 8.3068 11.1029C8.41386 11.1426 8.53084 11.2261 8.65771 11.3529L10.5438 13.2214V11.5255C10.5438 11.347 10.5836 11.2219 10.6629 11.1505C10.7383 11.0753 10.8592 11.0378 11.0256 11.0378H11.8407C12.3999 11.0378 12.8163 10.8988 13.09 10.6212C13.3597 10.3396 13.4949 9.92315 13.495 9.37183V7.32886C13.9045 7.31259 14.298 7.23531 14.6668 7.1049V9.41349C14.6668 10.0045 14.5575 10.5081 14.3394 10.9246C14.1172 11.3371 13.8019 11.6543 13.3934 11.8764C12.9809 12.0985 12.4873 12.2097 11.9123 12.2097H11.5907V13.6733C11.5907 13.939 11.5255 14.1494 11.3947 14.3041C11.2599 14.4588 11.0733 14.5358 10.8354 14.5359C10.6689 14.5359 10.5121 14.4923 10.3654 14.405C10.2186 14.3217 10.0436 14.1909 9.84131 14.0125L7.8068 12.2097H4.12972C3.53481 12.2097 3.02924 12.0985 2.61279 11.8764C2.19632 11.6543 1.87912 11.3371 1.66097 10.9246C1.44282 10.5081 1.3335 10.0045 1.3335 9.41349V4.79631C1.33351 4.20536 1.44283 3.70358 1.66097 3.2911C1.87912 2.87469 2.19636 2.55551 2.61279 2.33341C3.02924 2.11132 3.53482 2.0001 4.12972 2.00008H9.56201Z" fill="#4A6AEF"/>
|
||||
<path d="M8.17334 8.58667C8.27636 8.58673 8.36372 8.624 8.43506 8.6993C8.51036 8.77064 8.54763 8.858 8.54769 8.96102C8.54769 9.06404 8.51026 9.15138 8.43506 9.22274C8.36372 9.29408 8.27637 9.33011 8.17334 9.33016H4.97477C4.87164 9.33016 4.78445 9.29414 4.71305 9.22274C4.64171 9.15136 4.60563 9.06411 4.60563 8.96102C4.60569 8.858 4.63982 8.77064 4.70719 8.6993C4.77856 8.62408 4.86778 8.58667 4.97477 8.58667H8.17334Z" fill="#4A6AEF"/>
|
||||
<path d="M10.9598 6.68823C11.0669 6.68823 11.1566 6.72615 11.228 6.80151C11.2994 6.87685 11.3348 6.96222 11.3348 7.05737C11.3348 7.16438 11.2993 7.25359 11.228 7.32495C11.1566 7.39635 11.0669 7.43237 10.9598 7.43237H4.97477C4.87165 7.43237 4.78445 7.39634 4.71305 7.32495C4.64166 7.25356 4.60564 7.16446 4.60563 7.05737C4.60563 6.96218 4.63976 6.87688 4.70719 6.80151C4.77857 6.72624 4.86774 6.68823 4.97477 6.68823H10.9598Z" fill="#4A6AEF"/>
|
||||
<path d="M13.3335 0.666748C14.8063 0.666748 16.0002 1.86066 16.0002 3.33341C16.0002 4.80617 14.8063 6.00008 13.3335 6.00008C11.8607 6.00008 10.6668 4.80617 10.6668 3.33341C10.6668 1.86066 11.8607 0.666748 13.3335 0.666748Z" fill="#4A6AEF"/>
|
||||
<path d="M9.61279 4.80217C9.71574 5.06275 9.8448 5.31001 9.99756 5.54045H4.97477C4.87167 5.54045 4.78444 5.50438 4.71305 5.43302C4.64168 5.35769 4.60566 5.26853 4.60563 5.16545C4.60563 5.06628 4.63976 4.98098 4.70719 4.90959C4.77858 4.83825 4.86772 4.80217 4.97477 4.80217H9.61279Z" fill="#4A6AEF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -1,117 +0,0 @@
|
||||
<svg
|
||||
width="33"
|
||||
height="33"
|
||||
viewBox="0 0 33 33"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_3236_2952)">
|
||||
<g clip-path="url(#clip1_3236_2952)">
|
||||
<rect x="4.5" y="0.5" width="24" height="32" rx="3.55556" fill="white" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.08374 7.7623C8.08374 7.27138 8.48171 6.87341 8.97263 6.87341H16.9726C17.4635 6.87341 17.8615 7.27138 17.8615 7.7623C17.8615 8.25322 17.4635 8.65118 16.9726 8.65118H8.97263C8.48171 8.65118 8.08374 8.25322 8.08374 7.7623Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.08374 10.7685C8.08374 10.2776 8.48171 9.87964 8.97263 9.87964H24.0273C24.5182 9.87964 24.9162 10.2776 24.9162 10.7685C24.9162 11.2594 24.5182 11.6574 24.0273 11.6574H8.97263C8.48171 11.6574 8.08374 11.2594 8.08374 10.7685ZM8.08374 13.4352C8.08374 12.9443 8.48171 12.5463 8.97263 12.5463H24.0273C24.5182 12.5463 24.9162 12.9443 24.9162 13.4352C24.9162 13.9261 24.5182 14.3241 24.0273 14.3241H8.97263C8.48171 14.3241 8.08374 13.9261 8.08374 13.4352ZM8.08374 16.1019C8.08374 15.6109 8.48171 15.213 8.97263 15.213H24.0273C24.5182 15.213 24.9162 15.6109 24.9162 16.1019C24.9162 16.5928 24.5182 16.9907 24.0273 16.9907H8.97263C8.48171 16.9907 8.08374 16.5928 8.08374 16.1019ZM8.08374 18.7685C8.08374 18.2776 8.48171 17.8796 8.97263 17.8796H24.0273C24.5182 17.8796 24.9162 18.2776 24.9162 18.7685C24.9162 19.2594 24.5182 19.6574 24.0273 19.6574H8.97263C8.48171 19.6574 8.08374 19.2594 8.08374 18.7685Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.08374 10.7685C8.08374 10.2776 8.48171 9.87964 8.97263 9.87964H24.0273C24.5182 9.87964 24.9162 10.2776 24.9162 10.7685C24.9162 11.2594 24.5182 11.6574 24.0273 11.6574H8.97263C8.48171 11.6574 8.08374 11.2594 8.08374 10.7685ZM8.08374 13.4352C8.08374 12.9443 8.48171 12.5463 8.97263 12.5463H24.0273C24.5182 12.5463 24.9162 12.9443 24.9162 13.4352C24.9162 13.9261 24.5182 14.3241 24.0273 14.3241H8.97263C8.48171 14.3241 8.08374 13.9261 8.08374 13.4352ZM8.08374 16.1019C8.08374 15.6109 8.48171 15.213 8.97263 15.213H24.0273C24.5182 15.213 24.9162 15.6109 24.9162 16.1019C24.9162 16.5928 24.5182 16.9907 24.0273 16.9907H8.97263C8.48171 16.9907 8.08374 16.5928 8.08374 16.1019ZM8.08374 18.7685C8.08374 18.2776 8.48171 17.8796 8.97263 17.8796H24.0273C24.5182 17.8796 24.9162 18.2776 24.9162 18.7685C24.9162 19.2594 24.5182 19.6574 24.0273 19.6574H8.97263C8.48171 19.6574 8.08374 19.2594 8.08374 18.7685Z"
|
||||
fill="white"
|
||||
fill-opacity="0.65"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.08374 21.4666C8.08374 20.9757 8.48171 20.5777 8.97263 20.5777H24.0273C24.5182 20.5777 24.9162 20.9757 24.9162 21.4666C24.9162 21.9575 24.5182 22.3555 24.0273 22.3555H8.97263C8.48171 22.3555 8.08374 21.9575 8.08374 21.4666ZM8.08374 24.1333C8.08374 23.6424 8.48171 23.2444 8.97263 23.2444H24.0273C24.5182 23.2444 24.9162 23.6424 24.9162 24.1333C24.9162 24.6242 24.5182 25.0222 24.0273 25.0222H8.97263C8.48171 25.0222 8.08374 24.6242 8.08374 24.1333ZM8.08374 26.8C8.08374 26.309 8.48171 25.9111 8.97263 25.9111H24.0273C24.5182 25.9111 24.9162 26.309 24.9162 26.8C24.9162 27.2909 24.5182 27.6888 24.0273 27.6888H8.97263C8.48171 27.6888 8.08374 27.2909 8.08374 26.8ZM8.08374 29.4666C8.08374 28.9757 8.48171 28.5777 8.97263 28.5777H24.0273C24.5182 28.5777 24.9162 28.9757 24.9162 29.4666C24.9162 29.9575 24.5182 30.3555 24.0273 30.3555H8.97263C8.48171 30.3555 8.08374 29.9575 8.08374 29.4666Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M8.08374 21.4666C8.08374 20.9757 8.48171 20.5777 8.97263 20.5777H24.0273C24.5182 20.5777 24.9162 20.9757 24.9162 21.4666C24.9162 21.9575 24.5182 22.3555 24.0273 22.3555H8.97263C8.48171 22.3555 8.08374 21.9575 8.08374 21.4666ZM8.08374 24.1333C8.08374 23.6424 8.48171 23.2444 8.97263 23.2444H24.0273C24.5182 23.2444 24.9162 23.6424 24.9162 24.1333C24.9162 24.6242 24.5182 25.0222 24.0273 25.0222H8.97263C8.48171 25.0222 8.08374 24.6242 8.08374 24.1333ZM8.08374 26.8C8.08374 26.309 8.48171 25.9111 8.97263 25.9111H24.0273C24.5182 25.9111 24.9162 26.309 24.9162 26.8C24.9162 27.2909 24.5182 27.6888 24.0273 27.6888H8.97263C8.48171 27.6888 8.08374 27.2909 8.08374 26.8ZM8.08374 29.4666C8.08374 28.9757 8.48171 28.5777 8.97263 28.5777H24.0273C24.5182 28.5777 24.9162 28.9757 24.9162 29.4666C24.9162 29.9575 24.5182 30.3555 24.0273 30.3555H8.97263C8.48171 30.3555 8.08374 29.9575 8.08374 29.4666Z"
|
||||
fill="white"
|
||||
fill-opacity="0.65"
|
||||
/>
|
||||
<rect
|
||||
x="4.57422"
|
||||
y="0.5"
|
||||
width="23.9258"
|
||||
height="31.8206"
|
||||
fill="url(#paint0_linear_3236_2952)"
|
||||
fill-opacity="0.4"
|
||||
/>
|
||||
</g>
|
||||
<rect
|
||||
x="4.85"
|
||||
y="0.85"
|
||||
width="23.3"
|
||||
height="31.3"
|
||||
rx="3.20556"
|
||||
stroke="currentColor"
|
||||
stroke-width="0.7"
|
||||
/>
|
||||
<rect
|
||||
x="4.85"
|
||||
y="0.85"
|
||||
width="23.3"
|
||||
height="31.3"
|
||||
rx="3.20556"
|
||||
stroke="white"
|
||||
stroke-opacity="0.65"
|
||||
stroke-width="0.7"
|
||||
/>
|
||||
<rect
|
||||
x="4.85"
|
||||
y="0.85"
|
||||
width="23.3"
|
||||
height="31.3"
|
||||
rx="3.20556"
|
||||
stroke="url(#paint1_linear_3236_2952)"
|
||||
stroke-opacity="0.23"
|
||||
stroke-width="0.7"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_3236_2952"
|
||||
x1="16.5371"
|
||||
y1="0.5"
|
||||
x2="16.5371"
|
||||
y2="32.3206"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="white" stop-opacity="0" />
|
||||
<stop offset="1" stop-color="white" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear_3236_2952"
|
||||
x1="16.5"
|
||||
y1="0.5"
|
||||
x2="16.5"
|
||||
y2="32.5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="white" stop-opacity="0" />
|
||||
<stop offset="1" stop-color="white" />
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_3236_2952">
|
||||
<rect
|
||||
width="32"
|
||||
height="32"
|
||||
fill="white"
|
||||
transform="translate(0.5 0.5)"
|
||||
/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_3236_2952">
|
||||
<rect x="4.5" y="0.5" width="24" height="32" rx="3.55556" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.2 KiB |
@@ -1,7 +1,8 @@
|
||||
import { useModal } from '@openfun/cunningham-react';
|
||||
import { Button as _Button, useModal } from '@openfun/cunningham-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import { DropdownMenu, DropdownMenuOption, Icon } from '@/components';
|
||||
import { Box, DropdownMenu, DropdownMenuOption, Icon } from '@/components';
|
||||
import { ChatConversation } from '@/features/chat/types';
|
||||
|
||||
import { ModalRemoveConversation } from './ModalRemoveConversation';
|
||||
@@ -19,7 +20,7 @@ export const ConversationItemActions = ({
|
||||
|
||||
const options: DropdownMenuOption[] = [
|
||||
{
|
||||
label: t('Remove'),
|
||||
label: t('Delete chat'),
|
||||
icon: 'delete',
|
||||
callback: () => deleteModal.open(),
|
||||
disabled: false,
|
||||
@@ -30,12 +31,29 @@ export const ConversationItemActions = ({
|
||||
return (
|
||||
<>
|
||||
<DropdownMenu options={options}>
|
||||
<Icon
|
||||
data-testid={`conversation-item-actions-button-${conversation.id}`}
|
||||
iconName="more_horiz"
|
||||
$theme="primary"
|
||||
$variation="600"
|
||||
/>
|
||||
<Box
|
||||
$css={css`
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
&:hover {
|
||||
background-color: #e1e3e7 !important;
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Icon
|
||||
data-testid={`conversation-item-actions-button-${conversation.id}`}
|
||||
iconName="more_horiz"
|
||||
$theme="primary"
|
||||
$variation="600"
|
||||
$css={css`
|
||||
font-size: 1rem;
|
||||
color: var(--c--theme--colors--primary-text-text);
|
||||
`}
|
||||
/>
|
||||
</Box>
|
||||
</DropdownMenu>
|
||||
|
||||
{deleteModal.isOpen && (
|
||||
|
||||
@@ -5,8 +5,8 @@ import { createGlobalStyle, css } from 'styled-components';
|
||||
import { Box, SeparatedSection } from '@/components';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { ButtonLogin } from '@/features/auth';
|
||||
import { HEADER_HEIGHT } from '@/features/header/conf';
|
||||
import { LanguagePicker } from '@/features/language';
|
||||
import { SettingsButton } from '@/features/settings';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { useLeftPanelStore } from '../stores';
|
||||
@@ -29,8 +29,8 @@ export const LeftPanel = () => {
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
togglePanel(false);
|
||||
}, [pathname, togglePanel]);
|
||||
togglePanel(isDesktop ? true : false);
|
||||
}, [pathname, togglePanel, isDesktop]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -38,11 +38,12 @@ export const LeftPanel = () => {
|
||||
<Box
|
||||
data-testid="left-panel-desktop"
|
||||
$css={`
|
||||
height: calc(100vh - ${HEADER_HEIGHT}px);
|
||||
height: 100vh;
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
overflow: hidden;
|
||||
border-right: 1px solid ${colorsTokens['greyscale-200']};
|
||||
background-color: #F7F8FA;
|
||||
`}
|
||||
className="--docs--left-panel-desktop"
|
||||
>
|
||||
@@ -64,12 +65,14 @@ export const LeftPanel = () => {
|
||||
$hasTransition
|
||||
$css={css`
|
||||
z-index: 999;
|
||||
width: 100dvw;
|
||||
overflow: hidden;
|
||||
width: ${isPanelOpen ? '100%' : '200px'};
|
||||
height: calc(100dvh - 52px);
|
||||
border-right: 1px solid var(--c--theme--colors--greyscale-200);
|
||||
position: fixed;
|
||||
transform: translateX(${isPanelOpen ? '0' : '-100dvw'});
|
||||
background-color: var(--c--theme--colors--greyscale-000);
|
||||
top: 52px;
|
||||
left: ${isPanelOpen ? '0' : '-300px'};
|
||||
background-color: #fff;
|
||||
`}
|
||||
className="--docs--left-panel-mobile"
|
||||
>
|
||||
@@ -82,16 +85,33 @@ export const LeftPanel = () => {
|
||||
gap: ${spacingsTokens['base']};
|
||||
`}
|
||||
>
|
||||
<LeftPanelHeader />
|
||||
<LeftPanelContent />
|
||||
<SeparatedSection showSeparator={false}>
|
||||
<Box
|
||||
$justify="center"
|
||||
$css={css`
|
||||
display: flex;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 52px;
|
||||
width: 100%;
|
||||
gap: ${spacingsTokens['base']};
|
||||
border-top: 1px solid #dfe2ea;
|
||||
`}
|
||||
$justify="space-between"
|
||||
$align="center"
|
||||
$direction="row"
|
||||
$padding={{ horizontal: 'sm' }}
|
||||
$gap={spacingsTokens['sm']}
|
||||
>
|
||||
<ButtonLogin />
|
||||
<LanguagePicker />
|
||||
<Box
|
||||
$direction="row"
|
||||
$gap={spacingsTokens['sm']}
|
||||
$align="center"
|
||||
>
|
||||
<LanguagePicker />
|
||||
<SettingsButton />
|
||||
</Box>
|
||||
</Box>
|
||||
</SeparatedSection>
|
||||
</Box>
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Box } from '@/components';
|
||||
import { LeftPanelConversations } from '@/features/left-panel/components/LeftPanelConversations';
|
||||
import { LeftPanelSearch } from '@/features/left-panel/components/LeftPanelSearch';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
export const LeftPanelContent = () => {
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const [hasSearch, setHasSearch] = useState(false);
|
||||
|
||||
return (
|
||||
<Box $flex={1} $width="100%" $css="overflow-y: auto; overflow-x: hidden;">
|
||||
<LeftPanelConversations />
|
||||
<Box
|
||||
$width="100%"
|
||||
$css={`
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
height: calc(100dvh - ${isDesktop ? '52px' : '104px'});
|
||||
`}
|
||||
>
|
||||
<LeftPanelSearch onSearchChange={setHasSearch} />
|
||||
{!hasSearch && <LeftPanelConversations />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { css } from 'styled-components';
|
||||
|
||||
import { Box, StyledLink } from '@/components';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { ChatConversation } from '@/features/chat/types';
|
||||
import { ConversationItemActions } from '@/features/left-panel/components/ConversationItemActions';
|
||||
import { SimpleConversationItem } from '@/features/left-panel/components/SimpleConversationItem';
|
||||
@@ -9,43 +8,53 @@ import { useResponsiveStore } from '@/stores';
|
||||
|
||||
type LeftPanelConversationItemProps = {
|
||||
conversation: ChatConversation;
|
||||
isCurrentConversation: boolean;
|
||||
};
|
||||
|
||||
export const LeftPanelConversationItem = ({
|
||||
conversation,
|
||||
isCurrentConversation,
|
||||
}: LeftPanelConversationItemProps) => {
|
||||
const { spacingsTokens } = useCunninghamTheme();
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
// const { togglePanel } = useLeftPanelStore();
|
||||
|
||||
return (
|
||||
<Box
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$padding={{ horizontal: 'xs', vertical: '4px' }}
|
||||
$justify="space-between"
|
||||
$css={css`
|
||||
padding: ${spacingsTokens['2xs']};
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
background-color: ${isCurrentConversation ? '#ebedf1' : ''};
|
||||
font-weight: ${isCurrentConversation ? '700' : '500'};
|
||||
transition: background-color 0.2s cubic-bezier(1, 0, 0, 1);
|
||||
.pinned-actions {
|
||||
padding: 2px 0;
|
||||
opacity: ${isDesktop ? 0 : 1};
|
||||
background-color: transparent
|
||||
transition: all 0.3s cubic-bezier(1, 0, 0, 1);
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
|
||||
background-color: var(--c--theme--colors--greyscale-100);
|
||||
&:hover, &:focus {
|
||||
background-color: #ebedf1;
|
||||
.pinned-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`}
|
||||
key={conversation.id}
|
||||
className="--docs--left-panel-favorite-item"
|
||||
>
|
||||
<StyledLink href={`/chat/${conversation.id}/`} $css="overflow: auto;">
|
||||
<StyledLink
|
||||
href={`/chat/${conversation.id}/`}
|
||||
$css="overflow: auto; flex-grow: 1;"
|
||||
>
|
||||
<SimpleConversationItem showAccesses conversation={conversation} />
|
||||
</StyledLink>
|
||||
<div className="pinned-actions">
|
||||
|
||||
<Box className="pinned-actions">
|
||||
<ConversationItemActions conversation={conversation} />
|
||||
</div>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Box, InfiniteScroll, Text } from '@/components';
|
||||
@@ -7,6 +8,8 @@ import { LeftPanelConversationItem } from '@/features/left-panel/components/Left
|
||||
|
||||
export const LeftPanelConversations = () => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const { id } = router.query;
|
||||
|
||||
const { spacingsTokens } = useCunninghamTheme();
|
||||
|
||||
@@ -25,19 +28,18 @@ export const LeftPanelConversations = () => {
|
||||
return (
|
||||
<Box className="--conversations--left-panel-favorites">
|
||||
<Box
|
||||
$justify="center"
|
||||
$padding={{ horizontal: 'sm', top: 'sm' }}
|
||||
$gap={spacingsTokens['2xs']}
|
||||
$height="100%"
|
||||
$height="50vh"
|
||||
data-testid="left-panel-favorites"
|
||||
>
|
||||
<Text
|
||||
$size="sm"
|
||||
$variation="700"
|
||||
$padding={{ horizontal: '3xs' }}
|
||||
$padding={{ horizontal: 'xs' }}
|
||||
$weight="700"
|
||||
>
|
||||
{t('Recent conversations')}
|
||||
{t('History')}
|
||||
</Text>
|
||||
<InfiniteScroll
|
||||
hasMore={conversations.hasNextPage}
|
||||
@@ -47,6 +49,7 @@ export const LeftPanelConversations = () => {
|
||||
{favoriteConversations.map((conversation) => (
|
||||
<LeftPanelConversationItem
|
||||
key={conversation.id}
|
||||
isCurrentConversation={conversation.id === id}
|
||||
conversation={conversation}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -1,85 +1,56 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import { t } from 'i18next';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { PropsWithChildren, useCallback, useState } from 'react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import { Box, Icon, SeparatedSection } from '@/components';
|
||||
import NewChatIcon from '@/assets/icons/new-message-bold.svg';
|
||||
import { Box, SeparatedSection } from '@/components';
|
||||
import { useAuth } from '@/features/auth';
|
||||
import { ConversationSearchModal } from '@/features/chat-search';
|
||||
import { useCmdK } from '@/hook/useCmdK';
|
||||
import { SettingsButton } from '@/features/settings';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import { useLeftPanelStore } from '../stores';
|
||||
|
||||
export const LeftPanelHeader = ({ children }: PropsWithChildren) => {
|
||||
const router = useRouter();
|
||||
const { authenticated } = useAuth();
|
||||
const [isSearchModalOpen, setIsSearchModalOpen] = useState(false);
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
|
||||
const openSearchModal = useCallback(() => {
|
||||
const isEditorToolbarOpen =
|
||||
document.getElementsByClassName('bn-formatting-toolbar').length > 0;
|
||||
if (isEditorToolbarOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsSearchModalOpen(true);
|
||||
}, []);
|
||||
|
||||
const closeSearchModal = useCallback(() => {
|
||||
setIsSearchModalOpen(false);
|
||||
}, []);
|
||||
|
||||
useCmdK(openSearchModal);
|
||||
const { togglePanel } = useLeftPanelStore();
|
||||
|
||||
const goToHome = () => {
|
||||
router.push('/');
|
||||
togglePanel();
|
||||
if (!isDesktop) {
|
||||
togglePanel(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box $width="100%" className="--docs--left-panel-header">
|
||||
<SeparatedSection>
|
||||
<Box
|
||||
$padding={{ horizontal: 'sm' }}
|
||||
$width="100%"
|
||||
$direction="row"
|
||||
$justify="space-between"
|
||||
$align="center"
|
||||
>
|
||||
<Box $direction="row" $gap="2px">
|
||||
<Button
|
||||
onClick={goToHome}
|
||||
size="medium"
|
||||
color="tertiary-text"
|
||||
icon={
|
||||
<Icon $variation="800" $theme="primary" iconName="house" />
|
||||
}
|
||||
/>
|
||||
{authenticated && (
|
||||
{authenticated && (
|
||||
<Box $width="100%" className="--docs--left-panel-header">
|
||||
<SeparatedSection>
|
||||
<Box
|
||||
$padding={{ horizontal: 'sm' }}
|
||||
$width="100%"
|
||||
$direction="row"
|
||||
$justify="space-between"
|
||||
$align="center"
|
||||
>
|
||||
<Box $direction="row" $gap="2px">
|
||||
<Button
|
||||
onClick={openSearchModal}
|
||||
size="medium"
|
||||
color="tertiary-text"
|
||||
icon={
|
||||
<Icon $variation="800" $theme="primary" iconName="search" />
|
||||
}
|
||||
/>
|
||||
)}
|
||||
color="primary"
|
||||
icon={<NewChatIcon />}
|
||||
onClick={goToHome}
|
||||
>
|
||||
{t('New chat')}
|
||||
</Button>
|
||||
</Box>
|
||||
<SettingsButton />
|
||||
</Box>
|
||||
{authenticated && (
|
||||
<Button onClick={goToHome}>{t('New conversation')}</Button>
|
||||
)}
|
||||
</Box>
|
||||
</SeparatedSection>
|
||||
{children}
|
||||
</Box>
|
||||
{isSearchModalOpen && (
|
||||
<ConversationSearchModal
|
||||
onClose={closeSearchModal}
|
||||
isOpen={isSearchModalOpen}
|
||||
/>
|
||||
</SeparatedSection>
|
||||
{children}
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { InView } from 'react-intersection-observer';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
import { Box } from '@/components';
|
||||
import {
|
||||
QuickSearch,
|
||||
QuickSearchData,
|
||||
QuickSearchGroup,
|
||||
} from '@/components/quick-search';
|
||||
import { useInfiniteConversations } from '@/features/chat/api/useConversations';
|
||||
import { ChatConversation } from '@/features/chat/types';
|
||||
import { LeftPanelConversationItem } from '@/features/left-panel/components/LeftPanelConversationItem';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
type LeftPanelSearchProps = {
|
||||
onSearchChange?: (hasSearch: boolean) => void;
|
||||
};
|
||||
|
||||
export const LeftPanelSearch = ({ onSearchChange }: LeftPanelSearchProps) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const [search, setSearch] = useState('');
|
||||
const { isDesktop: _isDesktop } = useResponsiveStore();
|
||||
|
||||
const currentConversationId = params?.id as string;
|
||||
|
||||
const {
|
||||
data,
|
||||
isFetching,
|
||||
isRefetching,
|
||||
isLoading,
|
||||
fetchNextPage,
|
||||
hasNextPage,
|
||||
} = useInfiniteConversations({
|
||||
page: 1,
|
||||
title: search,
|
||||
});
|
||||
|
||||
const loading = isFetching || isRefetching || isLoading;
|
||||
const handleInputSearch = useDebouncedCallback((value: string) => {
|
||||
setSearch(value);
|
||||
onSearchChange?.(value.length > 0);
|
||||
}, 300);
|
||||
|
||||
const handleSelect = (conversation: ChatConversation) => {
|
||||
router.push(`/chat/${conversation.id}`);
|
||||
};
|
||||
|
||||
const handleClear = () => {
|
||||
setSearch('');
|
||||
onSearchChange?.(false);
|
||||
};
|
||||
|
||||
const conversationsData: QuickSearchData<ChatConversation> = useMemo(() => {
|
||||
const conversations = data?.pages.flatMap((page) => page.results) || [];
|
||||
|
||||
return {
|
||||
groupName: conversations.length > 0 ? t('Search results') : '',
|
||||
elements: search ? conversations : [],
|
||||
emptyString: t('No conversation found'),
|
||||
endActions: hasNextPage
|
||||
? [{ content: <InView onChange={() => void fetchNextPage()} /> }]
|
||||
: [],
|
||||
};
|
||||
}, [data, hasNextPage, fetchNextPage, t, search]);
|
||||
|
||||
return (
|
||||
<QuickSearch
|
||||
placeholder={t('Search for a chat')}
|
||||
loading={loading}
|
||||
onFilter={handleInputSearch}
|
||||
onClear={handleClear}
|
||||
inputValue={search}
|
||||
>
|
||||
<Box>
|
||||
{search && (
|
||||
<QuickSearchGroup
|
||||
onSelect={handleSelect}
|
||||
group={conversationsData}
|
||||
renderElement={(conversation) => (
|
||||
<LeftPanelConversationItem
|
||||
conversation={conversation}
|
||||
isCurrentConversation={
|
||||
conversation.id === currentConversationId
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</QuickSearch>
|
||||
);
|
||||
};
|
||||
@@ -1,15 +1,9 @@
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
ModalSize,
|
||||
VariantType,
|
||||
useToastProvider,
|
||||
} from '@openfun/cunningham-react';
|
||||
import { Button, Modal, ModalSize } from '@openfun/cunningham-react';
|
||||
import { t } from 'i18next';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
import { Box, Text, TextErrors } from '@/components';
|
||||
import { Box, Text, TextErrors, useToast } from '@/components';
|
||||
import { useRemoveConversation } from '@/features/chat/api/useRemoveConversation';
|
||||
import { ChatConversation } from '@/features/chat/types';
|
||||
|
||||
@@ -22,20 +16,22 @@ export const ModalRemoveConversation = ({
|
||||
onClose,
|
||||
conversation,
|
||||
}: ModalRemoveConversationProps) => {
|
||||
const { toast } = useToastProvider();
|
||||
const { showToast } = useToast();
|
||||
const { push } = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
const {
|
||||
mutate: removeDoc,
|
||||
|
||||
isError,
|
||||
error,
|
||||
} = useRemoveConversation({
|
||||
onSuccess: () => {
|
||||
toast(t('The conversation has been deleted.'), VariantType.SUCCESS, {
|
||||
duration: 4000,
|
||||
});
|
||||
showToast(
|
||||
'success',
|
||||
t('The conversation has been deleted.'),
|
||||
undefined,
|
||||
4000,
|
||||
);
|
||||
if (pathname === '/') {
|
||||
onClose();
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DateTime } from 'luxon';
|
||||
// A SUPPRIMER ?
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { css } from 'styled-components';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useCunninghamTheme } from '@/cunningham';
|
||||
import { ChatConversation } from '@/features/chat/types';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
import SimpleFileIcon from '../assets/simple-document.svg';
|
||||
import BubbleIcon from '../assets/bubble-bold.svg';
|
||||
|
||||
const ItemTextCss = css`
|
||||
overflow: hidden;
|
||||
@@ -26,11 +26,11 @@ type SimpleConversationItemProps = {
|
||||
|
||||
export const SimpleConversationItem = ({
|
||||
conversation,
|
||||
showAccesses = false,
|
||||
showAccesses: _showAccesses = false,
|
||||
}: SimpleConversationItemProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const { isDesktop: _isDesktop } = useResponsiveStore();
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -48,8 +48,8 @@ export const SimpleConversationItem = ({
|
||||
`}
|
||||
$padding={`${spacingsTokens['3xs']} 0`}
|
||||
>
|
||||
<SimpleFileIcon
|
||||
aria-label={t('Simple document icon')}
|
||||
<BubbleIcon
|
||||
aria-label={t('Simple chat icon')}
|
||||
color={colorsTokens['primary-500']}
|
||||
/>
|
||||
</Box>
|
||||
@@ -59,23 +59,10 @@ export const SimpleConversationItem = ({
|
||||
aria-label={conversation.title || t('Untitled conversation')}
|
||||
$size="sm"
|
||||
$variation="1000"
|
||||
$weight="500"
|
||||
$css={ItemTextCss}
|
||||
>
|
||||
{conversation.title || t('Untitled conversation')}
|
||||
</Text>
|
||||
{(!isDesktop || showAccesses) && (
|
||||
<Box
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$gap={spacingsTokens['3xs']}
|
||||
$margin={{ top: '-2px' }}
|
||||
>
|
||||
<Text $variation="600" $size="xs">
|
||||
{DateTime.fromISO(conversation.updated_at).toRelative()}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { BoxButton, Icon } from '@/components';
|
||||
|
||||
import { SettingsModal } from './SettingsModal';
|
||||
|
||||
export const SettingsButton = () => {
|
||||
const { t } = useTranslation();
|
||||
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<BoxButton
|
||||
aria-label={t('Settings')}
|
||||
onClick={() => setIsSettingsOpen(true)}
|
||||
>
|
||||
<Icon iconName="settings" $theme="primary" $size="24px" />
|
||||
</BoxButton>
|
||||
|
||||
<SettingsModal
|
||||
isOpen={isSettingsOpen}
|
||||
onClose={() => setIsSettingsOpen(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,123 @@
|
||||
import { Modal, ModalSize } from '@openfun/cunningham-react';
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Box, Icon, Text } from '@/components';
|
||||
|
||||
interface SettingsModalProps {
|
||||
onClose: () => void;
|
||||
isOpen: boolean;
|
||||
}
|
||||
|
||||
export const SettingsModal = ({ onClose, isOpen }: SettingsModalProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [isToggleEnabled, setIsToggleEnabled] = useState(false);
|
||||
|
||||
const handleToggleChange = () => {
|
||||
setIsToggleEnabled(!isToggleEnabled);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
closeOnClickOutside
|
||||
onClose={onClose}
|
||||
size={ModalSize.MEDIUM}
|
||||
title={
|
||||
<Text
|
||||
$size="h6"
|
||||
as="h6"
|
||||
$margin={{ all: '0' }}
|
||||
$align="flex-start"
|
||||
$variation="1000"
|
||||
>
|
||||
{t('Assistant settings')}
|
||||
</Text>
|
||||
}
|
||||
>
|
||||
<Box aria-label={t('Assistant settings')}>
|
||||
<Box $align="center" $justify="space-between">
|
||||
<Box $gap="2xs">
|
||||
<Text
|
||||
$size="xs"
|
||||
$weight="400"
|
||||
$variation="700"
|
||||
$padding={{ top: 'sm', bottom: 'sm' }}
|
||||
>
|
||||
{t(
|
||||
'The Assistant is a sovereign conversational AI designed for public servants. It helps you save time on daily tasks like rephrasing, summarising, translating, or searching information. Your data never leaves France and is stored on secure, state-compliant infrastructures. It is never used for commercial purposes.',
|
||||
)}
|
||||
</Text>
|
||||
<Text
|
||||
$size="md"
|
||||
$weight="500"
|
||||
$variation="1000"
|
||||
$padding={{ top: 'xs' }}
|
||||
>
|
||||
{t('Allow conversation analysis')}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box $direction="row" $justify="space-between" $align="flex-start">
|
||||
<Box $css="max-width: 70%;">
|
||||
<Text $size="xs" $weight="400" $variation="700">
|
||||
{t(
|
||||
'If enabled, this allows us to analyse your exchanges to improve the Assistant. If disabled, all conversations remain confidential and are not used in any way. Learn more about data usage.',
|
||||
)}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box $css="padding-top: 2px;">
|
||||
<Box
|
||||
$css={`
|
||||
position: relative;
|
||||
width: 44px;
|
||||
height: 24px;
|
||||
background-color: ${isToggleEnabled ? 'var(--c--theme--colors--primary-500)' : 'var(--c--theme--colors--greyscale-300)'};
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: ${isToggleEnabled ? 'var(--c--theme--colors--primary-600)' : 'var(--c--theme--colors--greyscale-400)'};
|
||||
}
|
||||
`}
|
||||
onClick={handleToggleChange}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
handleToggleChange();
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<Box
|
||||
$css={`
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: ${isToggleEnabled ? '22px' : '2px'};
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
transition: left 0.2s ease;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`}
|
||||
>
|
||||
<Icon
|
||||
iconName={isToggleEnabled ? 'check' : 'close'}
|
||||
$size="12px"
|
||||
$theme="primary"
|
||||
$variation="600"
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './components/SettingsModal';
|
||||
export * from './components/SettingsButton';
|
||||
@@ -1,9 +1,10 @@
|
||||
import { VariantType, useToastProvider } from '@openfun/cunningham-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useToast } from '@/components';
|
||||
|
||||
export const useClipboard = () => {
|
||||
const { toast } = useToastProvider();
|
||||
const { showToast } = useToast();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return useCallback(
|
||||
@@ -11,24 +12,22 @@ export const useClipboard = () => {
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
toast(
|
||||
successMessage ?? t('Copied to clipboard'),
|
||||
VariantType.SUCCESS,
|
||||
{
|
||||
duration: 3000,
|
||||
},
|
||||
showToast(
|
||||
'success',
|
||||
successMessage ?? t('Copied'),
|
||||
'content_copy',
|
||||
3000,
|
||||
);
|
||||
})
|
||||
.catch(() => {
|
||||
toast(
|
||||
errorMessage ?? t('Failed to copy to clipboard'),
|
||||
VariantType.ERROR,
|
||||
{
|
||||
duration: 3000,
|
||||
},
|
||||
showToast(
|
||||
'error',
|
||||
errorMessage ?? t('Failed to copy'),
|
||||
'content_copy',
|
||||
3000,
|
||||
);
|
||||
});
|
||||
},
|
||||
[t, toast],
|
||||
[t, showToast],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useCunninghamTheme } from '@/cunningham';
|
||||
import { Header } from '@/features/header';
|
||||
import { HEADER_HEIGHT } from '@/features/header/conf';
|
||||
import { LeftPanel } from '@/features/left-panel';
|
||||
import { useLeftPanelStore } from '@/features/left-panel/stores';
|
||||
import { MAIN_LAYOUT_ID } from '@/layouts/conf';
|
||||
import { useResponsiveStore } from '@/stores';
|
||||
|
||||
@@ -15,42 +16,52 @@ type MainLayoutProps = {
|
||||
|
||||
export function MainLayout({
|
||||
children,
|
||||
backgroundColor = 'white',
|
||||
backgroundColor: _backgroundColor = 'white',
|
||||
}: PropsWithChildren<MainLayoutProps>) {
|
||||
const { isDesktop } = useResponsiveStore();
|
||||
const { colorsTokens } = useCunninghamTheme();
|
||||
const currentBackgroundColor = !isDesktop ? 'white' : backgroundColor;
|
||||
const { togglePanel: _togglePanel, isPanelOpen } = useLeftPanelStore();
|
||||
|
||||
return (
|
||||
<Box className="--docs--main-layout">
|
||||
<Header />
|
||||
<Box
|
||||
$direction="row"
|
||||
$margin={{ top: `${HEADER_HEIGHT}px` }}
|
||||
$width="100%"
|
||||
$css={css`
|
||||
z-index: 1000;
|
||||
transition: left 0.3s ease;
|
||||
position: fixed;
|
||||
width: 300px;
|
||||
left: ${isPanelOpen ? '0px' : '-300px'};
|
||||
`}
|
||||
>
|
||||
<LeftPanel />
|
||||
<Box
|
||||
as="main"
|
||||
id={MAIN_LAYOUT_ID}
|
||||
$align="center"
|
||||
$flex={1}
|
||||
$width="100%"
|
||||
$height={`calc(100dvh - ${HEADER_HEIGHT}px)`}
|
||||
$padding={{
|
||||
all: isDesktop ? '0' : '0',
|
||||
}}
|
||||
$background={
|
||||
currentBackgroundColor === 'white'
|
||||
? colorsTokens['greyscale-000']
|
||||
: colorsTokens['greyscale-050']
|
||||
}
|
||||
$css={css`
|
||||
overflow-y: auto;
|
||||
overflow-x: clip;
|
||||
`}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
<Box
|
||||
$css={css`
|
||||
transition: all 0.3s ease;
|
||||
position: fixed;
|
||||
left: ${isDesktop && isPanelOpen ? '300px' : '0px'};
|
||||
width: calc(100vw - ${isDesktop && isPanelOpen ? '300px' : '0px'});
|
||||
`}
|
||||
>
|
||||
<Header />
|
||||
<Box $direction="row" $width="100%">
|
||||
<Box
|
||||
as="main"
|
||||
id={MAIN_LAYOUT_ID}
|
||||
$align="center"
|
||||
$width="100vw"
|
||||
$height={`calc(100dvh - ${HEADER_HEIGHT}px)`}
|
||||
$padding={{
|
||||
all: isDesktop ? '0' : '0',
|
||||
}}
|
||||
$background={colorsTokens['greyscale-000']}
|
||||
$css={css`
|
||||
overflow-y: auto;
|
||||
overflow-x: clip;
|
||||
`}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) {
|
||||
<meta
|
||||
name="description"
|
||||
content={t(
|
||||
`${productName}: Your new companion to use AI efficiently, intuitively, and securely.`,
|
||||
`${productName}: ${t('Your new companion to use AI efficiently, intuitively, and securely.')}`,
|
||||
)}
|
||||
/>
|
||||
<link rel="icon" href={favicon['ico']} sizes="any" />
|
||||
|
||||
@@ -13,7 +13,7 @@ const Page: NextPageWithLayout = () => {
|
||||
};
|
||||
|
||||
Page.getLayout = function getLayout(page: ReactElement) {
|
||||
return <MainLayout backgroundColor="grey">{page}</MainLayout>;
|
||||
return <MainLayout>{page}</MainLayout>;
|
||||
};
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -9,7 +9,7 @@ const Page: NextPageWithLayout = () => {
|
||||
};
|
||||
|
||||
Page.getLayout = function getLayout(page: ReactElement) {
|
||||
return <MainLayout backgroundColor="grey">{page}</MainLayout>;
|
||||
return <MainLayout>{page}</MainLayout>;
|
||||
};
|
||||
|
||||
export default Page;
|
||||
|
||||
@@ -76,3 +76,25 @@ main ::-webkit-scrollbar-thumb:hover,
|
||||
nextjs-portal {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.c__modal {
|
||||
box-shadow: 0 6px 18px 0 rgb(0 0 0 / 16%);
|
||||
}
|
||||
|
||||
.c__button--bordered,
|
||||
.c__button--bordered:hover {
|
||||
border: 1px solid var(--c--theme--colors--greyscale-200);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.c__button--bordered:focus {
|
||||
border: 1px solid rgb(0 0 0 / 16%);
|
||||
}
|
||||
|
||||
ul a {
|
||||
color: var(--c--theme--colors--greyscale-700);
|
||||
}
|
||||
|
||||
ul a:hover {
|
||||
color: var(--c--theme--colors--primary-800);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
declare module '*.json' {
|
||||
const value: Record<string, unknown>;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module '@/assets/lotties/*' {
|
||||
const value: Record<string, unknown>;
|
||||
export default value;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
declare module 'react-lottie' {
|
||||
import { Component } from 'react';
|
||||
|
||||
interface LottieOptions {
|
||||
loop?: boolean;
|
||||
autoplay?: boolean;
|
||||
animationData: Record<string, unknown>;
|
||||
rendererSettings?: {
|
||||
preserveAspectRatio?: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface LottieProps {
|
||||
options: LottieOptions;
|
||||
height?: number | string;
|
||||
width?: number | string;
|
||||
isStopped?: boolean;
|
||||
isPaused?: boolean;
|
||||
speed?: number;
|
||||
direction?: number;
|
||||
segments?: number[];
|
||||
goToAndPlay?: number;
|
||||
goToAndStop?: number;
|
||||
lottieRef?: (ref: unknown) => void;
|
||||
}
|
||||
|
||||
export default class Lottie extends Component<LottieProps> {}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { expect, test } from '@playwright/test';
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await expect(
|
||||
page.locator('header').first().locator('h2').getByText('Assistant'),
|
||||
page.locator('header').first().locator('svg[aria-label*="Logo"]'),
|
||||
).toBeVisible();
|
||||
await page.goto('unknown-page404');
|
||||
});
|
||||
|
||||
@@ -92,5 +92,5 @@ export const randomName = (name: string, browserName: string, length: number) =>
|
||||
|
||||
export const expectLoginPage = async (page: Page) =>
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Conversation with AI' }),
|
||||
page.getByRole('heading', { name: 'Your digital assistant' }),
|
||||
).toBeVisible();
|
||||
|
||||
@@ -18,11 +18,6 @@ test.describe('Footer', () => {
|
||||
await page.goto('/');
|
||||
const footer = page.locator('footer').first();
|
||||
|
||||
await expect(footer.getByAltText('Docs Logo')).toBeVisible();
|
||||
await expect(
|
||||
footer.getByRole('heading', { name: 'Assistant' }),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(footer.getByRole('link', { name: 'Github' })).toBeVisible();
|
||||
await expect(footer.getByRole('link', { name: 'DINUM' })).toBeVisible();
|
||||
|
||||
@@ -105,11 +100,6 @@ test.describe('Footer', () => {
|
||||
|
||||
await expect(footer.getByAltText('Gouvernement Logo')).toBeVisible();
|
||||
|
||||
await expect(
|
||||
footer.getByRole('heading', { name: 'Assistant' }),
|
||||
).toBeHidden();
|
||||
await expect(footer.getByText('BETA')).toBeHidden();
|
||||
|
||||
await expect(
|
||||
footer.getByRole('link', { name: 'legifrance.gouv.fr' }),
|
||||
).toBeVisible();
|
||||
|
||||
@@ -9,10 +9,6 @@ test.describe('Header', () => {
|
||||
const header = page.locator('header').first();
|
||||
|
||||
await expect(header.getByLabel('Assistant Logo')).toBeVisible();
|
||||
await expect(header.locator('h2').getByText('Assistant')).toHaveCSS(
|
||||
'font-family',
|
||||
/Roboto/i,
|
||||
);
|
||||
|
||||
await expect(
|
||||
header.getByRole('button', {
|
||||
@@ -34,10 +30,6 @@ test.describe('Header', () => {
|
||||
const header = page.locator('header').first();
|
||||
|
||||
await expect(header.getByLabel('Assistant Logo')).toBeVisible();
|
||||
await expect(header.locator('h2').getByText('Assistant')).toHaveCSS(
|
||||
'font-family',
|
||||
/Marianne/i,
|
||||
);
|
||||
|
||||
await expect(
|
||||
header.getByRole('button', {
|
||||
@@ -47,6 +39,8 @@ test.describe('Header', () => {
|
||||
|
||||
await expect(header.getByText('English')).toBeVisible();
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await expect(
|
||||
header.getByRole('button', {
|
||||
name: 'Les services de La Suite numérique',
|
||||
@@ -62,6 +56,8 @@ test.describe('Header', () => {
|
||||
|
||||
const header = page.locator('header').first();
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await expect(
|
||||
header.getByRole('button', {
|
||||
name: 'Les services de La Suite numérique',
|
||||
@@ -105,11 +101,6 @@ test.describe('Header mobile', () => {
|
||||
await expect(
|
||||
header.getByRole('link', { name: 'Assistant Logo' }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
header.getByRole('button', {
|
||||
name: 'Les services de La Suite numérique',
|
||||
}),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -21,15 +21,11 @@ test.describe('Home page', () => {
|
||||
await expect(
|
||||
header.getByRole('img', { name: 'Assistant logo' }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
header.getByRole('heading', { name: 'Assistant' }),
|
||||
).toBeVisible();
|
||||
|
||||
// Check the titles
|
||||
const h2 = page.locator('h2');
|
||||
await expect(h2.getByText('Govs ❤️ Open Source.')).toBeVisible();
|
||||
await expect(
|
||||
h2.getByText('Conversation with AI, simplified.'),
|
||||
h2.getByText('Your digital assistant'),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start conversation' }),
|
||||
@@ -76,21 +72,15 @@ test.describe('Home page', () => {
|
||||
header.getByRole('img', { name: 'Assistant logo' }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
header.getByRole('heading', { name: 'Assistant' }),
|
||||
header.getByRole('img', { name: 'Assistant logo' }),
|
||||
).toBeVisible();
|
||||
await expect(header.getByText('BETA')).toBeVisible();
|
||||
|
||||
// Check the titles
|
||||
const h2 = page.locator('h2');
|
||||
await expect(h2.getByText('Govs ❤️ Open Source.')).toBeVisible();
|
||||
await expect(
|
||||
h2.getByText('Conversation with AI, simplified.'),
|
||||
h2.getByText('Your digital assistant'),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Proconnect Login' }),
|
||||
).toHaveCount(2);
|
||||
|
||||
await expect(footer).toBeVisible();
|
||||
});
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ test.describe.serial('Language', () => {
|
||||
// initial language should be english
|
||||
await expect(
|
||||
page.getByRole('button', {
|
||||
name: 'New conversation',
|
||||
name: 'New chat',
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ test.describe('Left panel desktop', () => {
|
||||
test('checks all the elements are visible', async ({ page }) => {
|
||||
await expect(page.getByTestId('left-panel-desktop')).toBeVisible();
|
||||
await expect(page.getByTestId('left-panel-mobile')).toBeHidden();
|
||||
await expect(page.getByRole('button', { name: 'house' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'New conversation' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'New chat' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,30 +18,4 @@ test.describe('Left panel mobile', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
test('checks all the desktop elements are hidden and all mobile elements are visible', async ({
|
||||
page,
|
||||
}) => {
|
||||
await expect(page.getByTestId('left-panel-desktop')).toBeHidden();
|
||||
await expect(page.getByTestId('left-panel-mobile')).not.toBeInViewport();
|
||||
|
||||
const header = page.locator('header').first();
|
||||
const homeButton = page.getByRole('button', { name: 'house' });
|
||||
const newDocButton = page.getByRole('button', { name: 'New conversation' });
|
||||
const languageButton = page.getByRole('button', { name: /Language/ });
|
||||
const logoutButton = page.getByRole('button', { name: 'Logout' });
|
||||
|
||||
await expect(homeButton).not.toBeInViewport();
|
||||
await expect(newDocButton).not.toBeInViewport();
|
||||
await expect(languageButton).not.toBeInViewport();
|
||||
await expect(logoutButton).not.toBeInViewport();
|
||||
|
||||
await header.getByLabel('Open the header menu').click();
|
||||
|
||||
await expect(page.getByTestId('left-panel-mobile')).toBeInViewport();
|
||||
await expect(homeButton).toBeInViewport();
|
||||
await expect(newDocButton).toBeInViewport();
|
||||
await expect(languageButton).toBeInViewport();
|
||||
await expect(logoutButton).toBeInViewport();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6397,6 +6397,14 @@ babel-preset-jest@^29.6.3:
|
||||
babel-plugin-jest-hoist "^29.6.3"
|
||||
babel-preset-current-node-syntax "^1.0.0"
|
||||
|
||||
babel-runtime@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||
integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==
|
||||
dependencies:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.11.0"
|
||||
|
||||
bail@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz"
|
||||
@@ -6942,6 +6950,11 @@ core-js-compat@^3.40.0:
|
||||
dependencies:
|
||||
browserslist "^4.24.4"
|
||||
|
||||
core-js@^2.4.0:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||
|
||||
core-js@^3.0.0, core-js@^3.38.1:
|
||||
version "3.42.0"
|
||||
resolved "https://registry.npmjs.org/core-js/-/core-js-3.42.0.tgz"
|
||||
@@ -10001,6 +10014,11 @@ loose-envify@^1.0.0, loose-envify@^1.4.0:
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
lottie-web@^5.12.2:
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/lottie-web/-/lottie-web-5.13.0.tgz#441d3df217cc8ba302338c3f168e1a3af0f221d3"
|
||||
integrity sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==
|
||||
|
||||
lower-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz"
|
||||
@@ -11295,7 +11313,7 @@ prompts@^2.0.1:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@@ -11652,7 +11670,7 @@ react-dnd@^14.0.3:
|
||||
fast-deep-equal "^3.1.3"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
|
||||
react-dom@*, react-dom@19.0.0, react-dom@19.1.0:
|
||||
react-dom@18.3.1, react-dom@19.0.0, react-dom@19.1.0:
|
||||
version "19.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.1.0.tgz#133558deca37fa1d682708df8904b25186793623"
|
||||
integrity sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==
|
||||
@@ -11692,6 +11710,15 @@ react-lifecycles-compat@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react-lottie@^1.2.10:
|
||||
version "1.2.10"
|
||||
resolved "https://registry.yarnpkg.com/react-lottie/-/react-lottie-1.2.10.tgz#399f78a448a7833b2380d74fc489ecf15f8d18c7"
|
||||
integrity sha512-x0eWX3Z6zSx1XM5QSjnLupc6D22LlMCB0PH06O/N/epR2hsLaj1Vxd9RtMnbbEHjJ/qlsgHJ6bpN3vnZI92hjw==
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
lottie-web "^5.12.2"
|
||||
prop-types "^15.6.1"
|
||||
|
||||
react-markdown@10.1.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz"
|
||||
@@ -11959,6 +11986,11 @@ regenerate@^1.4.2:
|
||||
resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz"
|
||||
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
|
||||
|
||||
regenerator-runtime@^0.11.0:
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
||||
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
|
||||
|
||||
regexp.prototype.flags@^1.5.3:
|
||||
version "1.5.4"
|
||||
resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz"
|
||||
|
||||