| 1 |
import { __, sprintf } from '@wordpress/i18n' |
| 2 |
import type { DemoPlan, DemoSnippet } from './types' |
| 3 |
|
| 4 |
/** |
| 5 |
* The starter prompts the real agent offers, by their chip labels. The demo |
| 6 |
* never sends one — they are here so the page reads as the agent's own. |
| 7 |
*/ |
| 8 |
export const DEMO_EXAMPLES: readonly string[] = [ |
| 9 |
__('Replace a plugin with snippets', 'code-snippets'), |
| 10 |
__('Speed up my site', 'code-snippets'), |
| 11 |
__('Add a feature', 'code-snippets'), |
| 12 |
__('Fix a problem', 'code-snippets'), |
| 13 |
__('Customize appearance', 'code-snippets') |
| 14 |
] |
| 15 |
|
| 16 |
export const DEMO_PROMPT = __('Add a dismissible welcome banner to the top of my site.', 'code-snippets') |
| 17 |
|
| 18 |
export const DEMO_PLAN_REPLY = __('Here is what I would build. Two snippets keep the markup and the styling separate, so you can restyle the banner later without touching the PHP.', 'code-snippets') |
| 19 |
|
| 20 |
export const DEMO_PLAN: DemoPlan = { |
| 21 |
title: __('Dismissible welcome banner', 'code-snippets'), |
| 22 |
summary: DEMO_PLAN_REPLY, |
| 23 |
parts: [ |
| 24 |
{ |
| 25 |
language: 'php', |
| 26 |
name: __('Welcome banner', 'code-snippets'), |
| 27 |
description: __('Prints the banner at the top of every front-end page and remembers when a visitor dismisses it.', 'code-snippets') |
| 28 |
}, |
| 29 |
{ |
| 30 |
language: 'css', |
| 31 |
name: __('Welcome banner styles', 'code-snippets'), |
| 32 |
description: __('Styles the banner bar, its message, and the dismiss button.', 'code-snippets') |
| 33 |
} |
| 34 |
] |
| 35 |
} |
| 36 |
|
| 37 |
/** |
| 38 |
* Fallback used when the site has no name set, so the refinement still reads as |
| 39 |
* a sentence rather than trailing off into an empty quotation. |
| 40 |
*/ |
| 41 |
const FALLBACK_SITE_NAME = __('our site', 'code-snippets') |
| 42 |
|
| 43 |
export const getSiteName = (): string => { |
| 44 |
const siteName = window.CODE_SNIPPETS_MANAGE?.aiDemo?.siteName.trim() |
| 45 |
return undefined === siteName || '' === siteName ? FALLBACK_SITE_NAME : siteName |
| 46 |
} |
| 47 |
|
| 48 |
export const getRefinementPrompt = (siteName: string): string => |
| 49 |
sprintf( |
| 50 |
/* translators: %s: name of the current site. */ |
| 51 |
__('Make the banner say “Welcome to %s” and give it our brand colours.', 'code-snippets'), |
| 52 |
siteName |
| 53 |
) |
| 54 |
|
| 55 |
export const DEMO_REFINEMENT_REPLY = __('Done — the banner now greets visitors by name and uses a warmer gradient.', 'code-snippets') |
| 56 |
|
| 57 |
/** |
| 58 |
* Escape a value for embedding inside a single-quoted PHP string literal. |
| 59 |
*/ |
| 60 |
const escapePhpString = (value: string): string => |
| 61 |
value.replace(/\\/g, '\\\\').replace(/'/g, "\\'") |
| 62 |
|
| 63 |
const bannerPhp = (greeting: string) => `add_action( 'wp_body_open', function () { |
| 64 |
if ( is_admin() || isset( $_COOKIE['cs_welcome_banner_dismissed'] ) ) { |
| 65 |
return; |
| 66 |
} |
| 67 |
|
| 68 |
printf( |
| 69 |
'<div class="cs-welcome-banner" role="status"> |
| 70 |
<p class="cs-welcome-banner__message">%s</p> |
| 71 |
<button type="button" class="cs-welcome-banner__dismiss" aria-label="%s">×</button> |
| 72 |
</div>', |
| 73 |
esc_html( '${escapePhpString(greeting)}' ), |
| 74 |
esc_attr__( 'Dismiss this message', 'default' ) |
| 75 |
); |
| 76 |
} ); |
| 77 |
|
| 78 |
add_action( 'wp_footer', function () { |
| 79 |
?> |
| 80 |
<script> |
| 81 |
document.querySelector( '.cs-welcome-banner__dismiss' )?.addEventListener( 'click', function () { |
| 82 |
document.cookie = 'cs_welcome_banner_dismissed=1; path=/; max-age=2592000'; |
| 83 |
this.closest( '.cs-welcome-banner' ).remove(); |
| 84 |
} ); |
| 85 |
</script> |
| 86 |
<?php |
| 87 |
} );` |
| 88 |
|
| 89 |
const BANNER_CSS_PLAIN = `.cs-welcome-banner { |
| 90 |
display: flex; |
| 91 |
align-items: center; |
| 92 |
justify-content: center; |
| 93 |
gap: 1rem; |
| 94 |
padding-block: 0.75rem; |
| 95 |
padding-inline: 1.5rem; |
| 96 |
background: #2271b1; |
| 97 |
color: #fff; |
| 98 |
font-size: 0.95rem; |
| 99 |
} |
| 100 |
|
| 101 |
.cs-welcome-banner__message { |
| 102 |
margin: 0; |
| 103 |
} |
| 104 |
|
| 105 |
.cs-welcome-banner__dismiss { |
| 106 |
background: none; |
| 107 |
border: 0; |
| 108 |
color: inherit; |
| 109 |
cursor: pointer; |
| 110 |
font-size: 1.25rem; |
| 111 |
line-height: 1; |
| 112 |
padding: 0; |
| 113 |
}` |
| 114 |
|
| 115 |
const BANNER_CSS_REFINED = `.cs-welcome-banner { |
| 116 |
display: flex; |
| 117 |
align-items: center; |
| 118 |
justify-content: center; |
| 119 |
gap: 1rem; |
| 120 |
padding-block: 0.9rem; |
| 121 |
padding-inline: 1.5rem; |
| 122 |
background: linear-gradient(90deg, #1d3c78 0%, #2271b1 55%, #3fa8d4 100%); |
| 123 |
color: #fff; |
| 124 |
font-size: 1rem; |
| 125 |
letter-spacing: 0.01em; |
| 126 |
text-align: center; |
| 127 |
} |
| 128 |
|
| 129 |
.cs-welcome-banner__message { |
| 130 |
margin: 0; |
| 131 |
font-weight: 600; |
| 132 |
} |
| 133 |
|
| 134 |
.cs-welcome-banner__dismiss { |
| 135 |
background: none; |
| 136 |
border: 0; |
| 137 |
color: inherit; |
| 138 |
cursor: pointer; |
| 139 |
font-size: 1.4rem; |
| 140 |
line-height: 1; |
| 141 |
padding: 0; |
| 142 |
opacity: 0.8; |
| 143 |
transition: opacity 0.15s ease; |
| 144 |
} |
| 145 |
|
| 146 |
.cs-welcome-banner__dismiss:hover { |
| 147 |
opacity: 1; |
| 148 |
}` |
| 149 |
|
| 150 |
const snippetDesc = (summary: string): string => |
| 151 |
sprintf( |
| 152 |
/* translators: %s: description of what the snippet does. */ |
| 153 |
__('%s Created by the Code Snippets AI Agent demo, and left inactive so you can review it before switching it on.', 'code-snippets'), |
| 154 |
summary |
| 155 |
) |
| 156 |
|
| 157 |
export const getDraftSnippets = (): DemoSnippet[] => [ |
| 158 |
{ |
| 159 |
key: 'banner-php', |
| 160 |
name: __('Welcome banner', 'code-snippets'), |
| 161 |
desc: snippetDesc(__('Shows a dismissible welcome banner at the top of the site.', 'code-snippets')), |
| 162 |
language: 'php', |
| 163 |
code: bannerPhp(__('Welcome!', 'code-snippets')) |
| 164 |
}, |
| 165 |
{ |
| 166 |
key: 'banner-css', |
| 167 |
name: __('Welcome banner styles', 'code-snippets'), |
| 168 |
desc: snippetDesc(__('Styles the welcome banner.', 'code-snippets')), |
| 169 |
language: 'css', |
| 170 |
code: BANNER_CSS_PLAIN |
| 171 |
} |
| 172 |
] |
| 173 |
|
| 174 |
export const getRefinedSnippets = (siteName: string): DemoSnippet[] => { |
| 175 |
const greeting = sprintf( |
| 176 |
/* translators: %s: name of the current site. */ |
| 177 |
__('Welcome to %s', 'code-snippets'), |
| 178 |
siteName |
| 179 |
) |
| 180 |
|
| 181 |
return [ |
| 182 |
{ |
| 183 |
...getDraftSnippets()[0], |
| 184 |
code: bannerPhp(greeting) |
| 185 |
}, |
| 186 |
{ |
| 187 |
...getDraftSnippets()[1], |
| 188 |
code: BANNER_CSS_REFINED |
| 189 |
} |
| 190 |
] |
| 191 |
} |
| 192 |
|