mirror of
https://github.com/logto-io/logto.git
synced 2025-02-24 22:05:56 -05:00
refactor(console): remove protected app promotion (#6479)
This commit is contained in:
parent
0ec8510789
commit
fc512bc3ec
25 changed files with 205 additions and 431 deletions
|
@ -12,6 +12,7 @@ import nativeCapacitor from './native-capacitor/index';
|
|||
import nativeExpo from './native-expo/index';
|
||||
import nativeFlutter from './native-flutter/index';
|
||||
import nativeIosSwift from './native-ios-swift/index';
|
||||
import protectedApp from './protected-app/index';
|
||||
import spaAngular from './spa-angular/index';
|
||||
import spaChromeExtension from './spa-chrome-extension/index';
|
||||
import spaReact from './spa-react/index';
|
||||
|
@ -81,14 +82,6 @@ export const guides: Readonly<Guide[]> = Object.freeze([
|
|||
Component: lazy(async () => import('./spa-react/README.mdx')),
|
||||
metadata: spaReact,
|
||||
},
|
||||
{
|
||||
order: 1.2,
|
||||
id: 'm2m-general',
|
||||
Logo: lazy(async () => import('./m2m-general/logo.svg?react')),
|
||||
DarkLogo: lazy(async () => import('./m2m-general/logo-dark.svg?react')),
|
||||
Component: lazy(async () => import('./m2m-general/README.mdx')),
|
||||
metadata: m2mGeneral,
|
||||
},
|
||||
{
|
||||
order: 1.2,
|
||||
id: 'web-express',
|
||||
|
@ -113,6 +106,14 @@ export const guides: Readonly<Guide[]> = Object.freeze([
|
|||
Component: lazy(async () => import('./web-sveltekit/README.mdx')),
|
||||
metadata: webSveltekit,
|
||||
},
|
||||
{
|
||||
order: 1.3,
|
||||
id: 'spa-vue',
|
||||
Logo: lazy(async () => import('./spa-vue/logo.svg?react')),
|
||||
DarkLogo: undefined,
|
||||
Component: lazy(async () => import('./spa-vue/README.mdx')),
|
||||
metadata: spaVue,
|
||||
},
|
||||
{
|
||||
order: 1.3,
|
||||
id: 'web-go',
|
||||
|
@ -131,20 +132,28 @@ export const guides: Readonly<Guide[]> = Object.freeze([
|
|||
},
|
||||
{
|
||||
order: 1.4,
|
||||
id: 'protected-app',
|
||||
Logo: lazy(async () => import('./protected-app/logo.svg?react')),
|
||||
DarkLogo: lazy(async () => import('./protected-app/logo-dark.svg?react')),
|
||||
Component: lazy(async () => import('./protected-app/README.mdx')),
|
||||
metadata: protectedApp,
|
||||
},
|
||||
{
|
||||
order: 1.5,
|
||||
id: 'm2m-general',
|
||||
Logo: lazy(async () => import('./m2m-general/logo.svg?react')),
|
||||
DarkLogo: lazy(async () => import('./m2m-general/logo-dark.svg?react')),
|
||||
Component: lazy(async () => import('./m2m-general/README.mdx')),
|
||||
metadata: m2mGeneral,
|
||||
},
|
||||
{
|
||||
order: 1.6,
|
||||
id: 'web-java-spring-boot',
|
||||
Logo: lazy(async () => import('./web-java-spring-boot/logo.svg?react')),
|
||||
DarkLogo: undefined,
|
||||
Component: lazy(async () => import('./web-java-spring-boot/README.mdx')),
|
||||
metadata: webJavaSpringBoot,
|
||||
},
|
||||
{
|
||||
order: 1.6,
|
||||
id: 'spa-vue',
|
||||
Logo: lazy(async () => import('./spa-vue/logo.svg?react')),
|
||||
DarkLogo: undefined,
|
||||
Component: lazy(async () => import('./spa-vue/README.mdx')),
|
||||
metadata: spaVue,
|
||||
},
|
||||
{
|
||||
order: 1.7,
|
||||
id: 'native-ios-swift',
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"order": 1.2
|
||||
"order": 1.5
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
# Placeholder for protected app guide
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"order": 1.4
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { ApplicationType } from '@logto/schemas';
|
||||
|
||||
import { type GuideMetadata } from '../types';
|
||||
|
||||
const metadata: Readonly<GuideMetadata> = Object.freeze({
|
||||
name: 'Protected app',
|
||||
description: 'Non-SDK integration solution powered by Cloudflare Workers',
|
||||
target: ApplicationType.Protected,
|
||||
isFeatured: true,
|
||||
isCloud: true,
|
||||
skipGuideAfterCreation: true,
|
||||
});
|
||||
|
||||
export default metadata;
|
|
@ -0,0 +1,45 @@
|
|||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_11470_21298)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M39.0115 5.25065C39.3141 5.25496 39.5628 5.49988 39.5628 5.80249V24.1589C39.5628 30.7003 31.1501 38.1656 23.566 40.161C23.394 40.2063 23.2162 40.2063 23.0442 40.161C15.4601 38.1656 7.04736 30.7003 7.04736 24.1589V5.80249C7.04736 5.49988 7.29612 5.25496 7.59871 5.25065C16.1854 5.12836 20.9913 2.16331 22.7972 0.213738C23.0612 -0.0712458 23.549 -0.0712458 23.813 0.213737C25.6189 2.16331 30.4248 5.12836 39.0115 5.25065ZM26.6825 16.5744C26.6825 17.9009 25.8776 19.039 24.7306 19.5246L26.5349 24.2234C26.676 24.5911 26.4047 24.986 26.0109 24.986H20.4701C20.0548 24.986 19.7833 24.5505 19.9661 24.1776L22.2475 19.5246C21.1005 19.039 20.2955 17.9009 20.2955 16.5744C20.2955 14.8065 21.7253 13.3733 23.489 13.3733C25.2527 13.3733 26.6825 14.8065 26.6825 16.5744Z" fill="url(#paint0_linear_11470_21298)"/>
|
||||
<mask id="path-3-inside-1_11470_21298" fill="white">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.7972 0.213737C22.9292 0.0712637 23.1171 1.78196e-05 23.305 0V13.3785C21.6269 13.4741 20.2955 14.8684 20.2955 16.5744C20.2955 17.9009 21.1005 19.039 22.2475 19.5246L19.9661 24.1776C19.7833 24.5505 20.0548 24.986 20.4701 24.986H23.305V40.195C23.2176 40.195 23.1301 40.1837 23.0442 40.161C15.4601 38.1656 7.04736 30.7003 7.04736 24.1589V5.80249C7.04736 5.49988 7.29612 5.25496 7.59871 5.25065C16.1854 5.12836 20.9913 2.16331 22.7972 0.213737Z"/>
|
||||
</mask>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.7972 0.213737C22.9292 0.0712637 23.1171 1.78196e-05 23.305 0V13.3785C21.6269 13.4741 20.2955 14.8684 20.2955 16.5744C20.2955 17.9009 21.1005 19.039 22.2475 19.5246L19.9661 24.1776C19.7833 24.5505 20.0548 24.986 20.4701 24.986H23.305V40.195C23.2176 40.195 23.1301 40.1837 23.0442 40.161C15.4601 38.1656 7.04736 30.7003 7.04736 24.1589V5.80249C7.04736 5.49988 7.29612 5.25496 7.59871 5.25065C16.1854 5.12836 20.9913 2.16331 22.7972 0.213737Z" fill="url(#paint1_linear_11470_21298)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.7972 0.213737C22.9292 0.0712637 23.1171 1.78196e-05 23.305 0V13.3785C21.6269 13.4741 20.2955 14.8684 20.2955 16.5744C20.2955 17.9009 21.1005 19.039 22.2475 19.5246L19.9661 24.1776C19.7833 24.5505 20.0548 24.986 20.4701 24.986H23.305V40.195C23.2176 40.195 23.1301 40.1837 23.0442 40.161C15.4601 38.1656 7.04736 30.7003 7.04736 24.1589V5.80249C7.04736 5.49988 7.29612 5.25496 7.59871 5.25065C16.1854 5.12836 20.9913 2.16331 22.7972 0.213737Z" fill="#4300DA"/>
|
||||
<path d="M23.305 0H36.5651V-13.2613L23.3038 -13.26L23.305 0ZM22.7972 0.213737L13.0692 -8.79712L13.0692 -8.79711L22.7972 0.213737ZM23.305 13.3785L24.0589 26.6171L36.5651 25.905V13.3785H23.305ZM22.2475 19.5246L34.1535 25.362L40.3233 12.778L27.4172 7.31382L22.2475 19.5246ZM19.9661 24.1776L8.06011 18.3401L8.06011 18.3401L19.9661 24.1776ZM23.305 24.986H36.5651V11.7259H23.305V24.986ZM23.305 40.195L23.3039 53.455L36.5651 53.4562V40.195H23.305ZM23.0442 40.161L26.4183 27.3375L26.4182 27.3374L23.0442 40.161ZM7.59871 5.25065L7.78753 18.5093L7.78754 18.5093L7.59871 5.25065ZM23.3038 -13.26C19.8812 -13.2597 16.0055 -11.967 13.0692 -8.79712L32.5252 9.2246C29.8529 12.1095 26.353 13.2598 23.3063 13.26L23.3038 -13.26ZM36.5651 13.3785V0H10.045V13.3785H36.5651ZM22.5512 0.139928C13.867 0.634423 7.03551 7.82492 7.03551 16.5744H33.5556C33.5556 21.9118 29.3869 26.3137 24.0589 26.6171L22.5512 0.139928ZM7.03551 16.5744C7.03551 23.3982 11.1866 29.2411 17.0777 31.7353L27.4172 7.31382C31.0143 8.83676 33.5556 12.4036 33.5556 16.5744H7.03551ZM10.3414 13.6871L8.06011 18.3401L31.8721 30.015L34.1535 25.362L10.3414 13.6871ZM8.06011 18.3401C3.55766 27.5233 10.2426 38.246 20.4701 38.246V11.7259C29.8669 11.7259 36.0089 21.5777 31.8721 30.015L8.06011 18.3401ZM20.4701 38.246H23.305V11.7259H20.4701V38.246ZM36.5651 40.195V24.986H10.045V40.195H36.5651ZM19.6701 52.9846C20.8482 53.2946 22.069 53.4549 23.3039 53.455L23.3062 26.9349C24.3661 26.935 25.4121 27.0727 26.4183 27.3375L19.6701 52.9846ZM-6.21268 24.1589C-6.21268 32.7287 -1.09566 39.4747 3.01175 43.4236C7.46385 47.7039 13.4063 51.3366 19.6702 52.9846L26.4182 27.3374C25.8572 27.1898 25.0166 26.8629 24.0287 26.2863C23.0545 25.7177 22.1379 25.0232 21.3917 24.3058C20.6243 23.568 20.2377 23.0005 20.1014 22.7525C19.9478 22.4728 20.3074 22.9773 20.3074 24.1589H-6.21268ZM-6.21268 5.80249V24.1589H20.3074V5.80249H-6.21268ZM7.40989 -8.00805C0.0881227 -7.90378 -6.21268 -1.97747 -6.21268 5.80249H20.3074C20.3074 12.9772 14.5041 18.4137 7.78753 18.5093L7.40989 -8.00805ZM13.0692 -8.79711C13.7187 -9.4983 13.8105 -9.29199 12.816 -8.89418C11.9313 -8.5403 10.201 -8.0478 7.40987 -8.00805L7.78754 18.5093C19.2291 18.3464 27.7748 14.353 32.5252 9.22458L13.0692 -8.79711Z" fill="#9C85FD" mask="url(#path-3-inside-1_11470_21298)"/>
|
||||
<rect y="25.7119" width="4.35475" height="4.35475" rx="0.5" fill="url(#paint2_linear_11470_21298)"/>
|
||||
<rect y="8.29297" width="4.35475" height="4.35475" rx="0.5" fill="url(#paint3_linear_11470_21298)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0964 21.737C12.2209 21.6105 12.1313 21.3967 11.9539 21.3967L0.512293 21.3965C0.234484 21.3965 0.00927773 21.1713 0.0092777 20.8935L0.00927739 17.3835C0.00927736 17.1057 0.234491 16.8804 0.512305 16.8804L11.9477 16.8806C12.126 16.8806 12.2152 16.6648 12.0889 16.5389L9.04317 13.5027C8.72714 13.1876 8.95079 12.6478 9.39703 12.6486L12.8315 12.6544C13.111 12.6549 13.3775 12.7723 13.5665 12.9782L18.8991 18.7881C19.185 19.0996 19.1791 19.5798 18.8857 19.8842L13.565 25.4046C13.3765 25.6001 13.1166 25.7106 12.845 25.7106L9.37825 25.7107C8.93468 25.7107 8.71074 25.176 9.02193 24.8599L12.0964 21.737Z" fill="#F7F8F8" fill-opacity="0.14"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0964 21.737C12.2209 21.6105 12.1313 21.3967 11.9539 21.3967L0.512293 21.3965C0.234484 21.3965 0.00927773 21.1713 0.0092777 20.8935L0.00927739 17.3835C0.00927736 17.1057 0.234491 16.8804 0.512305 16.8804L11.9477 16.8806C12.126 16.8806 12.2152 16.6648 12.0889 16.5389L9.04317 13.5027C8.72714 13.1876 8.95079 12.6478 9.39703 12.6486L12.8315 12.6544C13.111 12.6549 13.3775 12.7723 13.5665 12.9782L18.8991 18.7881C19.185 19.0996 19.1791 19.5798 18.8857 19.8842L13.565 25.4046C13.3765 25.6001 13.1166 25.7106 12.845 25.7106L9.37825 25.7107C8.93468 25.7107 8.71074 25.176 9.02193 24.8599L12.0964 21.737Z" fill="url(#paint4_linear_11470_21298)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0964 21.737C12.2209 21.6105 12.1313 21.3967 11.9539 21.3967L0.512293 21.3965C0.234484 21.3965 0.00927773 21.1713 0.0092777 20.8935L0.00927739 17.3835C0.00927736 17.1057 0.234491 16.8804 0.512305 16.8804L11.9477 16.8806C12.126 16.8806 12.2152 16.6648 12.0889 16.5389L9.04317 13.5027C8.72714 13.1876 8.95079 12.6478 9.39703 12.6486L12.8315 12.6544C13.111 12.6549 13.3775 12.7723 13.5665 12.9782L18.8991 18.7881C19.185 19.0996 19.1791 19.5798 18.8857 19.8842L13.565 25.4046C13.3765 25.6001 13.1166 25.7106 12.845 25.7106L9.37825 25.7107C8.93468 25.7107 8.71074 25.176 9.02193 24.8599L12.0964 21.737Z" fill="url(#paint5_linear_11470_21298)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_11470_21298" x1="4.37645" y1="22.7996" x2="40.7275" y2="12.1142" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#492EF3"/>
|
||||
<stop offset="1" stop-color="#CF69FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_11470_21298" x1="5.71191" y1="23.0284" x2="25.027" y2="20.1438" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#492EF3"/>
|
||||
<stop offset="1" stop-color="#CF69FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_11470_21298" x1="9.76044" y1="26.73" x2="-3.69309" y2="29.1027" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF06A"/>
|
||||
<stop offset="1" stop-color="#EC78FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_11470_21298" x1="9.76044" y1="9.3111" x2="-3.69309" y2="11.6838" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF06A"/>
|
||||
<stop offset="1" stop-color="#EC78FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_11470_21298" x1="-25.2091" y1="23.334" x2="19.7357" y2="10.6593" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF06A"/>
|
||||
<stop offset="1" stop-color="#EC78FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_11470_21298" x1="-8.55895" y1="24.3039" x2="32.2319" y2="9.9529" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EC78FF"/>
|
||||
<stop offset="1" stop-color="#FFF06A"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_11470_21298">
|
||||
<rect width="40" height="40" rx="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 8.3 KiB |
|
@ -0,0 +1,41 @@
|
|||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_11470_21285)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M39.0115 5.25065C39.3141 5.25496 39.5628 5.49988 39.5628 5.80249V24.1589C39.5628 30.7003 31.1501 38.1656 23.566 40.161C23.394 40.2063 23.2162 40.2063 23.0442 40.161C15.4601 38.1656 7.04736 30.7003 7.04736 24.1589V5.80249C7.04736 5.49988 7.29612 5.25496 7.59871 5.25065C16.1854 5.12836 20.9913 2.16331 22.7972 0.213738C23.0612 -0.0712458 23.549 -0.0712459 23.813 0.213737C25.6189 2.16331 30.4248 5.12836 39.0115 5.25065ZM26.6825 16.5744C26.6825 17.9009 25.8776 19.039 24.7306 19.5246L26.5349 24.2234C26.676 24.5911 26.4047 24.986 26.0109 24.986H20.4701C20.0548 24.986 19.7833 24.5505 19.9661 24.1776L22.2475 19.5246C21.1005 19.039 20.2955 17.9009 20.2955 16.5744C20.2955 14.8065 21.7253 13.3733 23.489 13.3733C25.2527 13.3733 26.6825 14.8065 26.6825 16.5744Z" fill="url(#paint0_linear_11470_21285)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.7972 0.213737C22.9292 0.0712637 23.1171 1.78196e-05 23.305 0V13.3785C21.6269 13.4741 20.2955 14.8684 20.2955 16.5744C20.2955 17.9009 21.1005 19.039 22.2475 19.5246L19.9661 24.1776C19.7833 24.5505 20.0548 24.986 20.4701 24.986H23.305V40.195C23.2176 40.195 23.1301 40.1837 23.0442 40.161C15.4601 38.1656 7.04736 30.7003 7.04736 24.1589V5.80249C7.04736 5.49988 7.29612 5.25496 7.59871 5.25065C16.1854 5.12836 20.9913 2.16331 22.7972 0.213737Z" fill="url(#paint1_linear_11470_21285)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.7972 0.213737C22.9292 0.0712637 23.1171 1.78196e-05 23.305 0V13.3785C21.6269 13.4741 20.2955 14.8684 20.2955 16.5744C20.2955 17.9009 21.1005 19.039 22.2475 19.5246L19.9661 24.1776C19.7833 24.5505 20.0548 24.986 20.4701 24.986H23.305V40.195C23.2176 40.195 23.1301 40.1837 23.0442 40.161C15.4601 38.1656 7.04736 30.7003 7.04736 24.1589V5.80249C7.04736 5.49988 7.29612 5.25496 7.59871 5.25065C16.1854 5.12836 20.9913 2.16331 22.7972 0.213737Z" fill="#4300DA"/>
|
||||
<rect y="25.7119" width="4.35475" height="4.35475" rx="0.5" fill="url(#paint2_linear_11470_21285)"/>
|
||||
<rect y="8.29297" width="4.35475" height="4.35475" rx="0.5" fill="url(#paint3_linear_11470_21285)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0964 21.737C12.2209 21.6105 12.1313 21.3967 11.9539 21.3967L0.512293 21.3965C0.234484 21.3965 0.00927773 21.1713 0.0092777 20.8935L0.00927739 17.3835C0.00927736 17.1057 0.234491 16.8804 0.512305 16.8804L11.9477 16.8806C12.126 16.8806 12.2152 16.6648 12.0889 16.5389L9.04317 13.5027C8.72714 13.1876 8.95079 12.6478 9.39703 12.6486L12.8315 12.6544C13.111 12.6549 13.3775 12.7723 13.5665 12.9782L18.8991 18.7881C19.185 19.0996 19.1791 19.5798 18.8857 19.8842L13.565 25.4046C13.3765 25.6001 13.1166 25.7106 12.845 25.7106L9.37825 25.7107C8.93468 25.7107 8.71074 25.176 9.02193 24.8599L12.0964 21.737Z" fill="#191C1D" fill-opacity="0.12"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0964 21.737C12.2209 21.6105 12.1313 21.3967 11.9539 21.3967L0.512293 21.3965C0.234484 21.3965 0.00927773 21.1713 0.0092777 20.8935L0.00927739 17.3835C0.00927736 17.1057 0.234491 16.8804 0.512305 16.8804L11.9477 16.8806C12.126 16.8806 12.2152 16.6648 12.0889 16.5389L9.04317 13.5027C8.72714 13.1876 8.95079 12.6478 9.39703 12.6486L12.8315 12.6544C13.111 12.6549 13.3775 12.7723 13.5665 12.9782L18.8991 18.7881C19.185 19.0996 19.1791 19.5798 18.8857 19.8842L13.565 25.4046C13.3765 25.6001 13.1166 25.7106 12.845 25.7106L9.37825 25.7107C8.93468 25.7107 8.71074 25.176 9.02193 24.8599L12.0964 21.737Z" fill="url(#paint4_linear_11470_21285)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0964 21.737C12.2209 21.6105 12.1313 21.3967 11.9539 21.3967L0.512293 21.3965C0.234484 21.3965 0.00927773 21.1713 0.0092777 20.8935L0.00927739 17.3835C0.00927736 17.1057 0.234491 16.8804 0.512305 16.8804L11.9477 16.8806C12.126 16.8806 12.2152 16.6648 12.0889 16.5389L9.04317 13.5027C8.72714 13.1876 8.95079 12.6478 9.39703 12.6486L12.8315 12.6544C13.111 12.6549 13.3775 12.7723 13.5665 12.9782L18.8991 18.7881C19.185 19.0996 19.1791 19.5798 18.8857 19.8842L13.565 25.4046C13.3765 25.6001 13.1166 25.7106 12.845 25.7106L9.37825 25.7107C8.93468 25.7107 8.71074 25.176 9.02193 24.8599L12.0964 21.737Z" fill="url(#paint5_linear_11470_21285)"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_11470_21285" x1="4.37645" y1="22.7996" x2="40.7275" y2="12.1142" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#492EF3"/>
|
||||
<stop offset="1" stop-color="#CF69FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_11470_21285" x1="5.71191" y1="23.0284" x2="25.027" y2="20.1438" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#492EF3"/>
|
||||
<stop offset="1" stop-color="#CF69FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_11470_21285" x1="9.76044" y1="26.73" x2="-3.69309" y2="29.1027" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF06A"/>
|
||||
<stop offset="1" stop-color="#EC78FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_11470_21285" x1="9.76044" y1="9.3111" x2="-3.69309" y2="11.6838" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF06A"/>
|
||||
<stop offset="1" stop-color="#EC78FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_11470_21285" x1="-25.2091" y1="23.3339" x2="19.7357" y2="10.6593" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF06A"/>
|
||||
<stop offset="1" stop-color="#EC78FF"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_11470_21285" x1="-8.55895" y1="24.3039" x2="32.2319" y2="9.9529" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EC78FF"/>
|
||||
<stop offset="1" stop-color="#FFF06A"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_11470_21285">
|
||||
<rect width="40" height="40" rx="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 5.6 KiB |
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"order": 1.6
|
||||
"order": 1.3
|
||||
}
|
||||
|
|
|
@ -4,9 +4,10 @@ import { type GuideMetadata } from '../types';
|
|||
|
||||
const metadata: Readonly<GuideMetadata> = Object.freeze({
|
||||
name: 'OIDC',
|
||||
description: 'Use Logto as a third-party OIDC identity provider (IdP) for your application. ',
|
||||
description: 'Use Logto as a third-party OIDC identity provider (IdP) for your application.',
|
||||
target: ApplicationType.Traditional,
|
||||
isThirdParty: true,
|
||||
skipGuideAfterCreation: true,
|
||||
});
|
||||
|
||||
export default metadata;
|
||||
|
|
|
@ -27,13 +27,14 @@ export type GuideMetadata = {
|
|||
};
|
||||
/** Whether the guide is displayed in featured group. */
|
||||
isFeatured?: boolean;
|
||||
|
||||
/** Indicate whether the application is for third-party use */
|
||||
/** Indicate whether the application is for third-party use. */
|
||||
isThirdParty?: boolean;
|
||||
|
||||
/** Indicate whether the application is Cloud only. E.g. Protected app */
|
||||
isCloud?: boolean;
|
||||
/** Indicates whether we should skip the guide after creating the application. */
|
||||
skipGuideAfterCreation?: boolean;
|
||||
/** The related complete guide url relative to the quick starts page (https://docs.logto.io/quick-starts). */
|
||||
fullGuide?: string;
|
||||
|
||||
/** The related URLs to add to the further readings section. */
|
||||
furtherReadings?: Array<{
|
||||
title: string;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"order": 1.4
|
||||
"order": 1.6
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import { ApplicationType } from '@logto/schemas';
|
||||
|
||||
import { isCloud } from '@/consts/env';
|
||||
|
||||
import { type GuideMetadata } from '../types';
|
||||
|
||||
const metadata: Readonly<GuideMetadata> = Object.freeze({
|
||||
|
@ -7,7 +9,7 @@ const metadata: Readonly<GuideMetadata> = Object.freeze({
|
|||
description:
|
||||
'Ruby is a dynamic, open-source programming language with a focus on simplicity and productivity.',
|
||||
target: ApplicationType.Traditional,
|
||||
isFeatured: true,
|
||||
isFeatured: !isCloud,
|
||||
sample: {
|
||||
repo: 'ruby',
|
||||
path: 'logto-sample',
|
||||
|
|
|
@ -14,9 +14,7 @@ import styles from './index.module.scss';
|
|||
|
||||
export type SelectedGuide = {
|
||||
id: Guide['id'];
|
||||
target: GuideMetadata['target'];
|
||||
name: GuideMetadata['name'];
|
||||
isThirdParty: GuideMetadata['isThirdParty'];
|
||||
metadata: GuideMetadata;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
|
@ -27,13 +25,9 @@ type Props = {
|
|||
};
|
||||
|
||||
function GuideCard({ data, onClick, hasBorder, hasButton }: Props) {
|
||||
const {
|
||||
id,
|
||||
Logo,
|
||||
DarkLogo,
|
||||
metadata: { target, name, description, isThirdParty },
|
||||
} = data;
|
||||
const { id, Logo, DarkLogo, metadata } = data;
|
||||
|
||||
const { target, name, description, isThirdParty } = metadata;
|
||||
const buttonText = target === 'API' ? 'guide.get_started' : 'guide.start_building';
|
||||
const { currentSubscriptionQuota } = useContext(SubscriptionDataContext);
|
||||
const theme = useTheme();
|
||||
|
@ -42,8 +36,8 @@ function GuideCard({ data, onClick, hasBorder, hasButton }: Props) {
|
|||
const showBetaTag = isCloud && isThirdParty;
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
onClick({ id, target, name, isThirdParty });
|
||||
}, [onClick, id, target, name, isThirdParty]);
|
||||
onClick({ id, metadata });
|
||||
}, [onClick, id, metadata]);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
@ -2,6 +2,7 @@ import { useCallback, useMemo } from 'react';
|
|||
|
||||
import { guides } from '@/assets/docs/guides';
|
||||
import { type Guide } from '@/assets/docs/guides/types';
|
||||
import { isCloud as isCloudEnv } from '@/consts/env';
|
||||
import {
|
||||
thirdPartyAppCategory,
|
||||
type AppGuideCategory,
|
||||
|
@ -33,7 +34,10 @@ export const useAppGuideMetadata = (): {
|
|||
) => Record<AppGuideCategory, readonly Guide[]>;
|
||||
} => {
|
||||
const appGuides = useMemo(
|
||||
() => guides.filter(({ metadata: { target } }) => target !== 'API'),
|
||||
() =>
|
||||
guides.filter(
|
||||
({ metadata: { target, isCloud } }) => target !== 'API' && (isCloudEnv || !isCloud)
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ function GuideDrawer({ apiResource, onClose }: Props) {
|
|||
<ArrowLeft />
|
||||
</IconButton>
|
||||
<div className={styles.separator} />
|
||||
<span>{t('checkout_tutorial', { name: selectedGuide.name })}</span>
|
||||
<span>{t('checkout_tutorial', { name: selectedGuide.metadata.name })}</span>
|
||||
</>
|
||||
)}
|
||||
{!selectedGuide && t('api.select_a_tutorial')}
|
||||
|
|
|
@ -59,7 +59,7 @@ function GuideLibrary({ className, hasCardBorder, hasCardButton }: Props) {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{selectedGuide?.target === 'API' && showCreateForm && (
|
||||
{selectedGuide?.metadata.target === 'API' && showCreateForm && (
|
||||
<CreateForm onClose={onCloseCreateForm} />
|
||||
)}
|
||||
</OverlayScrollbar>
|
||||
|
|
|
@ -39,11 +39,8 @@ function GuideDrawer({ app, secrets, onClose }: Props) {
|
|||
if (hasSingleGuide) {
|
||||
const guide = structuredMetadata[app.type][0];
|
||||
if (guide) {
|
||||
const {
|
||||
id,
|
||||
metadata: { target, name, isThirdParty },
|
||||
} = guide;
|
||||
setSelectedGuide({ id, target, name, isThirdParty });
|
||||
const { id, metadata } = guide;
|
||||
setSelectedGuide({ id, metadata });
|
||||
}
|
||||
}
|
||||
}, [hasSingleGuide, app.type, structuredMetadata]);
|
||||
|
@ -66,7 +63,7 @@ function GuideDrawer({ app, secrets, onClose }: Props) {
|
|||
<div className={styles.separator} />
|
||||
</>
|
||||
)}
|
||||
<span>{t('checkout_tutorial', { name: selectedGuide.name })}</span>
|
||||
<span>{t('checkout_tutorial', { name: selectedGuide.metadata.name })}</span>
|
||||
</>
|
||||
)}
|
||||
{!selectedGuide && t('app.select_a_framework')}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ApplicationType, ReservedPlanId } from '@logto/schemas';
|
||||
import { ReservedPlanId } from '@logto/schemas';
|
||||
import { cond } from '@silverhand/essentials';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback, useContext, useMemo, useState } from 'react';
|
||||
|
@ -20,8 +20,6 @@ import TextLink from '@/ds-components/TextLink';
|
|||
import { allAppGuideCategories, type AppGuideCategory } from '@/types/applications';
|
||||
import { thirdPartyAppCategory } from '@/types/applications';
|
||||
|
||||
import ProtectedAppCard from '../ProtectedAppCard';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
|
@ -131,34 +129,21 @@ function GuideLibrary({ className, hasCardBorder, hasCardButton, onSelectGuide }
|
|||
) : (
|
||||
<EmptyDataPlaceholder className={styles.emptyPlaceholder} size="large" />
|
||||
))}
|
||||
{!keyword && (
|
||||
<>
|
||||
{isCloud &&
|
||||
(filterCategories.length === 0 ||
|
||||
filterCategories.includes(ApplicationType.Protected)) && (
|
||||
<ProtectedAppCard
|
||||
isInAppCreationPage
|
||||
hasCreateButton
|
||||
hasBorder={hasCardBorder}
|
||||
className={styles.protectedAppCard}
|
||||
{!keyword &&
|
||||
(filterCategories.length > 0 ? filterCategories : fullApplicationCategories).map(
|
||||
(category) =>
|
||||
structuredMetadata[category].length > 0 && (
|
||||
<GuideCardGroup
|
||||
key={category}
|
||||
className={styles.guideGroup}
|
||||
hasCardBorder={hasCardBorder}
|
||||
hasCardButton={hasCardButton}
|
||||
categoryName={t(`guide.categories.${category}`)}
|
||||
guides={structuredMetadata[category]}
|
||||
onClickGuide={onClickGuide}
|
||||
/>
|
||||
)}
|
||||
{(filterCategories.length > 0 ? filterCategories : fullApplicationCategories).map(
|
||||
(category) =>
|
||||
structuredMetadata[category].length > 0 && (
|
||||
<GuideCardGroup
|
||||
key={category}
|
||||
className={styles.guideGroup}
|
||||
hasCardBorder={hasCardBorder}
|
||||
hasCardButton={hasCardButton}
|
||||
categoryName={t(`guide.categories.${category}`)}
|
||||
guides={structuredMetadata[category]}
|
||||
onClickGuide={onClickGuide}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
)
|
||||
)}
|
||||
{!isApplicationCreateModal && (
|
||||
<TextLink className={styles.viewAll} to="/applications/create">
|
||||
{t('get_started.view_all')}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: _.unit(4);
|
||||
|
||||
label {
|
||||
color: var(--color-text-secondary);
|
||||
font: var(--font-section-head-1);
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: _.unit(6) _.unit(8);
|
||||
gap: _.unit(6);
|
||||
background-color: var(--color-layer-1);
|
||||
border-radius: 12px;
|
||||
|
||||
&.hasBorder {
|
||||
border: 1px solid var(--color-divider);
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.columnWrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.titleRowWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: _.unit(3);
|
||||
}
|
||||
|
||||
.title {
|
||||
font: var(--font-title-2);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.label {
|
||||
font: var(--font-label-2);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.description {
|
||||
font: var(--font-body-2);
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
import { type Application, Theme } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useState } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
import ProtectedAppDarkIcon from '@/assets/icons/protected-app-dark.svg?react';
|
||||
import ProtectedAppIcon from '@/assets/icons/protected-app.svg?react';
|
||||
import Button from '@/ds-components/Button';
|
||||
import TextLink from '@/ds-components/TextLink';
|
||||
import useDocumentationUrl from '@/hooks/use-documentation-url';
|
||||
import useTheme from '@/hooks/use-theme';
|
||||
|
||||
import ProtectedAppModal from '../ProtectedAppModal';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
readonly className?: string;
|
||||
/** When used in application creation modal, card has a "PROTECTED APP" label on top of it */
|
||||
readonly isInAppCreationPage?: boolean;
|
||||
readonly hasBorder?: boolean;
|
||||
readonly hasCreateButton?: boolean;
|
||||
readonly onCreateSuccess?: (app: Application) => void;
|
||||
};
|
||||
|
||||
function ProtectedAppCard({
|
||||
className,
|
||||
isInAppCreationPage,
|
||||
hasBorder,
|
||||
hasCreateButton,
|
||||
onCreateSuccess,
|
||||
}: Props) {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.protected_app' });
|
||||
const { getDocumentationUrl } = useDocumentationUrl();
|
||||
const [showCreateModal, setShowCreateModal] = useState<boolean>(false);
|
||||
const theme = useTheme();
|
||||
const Icon = theme === Theme.Light ? ProtectedAppIcon : ProtectedAppDarkIcon;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classNames(styles.container, className)}>
|
||||
{isInAppCreationPage && <label>{t('name')}</label>}
|
||||
<div className={classNames(styles.card, hasBorder && styles.hasBorder)}>
|
||||
<Icon className={styles.logo} />
|
||||
<div className={styles.columnWrapper}>
|
||||
<div className={styles.titleRowWrapper}>
|
||||
<div className={isInAppCreationPage ? styles.label : styles.title}>
|
||||
{t(isInAppCreationPage ? 'name' : 'title')}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.description}>
|
||||
<Trans
|
||||
components={{
|
||||
a: (
|
||||
<TextLink
|
||||
href={getDocumentationUrl('/docs/recipes/protected-app/')}
|
||||
targetBlank="noopener"
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{t('description')}
|
||||
</Trans>
|
||||
</div>
|
||||
</div>
|
||||
{hasCreateButton && (
|
||||
<Button
|
||||
title="protected_app.fast_create"
|
||||
onClick={() => {
|
||||
setShowCreateModal(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{showCreateModal && (
|
||||
<ProtectedAppModal
|
||||
onClose={(app) => {
|
||||
setShowCreateModal(false);
|
||||
if (app) {
|
||||
onCreateSuccess?.(app);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProtectedAppCard;
|
|
@ -1,4 +1,4 @@
|
|||
import { type Application } from '@logto/schemas';
|
||||
import { ApplicationType, type Application } from '@logto/schemas';
|
||||
import { type Nullable, joinPath, cond } from '@silverhand/essentials';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
@ -23,6 +23,7 @@ import { buildUrl } from '@/utils/url';
|
|||
|
||||
import GuideLibrary from './components/GuideLibrary';
|
||||
import GuideLibraryModal from './components/GuideLibraryModal';
|
||||
import ProtectedAppModal from './components/ProtectedAppModal';
|
||||
import useApplicationsData from './hooks/use-application-data';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
|
@ -81,7 +82,7 @@ function Applications({ tab }: Props) {
|
|||
/**
|
||||
* Navigate to the application details page if no framework guide is selected or the selected guide is third party
|
||||
*/
|
||||
if (selectedGuide === null || selectedGuide?.isThirdParty) {
|
||||
if (selectedGuide === null || selectedGuide?.metadata.skipGuideAfterCreation) {
|
||||
navigate(`/applications/${newApp.id}`, { replace: true });
|
||||
setSelectedGuide(undefined);
|
||||
return;
|
||||
|
@ -205,12 +206,21 @@ function Applications({ tab }: Props) {
|
|||
/>
|
||||
{selectedGuide !== undefined && (
|
||||
<ApplicationCreation
|
||||
defaultCreateType={cond(selectedGuide?.target !== 'API' && selectedGuide?.target)}
|
||||
defaultCreateFrameworkName={selectedGuide?.name ?? undefined}
|
||||
isDefaultCreateThirdParty={selectedGuide?.isThirdParty ?? undefined}
|
||||
defaultCreateType={cond(
|
||||
selectedGuide?.metadata.target !== 'API' && selectedGuide?.metadata.target
|
||||
)}
|
||||
defaultCreateFrameworkName={selectedGuide?.metadata.name ?? undefined}
|
||||
isDefaultCreateThirdParty={selectedGuide?.metadata.isThirdParty ?? undefined}
|
||||
onCompleted={onAppCreationCompleted}
|
||||
/>
|
||||
)}
|
||||
{selectedGuide?.metadata.target === ApplicationType.Protected && (
|
||||
<ProtectedAppModal
|
||||
onClose={() => {
|
||||
setSelectedGuide(undefined);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.container {
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--color-divider);
|
||||
overflow: hidden;
|
||||
|
||||
.separator {
|
||||
border-bottom: 1px solid var(--color-divider);
|
||||
}
|
||||
|
||||
.form {
|
||||
background: var(--color-layer-light);
|
||||
padding: _.unit(6) _.unit(8) _.unit(8) _.unit(11);
|
||||
}
|
||||
|
||||
.protectedApps {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: _.unit(3);
|
||||
background: var(--color-success-container);
|
||||
padding: _.unit(5) _.unit(9);
|
||||
|
||||
.label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font: var(--font-label-2);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: _.unit(3) _.unit(8);
|
||||
}
|
||||
|
||||
.app {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: _.unit(5);
|
||||
gap: _.unit(3);
|
||||
font: var(--font-body-2);
|
||||
|
||||
.status {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-on-success-container);
|
||||
margin-right: _.unit(-1);
|
||||
}
|
||||
|
||||
.hostName {
|
||||
margin-right: _.unit(-3);
|
||||
color: var(--color-text);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.loadingSkeleton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: _.unit(6);
|
||||
padding: _.unit(6) _.unit(8);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--color-divider);
|
||||
|
||||
.bone {
|
||||
border-radius: 8px;
|
||||
@include _.shimmering-animation;
|
||||
}
|
||||
|
||||
.columnWrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: _.unit(2);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.description {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
import { type Application } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import OpenExternalLink from '@/components/OpenExternalLink';
|
||||
import CopyToClipboard from '@/ds-components/CopyToClipboard';
|
||||
import useApplicationsUsage from '@/hooks/use-applications-usage';
|
||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||
import ProtectedAppCard from '@/pages/Applications/components/ProtectedAppCard';
|
||||
import ProtectedAppForm from '@/pages/Applications/components/ProtectedAppForm';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
|
||||
function ProtectedAppCreationForm() {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { getTo } = useTenantPathname();
|
||||
const { data, isLoading, mutate } = useSWR<Application[]>('api/applications?types=Protected');
|
||||
const { hasAppsReachedLimit } = useApplicationsUsage();
|
||||
const hasProtectedApps = !isLoading && !!data?.length;
|
||||
const showCreationForm = !hasProtectedApps && !hasAppsReachedLimit;
|
||||
|
||||
const mutateApps = useCallback(
|
||||
(app: Application) => {
|
||||
void mutate([...(data ?? []), app]);
|
||||
},
|
||||
[data, mutate]
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={styles.loadingSkeleton}>
|
||||
<div className={classNames(styles.bone, styles.icon)} />
|
||||
<div className={styles.columnWrapper}>
|
||||
<div className={classNames(styles.bone, styles.title)} />
|
||||
<div className={classNames(styles.bone, styles.description)} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<ProtectedAppCard hasCreateButton={!showCreationForm} onCreateSuccess={mutateApps} />
|
||||
{showCreationForm && (
|
||||
<>
|
||||
<div className={styles.separator} />
|
||||
<div className={styles.form}>
|
||||
<ProtectedAppForm
|
||||
hasDetailedInstructions
|
||||
buttonAlignment="left"
|
||||
buttonText="protected_app.form.create_protected_app"
|
||||
buttonSize="medium"
|
||||
onCreateSuccess={mutateApps}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{hasProtectedApps && (
|
||||
<div className={styles.protectedApps}>
|
||||
<div className={styles.label}>{t('protected_app.success_message')}</div>
|
||||
<div className={styles.list}>
|
||||
{data.map((app) => {
|
||||
const { host, customDomains } = app.protectedAppMetadata ?? {};
|
||||
const domain = customDomains?.[0]?.domain ?? host;
|
||||
return (
|
||||
!!domain && (
|
||||
<div key={app.id} className={styles.app}>
|
||||
<div className={styles.status} />
|
||||
<Link className={styles.hostName} to={getTo(`/applications/${app.id}`)}>
|
||||
{domain}
|
||||
</Link>
|
||||
<CopyToClipboard value={domain} variant="icon" />
|
||||
<OpenExternalLink link={`https://${domain}`} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProtectedAppCreationForm;
|
|
@ -1,4 +1,4 @@
|
|||
import { Theme, type Application, type Resource } from '@logto/schemas';
|
||||
import { ApplicationType, Theme, type Application, type Resource } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback, useContext, useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
@ -26,8 +26,8 @@ import useTheme from '@/hooks/use-theme';
|
|||
import useWindowResize from '@/hooks/use-window-resize';
|
||||
|
||||
import CreateApiForm from '../ApiResources/components/CreateForm';
|
||||
import ProtectedAppModal from '../Applications/components/ProtectedAppModal';
|
||||
|
||||
import ProtectedAppCreationForm from './ProtectedAppCreationForm';
|
||||
import styles from './index.module.scss';
|
||||
|
||||
const icons = {
|
||||
|
@ -111,12 +111,6 @@ function GetStarted() {
|
|||
<div className={styles.title}>
|
||||
{t(`get_started.develop.title${isCloud ? '_cloud' : ''}`)}
|
||||
</div>
|
||||
{isCloud && (
|
||||
<>
|
||||
<ProtectedAppCreationForm />
|
||||
<div className={styles.subtitle}>{t('get_started.develop.subtitle_cloud')}</div>
|
||||
</>
|
||||
)}
|
||||
<GuideCardGroup
|
||||
ref={containerRef}
|
||||
hasCardBorder
|
||||
|
@ -124,11 +118,21 @@ function GetStarted() {
|
|||
guides={featuredAppGuides}
|
||||
onClickGuide={onClickAppGuide}
|
||||
/>
|
||||
{selectedGuide?.target !== 'API' && showCreateAppForm && (
|
||||
<ApplicationCreation
|
||||
defaultCreateType={selectedGuide?.target}
|
||||
defaultCreateFrameworkName={selectedGuide?.name}
|
||||
onCompleted={onAppCreationCompleted}
|
||||
{selectedGuide?.metadata.target !== 'API' &&
|
||||
selectedGuide?.metadata.target !== ApplicationType.Protected &&
|
||||
showCreateAppForm && (
|
||||
<ApplicationCreation
|
||||
defaultCreateType={selectedGuide?.metadata.target}
|
||||
defaultCreateFrameworkName={selectedGuide?.metadata.name}
|
||||
onCompleted={onAppCreationCompleted}
|
||||
/>
|
||||
)}
|
||||
{selectedGuide?.metadata.target === ApplicationType.Protected && showCreateAppForm && (
|
||||
<ProtectedAppModal
|
||||
onClose={() => {
|
||||
setShowCreateAppForm(false);
|
||||
setSelectedGuide(undefined);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<TextLink to="/applications/create">{t('get_started.view_all')}</TextLink>
|
||||
|
|
|
@ -18,11 +18,11 @@ export const applicationTypeI18nKey = Object.freeze({
|
|||
* plus the "featured" category.
|
||||
*/
|
||||
export const allAppGuideCategories = Object.freeze([
|
||||
'Protected',
|
||||
'featured',
|
||||
'Traditional',
|
||||
'SPA',
|
||||
'Native',
|
||||
'Protected',
|
||||
'MachineToMachine',
|
||||
thirdPartyAppCategory,
|
||||
] as const);
|
||||
|
|
Loading…
Add table
Reference in a new issue