@qobo/banner 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @qobo/banner
2
+
3
+ Shared banner component for all Qobo-generated projects. Displays "Made with ❤️ by qobo.dev" with visibility controlled by the backend.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @qobo/banner
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```jsx
14
+ import { QoboBanner } from '@qobo/banner';
15
+
16
+ export default function App() {
17
+ return (
18
+ <>
19
+ <QoboBanner />
20
+ {/* Rest of your app */}
21
+ </>
22
+ );
23
+ }
24
+ ```
25
+
26
+ ## Features
27
+
28
+ - **Consistent UI**: Same banner styling across all Qobo projects
29
+ - **Backend controlled**: Visibility managed via `/api/show-banner` endpoint
30
+ - **API Key integrated**: Automatically uses `VITE_API_KEY` from environment
31
+ - **Error resilient**: Defaults to visible if API fails
32
+ - **Layout shift prevention**: Initializes as visible before API response
33
+ - **Responsive**: Works on all screen sizes
34
+
35
+ ## Environment Variables
36
+
37
+ Required in your `.env` file:
38
+
39
+ ```
40
+ VITE_API_BASE_URL=https://api.qobo.dev
41
+ VITE_API_KEY=your_api_key_here
42
+ ```
43
+
44
+ ## License
45
+
46
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const Y=require("react");var H={exports:{}},I={};/**
2
+ * @license React
3
+ * react-jsx-runtime.production.min.js
4
+ *
5
+ * Copyright (c) Facebook, Inc. and its affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */var Se;function cr(){if(Se)return I;Se=1;var j=Y,E=Symbol.for("react.element"),F=Symbol.for("react.fragment"),g=Object.prototype.hasOwnProperty,k=j.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,T={key:!0,ref:!0,__self:!0,__source:!0};function _(h,f,m){var c,y={},w=null,W=null;m!==void 0&&(w=""+m),f.key!==void 0&&(w=""+f.key),f.ref!==void 0&&(W=f.ref);for(c in f)g.call(f,c)&&!T.hasOwnProperty(c)&&(y[c]=f[c]);if(h&&h.defaultProps)for(c in f=h.defaultProps,f)y[c]===void 0&&(y[c]=f[c]);return{$$typeof:E,type:h,key:w,ref:W,props:y,_owner:k.current}}return I.Fragment=F,I.jsx=_,I.jsxs=_,I}var $={};/**
10
+ * @license React
11
+ * react-jsx-runtime.development.js
12
+ *
13
+ * Copyright (c) Facebook, Inc. and its affiliates.
14
+ *
15
+ * This source code is licensed under the MIT license found in the
16
+ * LICENSE file in the root directory of this source tree.
17
+ */var Pe;function dr(){return Pe||(Pe=1,process.env.NODE_ENV!=="production"&&function(){var j=Y,E=Symbol.for("react.element"),F=Symbol.for("react.portal"),g=Symbol.for("react.fragment"),k=Symbol.for("react.strict_mode"),T=Symbol.for("react.profiler"),_=Symbol.for("react.provider"),h=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),c=Symbol.for("react.suspense_list"),y=Symbol.for("react.memo"),w=Symbol.for("react.lazy"),W=Symbol.for("react.offscreen"),Z=Symbol.iterator,xe="@@iterator";function Ce(e){if(e===null||typeof e!="object")return null;var r=Z&&e[Z]||e[xe];return typeof r=="function"?r:null}var O=j.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function d(e){{for(var r=arguments.length,t=new Array(r>1?r-1:0),n=1;n<r;n++)t[n-1]=arguments[n];je("error",e,t)}}function je(e,r,t){{var n=O.ReactDebugCurrentFrame,i=n.getStackAddendum();i!==""&&(r+="%s",t=t.concat([i]));var u=t.map(function(o){return String(o)});u.unshift("Warning: "+r),Function.prototype.apply.call(console[e],console,u)}}var Fe=!1,ke=!1,Ae=!1,De=!1,Ie=!1,ee;ee=Symbol.for("react.module.reference");function $e(e){return!!(typeof e=="string"||typeof e=="function"||e===g||e===T||Ie||e===k||e===m||e===c||De||e===W||Fe||ke||Ae||typeof e=="object"&&e!==null&&(e.$$typeof===w||e.$$typeof===y||e.$$typeof===_||e.$$typeof===h||e.$$typeof===f||e.$$typeof===ee||e.getModuleId!==void 0))}function Ye(e,r,t){var n=e.displayName;if(n)return n;var i=r.displayName||r.name||"";return i!==""?t+"("+i+")":t}function re(e){return e.displayName||"Context"}function R(e){if(e==null)return null;if(typeof e.tag=="number"&&d("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case g:return"Fragment";case F:return"Portal";case T:return"Profiler";case k:return"StrictMode";case m:return"Suspense";case c:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case h:var r=e;return re(r)+".Consumer";case _:var t=e;return re(t._context)+".Provider";case f:return Ye(e,e.render,"ForwardRef");case y:var n=e.displayName||null;return n!==null?n:R(e.type)||"Memo";case w:{var i=e,u=i._payload,o=i._init;try{return R(o(u))}catch{return null}}}return null}var S=Object.assign,A=0,te,ne,ae,oe,ie,ue,se;function le(){}le.__reactDisabledLog=!0;function We(){{if(A===0){te=console.log,ne=console.info,ae=console.warn,oe=console.error,ie=console.group,ue=console.groupCollapsed,se=console.groupEnd;var e={configurable:!0,enumerable:!0,value:le,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}A++}}function Be(){{if(A--,A===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:S({},e,{value:te}),info:S({},e,{value:ne}),warn:S({},e,{value:ae}),error:S({},e,{value:oe}),group:S({},e,{value:ie}),groupCollapsed:S({},e,{value:ue}),groupEnd:S({},e,{value:se})})}A<0&&d("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var U=O.ReactCurrentDispatcher,N;function B(e,r,t){{if(N===void 0)try{throw Error()}catch(i){var n=i.stack.trim().match(/\n( *(at )?)/);N=n&&n[1]||""}return`
18
+ `+N+e}}var K=!1,V;{var Ve=typeof WeakMap=="function"?WeakMap:Map;V=new Ve}function fe(e,r){if(!e||K)return"";{var t=V.get(e);if(t!==void 0)return t}var n;K=!0;var i=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var u;u=U.current,U.current=null,We();try{if(r){var o=function(){throw Error()};if(Object.defineProperty(o.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(o,[])}catch(p){n=p}Reflect.construct(e,[],o)}else{try{o.call()}catch(p){n=p}e.call(o.prototype)}}else{try{throw Error()}catch(p){n=p}e()}}catch(p){if(p&&n&&typeof p.stack=="string"){for(var a=p.stack.split(`
19
+ `),v=n.stack.split(`
20
+ `),s=a.length-1,l=v.length-1;s>=1&&l>=0&&a[s]!==v[l];)l--;for(;s>=1&&l>=0;s--,l--)if(a[s]!==v[l]){if(s!==1||l!==1)do if(s--,l--,l<0||a[s]!==v[l]){var b=`
21
+ `+a[s].replace(" at new "," at ");return e.displayName&&b.includes("<anonymous>")&&(b=b.replace("<anonymous>",e.displayName)),typeof e=="function"&&V.set(e,b),b}while(s>=1&&l>=0);break}}}finally{K=!1,U.current=u,Be(),Error.prepareStackTrace=i}var C=e?e.displayName||e.name:"",P=C?B(C):"";return typeof e=="function"&&V.set(e,P),P}function Le(e,r,t){return fe(e,!1)}function Me(e){var r=e.prototype;return!!(r&&r.isReactComponent)}function L(e,r,t){if(e==null)return"";if(typeof e=="function")return fe(e,Me(e));if(typeof e=="string")return B(e);switch(e){case m:return B("Suspense");case c:return B("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case f:return Le(e.render);case y:return L(e.type,r,t);case w:{var n=e,i=n._payload,u=n._init;try{return L(u(i),r,t)}catch{}}}return""}var D=Object.prototype.hasOwnProperty,ce={},de=O.ReactDebugCurrentFrame;function M(e){if(e){var r=e._owner,t=L(e.type,e._source,r?r.type:null);de.setExtraStackFrame(t)}else de.setExtraStackFrame(null)}function Ue(e,r,t,n,i){{var u=Function.call.bind(D);for(var o in e)if(u(e,o)){var a=void 0;try{if(typeof e[o]!="function"){var v=Error((n||"React class")+": "+t+" type `"+o+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[o]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw v.name="Invariant Violation",v}a=e[o](r,o,n,t,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(s){a=s}a&&!(a instanceof Error)&&(M(i),d("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",n||"React class",t,o,typeof a),M(null)),a instanceof Error&&!(a.message in ce)&&(ce[a.message]=!0,M(i),d("Failed %s type: %s",t,a.message),M(null))}}}var Ne=Array.isArray;function q(e){return Ne(e)}function Ke(e){{var r=typeof Symbol=="function"&&Symbol.toStringTag,t=r&&e[Symbol.toStringTag]||e.constructor.name||"Object";return t}}function qe(e){try{return ve(e),!1}catch{return!0}}function ve(e){return""+e}function pe(e){if(qe(e))return d("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",Ke(e)),ve(e)}var be=O.ReactCurrentOwner,Je={key:!0,ref:!0,__self:!0,__source:!0},ge,he;function Ge(e){if(D.call(e,"ref")){var r=Object.getOwnPropertyDescriptor(e,"ref").get;if(r&&r.isReactWarning)return!1}return e.ref!==void 0}function ze(e){if(D.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return e.key!==void 0}function Qe(e,r){typeof e.ref=="string"&&be.current}function Xe(e,r){{var t=function(){ge||(ge=!0,d("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"key",{get:t,configurable:!0})}}function He(e,r){{var t=function(){he||(he=!0,d("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"ref",{get:t,configurable:!0})}}var Ze=function(e,r,t,n,i,u,o){var a={$$typeof:E,type:e,key:r,ref:t,props:o,_owner:u};return a._store={},Object.defineProperty(a._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(a,"_self",{configurable:!1,enumerable:!1,writable:!1,value:n}),Object.defineProperty(a,"_source",{configurable:!1,enumerable:!1,writable:!1,value:i}),Object.freeze&&(Object.freeze(a.props),Object.freeze(a)),a};function er(e,r,t,n,i){{var u,o={},a=null,v=null;t!==void 0&&(pe(t),a=""+t),ze(r)&&(pe(r.key),a=""+r.key),Ge(r)&&(v=r.ref,Qe(r,i));for(u in r)D.call(r,u)&&!Je.hasOwnProperty(u)&&(o[u]=r[u]);if(e&&e.defaultProps){var s=e.defaultProps;for(u in s)o[u]===void 0&&(o[u]=s[u])}if(a||v){var l=typeof e=="function"?e.displayName||e.name||"Unknown":e;a&&Xe(o,l),v&&He(o,l)}return Ze(e,a,v,i,n,be.current,o)}}var J=O.ReactCurrentOwner,ye=O.ReactDebugCurrentFrame;function x(e){if(e){var r=e._owner,t=L(e.type,e._source,r?r.type:null);ye.setExtraStackFrame(t)}else ye.setExtraStackFrame(null)}var G;G=!1;function z(e){return typeof e=="object"&&e!==null&&e.$$typeof===E}function Ee(){{if(J.current){var e=R(J.current.type);if(e)return`
22
+
23
+ Check the render method of \``+e+"`."}return""}}function rr(e){return""}var _e={};function tr(e){{var r=Ee();if(!r){var t=typeof e=="string"?e:e.displayName||e.name;t&&(r=`
24
+
25
+ Check the top-level render call using <`+t+">.")}return r}}function me(e,r){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var t=tr(r);if(_e[t])return;_e[t]=!0;var n="";e&&e._owner&&e._owner!==J.current&&(n=" It was passed a child from "+R(e._owner.type)+"."),x(e),d('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',t,n),x(null)}}function Re(e,r){{if(typeof e!="object")return;if(q(e))for(var t=0;t<e.length;t++){var n=e[t];z(n)&&me(n,r)}else if(z(e))e._store&&(e._store.validated=!0);else if(e){var i=Ce(e);if(typeof i=="function"&&i!==e.entries)for(var u=i.call(e),o;!(o=u.next()).done;)z(o.value)&&me(o.value,r)}}}function nr(e){{var r=e.type;if(r==null||typeof r=="string")return;var t;if(typeof r=="function")t=r.propTypes;else if(typeof r=="object"&&(r.$$typeof===f||r.$$typeof===y))t=r.propTypes;else return;if(t){var n=R(r);Ue(t,e.props,"prop",n,e)}else if(r.PropTypes!==void 0&&!G){G=!0;var i=R(r);d("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",i||"Unknown")}typeof r.getDefaultProps=="function"&&!r.getDefaultProps.isReactClassApproved&&d("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function ar(e){{for(var r=Object.keys(e.props),t=0;t<r.length;t++){var n=r[t];if(n!=="children"&&n!=="key"){x(e),d("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",n),x(null);break}}e.ref!==null&&(x(e),d("Invalid attribute `ref` supplied to `React.Fragment`."),x(null))}}var Te={};function we(e,r,t,n,i,u){{var o=$e(e);if(!o){var a="";(e===void 0||typeof e=="object"&&e!==null&&Object.keys(e).length===0)&&(a+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var v=rr();v?a+=v:a+=Ee();var s;e===null?s="null":q(e)?s="array":e!==void 0&&e.$$typeof===E?(s="<"+(R(e.type)||"Unknown")+" />",a=" Did you accidentally export a JSX literal instead of a component?"):s=typeof e,d("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",s,a)}var l=er(e,r,t,i,u);if(l==null)return l;if(o){var b=r.children;if(b!==void 0)if(n)if(q(b)){for(var C=0;C<b.length;C++)Re(b[C],e);Object.freeze&&Object.freeze(b)}else d("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else Re(b,e)}if(D.call(r,"key")){var P=R(e),p=Object.keys(r).filter(function(fr){return fr!=="key"}),Q=p.length>0?"{key: someKey, "+p.join(": ..., ")+": ...}":"{key: someKey}";if(!Te[P+Q]){var lr=p.length>0?"{"+p.join(": ..., ")+": ...}":"{}";d(`A props object containing a "key" prop is being spread into JSX:
26
+ let props = %s;
27
+ <%s {...props} />
28
+ React keys must be passed directly to JSX without using spread:
29
+ let props = %s;
30
+ <%s key={someKey} {...props} />`,Q,P,lr,P),Te[P+Q]=!0}}return e===g?ar(l):nr(l),l}}function or(e,r,t){return we(e,r,t,!0)}function ir(e,r,t){return we(e,r,t,!1)}var ur=ir,sr=or;$.Fragment=g,$.jsx=ur,$.jsxs=sr}()),$}process.env.NODE_ENV==="production"?H.exports=cr():H.exports=dr();var X=H.exports;function Oe(){const[j,E]=Y.useState(!0),[F,g]=Y.useState(!0);return Y.useEffect(()=>{(async()=>{var T;try{const h="https://api.qobo.dev";console.warn("[QoboBanner] VITE_API_KEY not set, defaulting to visible"),g(!1);return}catch(_){console.warn("[QoboBanner] Error fetching banner visibility, defaulting to visible:",_.message),E(!0)}finally{g(!1)}})()},[]),!j&&!F?null:X.jsxs("div",{className:"w-full bg-gradient-to-r from-cyan-400 to-blue-500 text-white py-2 px-4 text-center text-sm font-medium shadow-md",style:{backgroundColor:"#06B6D4",color:"#FFFFFF",padding:"0.5rem 1rem",textAlign:"center",fontSize:"0.875rem",fontWeight:"500",boxShadow:"0 2px 4px rgba(0, 0, 0, 0.1)",transition:"all 0.3s ease"},children:["Made with"," ",X.jsx("span",{style:{color:"#FF1744",display:"inline-block",margin:"0 0.25rem"},children:"❤️"})," ","by"," ",X.jsx("a",{href:"https://qobo.dev",target:"_blank",rel:"noopener noreferrer",style:{color:"#FFFFFF",textDecoration:"underline",fontWeight:"600",cursor:"pointer"},className:"hover:text-cyan-100 transition-colors",children:"qobo.dev"})]})}exports.QoboBanner=Oe;exports.default=Oe;
package/dist/index.js ADDED
@@ -0,0 +1,697 @@
1
+ import Se, { useState as we, useEffect as cr } from "react";
2
+ var Q = { exports: {} }, I = {};
3
+ /**
4
+ * @license React
5
+ * react-jsx-runtime.production.min.js
6
+ *
7
+ * Copyright (c) Facebook, Inc. and its affiliates.
8
+ *
9
+ * This source code is licensed under the MIT license found in the
10
+ * LICENSE file in the root directory of this source tree.
11
+ */
12
+ var Pe;
13
+ function dr() {
14
+ if (Pe) return I;
15
+ Pe = 1;
16
+ var j = Se, E = Symbol.for("react.element"), F = Symbol.for("react.fragment"), h = Object.prototype.hasOwnProperty, k = j.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, T = { key: !0, ref: !0, __self: !0, __source: !0 };
17
+ function _(g, f, m) {
18
+ var c, y = {}, w = null, Y = null;
19
+ m !== void 0 && (w = "" + m), f.key !== void 0 && (w = "" + f.key), f.ref !== void 0 && (Y = f.ref);
20
+ for (c in f) h.call(f, c) && !T.hasOwnProperty(c) && (y[c] = f[c]);
21
+ if (g && g.defaultProps) for (c in f = g.defaultProps, f) y[c] === void 0 && (y[c] = f[c]);
22
+ return { $$typeof: E, type: g, key: w, ref: Y, props: y, _owner: k.current };
23
+ }
24
+ return I.Fragment = F, I.jsx = _, I.jsxs = _, I;
25
+ }
26
+ var $ = {};
27
+ /**
28
+ * @license React
29
+ * react-jsx-runtime.development.js
30
+ *
31
+ * Copyright (c) Facebook, Inc. and its affiliates.
32
+ *
33
+ * This source code is licensed under the MIT license found in the
34
+ * LICENSE file in the root directory of this source tree.
35
+ */
36
+ var Oe;
37
+ function vr() {
38
+ return Oe || (Oe = 1, process.env.NODE_ENV !== "production" && function() {
39
+ var j = Se, E = Symbol.for("react.element"), F = Symbol.for("react.portal"), h = Symbol.for("react.fragment"), k = Symbol.for("react.strict_mode"), T = Symbol.for("react.profiler"), _ = Symbol.for("react.provider"), g = Symbol.for("react.context"), f = Symbol.for("react.forward_ref"), m = Symbol.for("react.suspense"), c = Symbol.for("react.suspense_list"), y = Symbol.for("react.memo"), w = Symbol.for("react.lazy"), Y = Symbol.for("react.offscreen"), H = Symbol.iterator, xe = "@@iterator";
40
+ function Ce(e) {
41
+ if (e === null || typeof e != "object")
42
+ return null;
43
+ var r = H && e[H] || e[xe];
44
+ return typeof r == "function" ? r : null;
45
+ }
46
+ var S = j.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
47
+ function d(e) {
48
+ {
49
+ for (var r = arguments.length, t = new Array(r > 1 ? r - 1 : 0), n = 1; n < r; n++)
50
+ t[n - 1] = arguments[n];
51
+ je("error", e, t);
52
+ }
53
+ }
54
+ function je(e, r, t) {
55
+ {
56
+ var n = S.ReactDebugCurrentFrame, i = n.getStackAddendum();
57
+ i !== "" && (r += "%s", t = t.concat([i]));
58
+ var s = t.map(function(o) {
59
+ return String(o);
60
+ });
61
+ s.unshift("Warning: " + r), Function.prototype.apply.call(console[e], console, s);
62
+ }
63
+ }
64
+ var Fe = !1, ke = !1, Ae = !1, De = !1, Ie = !1, Z;
65
+ Z = Symbol.for("react.module.reference");
66
+ function $e(e) {
67
+ return !!(typeof e == "string" || typeof e == "function" || e === h || e === T || Ie || e === k || e === m || e === c || De || e === Y || Fe || ke || Ae || typeof e == "object" && e !== null && (e.$$typeof === w || e.$$typeof === y || e.$$typeof === _ || e.$$typeof === g || e.$$typeof === f || // This needs to include all possible module reference object
68
+ // types supported by any Flight configuration anywhere since
69
+ // we don't know which Flight build this will end up being used
70
+ // with.
71
+ e.$$typeof === Z || e.getModuleId !== void 0));
72
+ }
73
+ function Ye(e, r, t) {
74
+ var n = e.displayName;
75
+ if (n)
76
+ return n;
77
+ var i = r.displayName || r.name || "";
78
+ return i !== "" ? t + "(" + i + ")" : t;
79
+ }
80
+ function ee(e) {
81
+ return e.displayName || "Context";
82
+ }
83
+ function R(e) {
84
+ if (e == null)
85
+ return null;
86
+ if (typeof e.tag == "number" && d("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), typeof e == "function")
87
+ return e.displayName || e.name || null;
88
+ if (typeof e == "string")
89
+ return e;
90
+ switch (e) {
91
+ case h:
92
+ return "Fragment";
93
+ case F:
94
+ return "Portal";
95
+ case T:
96
+ return "Profiler";
97
+ case k:
98
+ return "StrictMode";
99
+ case m:
100
+ return "Suspense";
101
+ case c:
102
+ return "SuspenseList";
103
+ }
104
+ if (typeof e == "object")
105
+ switch (e.$$typeof) {
106
+ case g:
107
+ var r = e;
108
+ return ee(r) + ".Consumer";
109
+ case _:
110
+ var t = e;
111
+ return ee(t._context) + ".Provider";
112
+ case f:
113
+ return Ye(e, e.render, "ForwardRef");
114
+ case y:
115
+ var n = e.displayName || null;
116
+ return n !== null ? n : R(e.type) || "Memo";
117
+ case w: {
118
+ var i = e, s = i._payload, o = i._init;
119
+ try {
120
+ return R(o(s));
121
+ } catch {
122
+ return null;
123
+ }
124
+ }
125
+ }
126
+ return null;
127
+ }
128
+ var P = Object.assign, A = 0, re, te, ne, ae, oe, ie, se;
129
+ function ue() {
130
+ }
131
+ ue.__reactDisabledLog = !0;
132
+ function We() {
133
+ {
134
+ if (A === 0) {
135
+ re = console.log, te = console.info, ne = console.warn, ae = console.error, oe = console.group, ie = console.groupCollapsed, se = console.groupEnd;
136
+ var e = {
137
+ configurable: !0,
138
+ enumerable: !0,
139
+ value: ue,
140
+ writable: !0
141
+ };
142
+ Object.defineProperties(console, {
143
+ info: e,
144
+ log: e,
145
+ warn: e,
146
+ error: e,
147
+ group: e,
148
+ groupCollapsed: e,
149
+ groupEnd: e
150
+ });
151
+ }
152
+ A++;
153
+ }
154
+ }
155
+ function Ve() {
156
+ {
157
+ if (A--, A === 0) {
158
+ var e = {
159
+ configurable: !0,
160
+ enumerable: !0,
161
+ writable: !0
162
+ };
163
+ Object.defineProperties(console, {
164
+ log: P({}, e, {
165
+ value: re
166
+ }),
167
+ info: P({}, e, {
168
+ value: te
169
+ }),
170
+ warn: P({}, e, {
171
+ value: ne
172
+ }),
173
+ error: P({}, e, {
174
+ value: ae
175
+ }),
176
+ group: P({}, e, {
177
+ value: oe
178
+ }),
179
+ groupCollapsed: P({}, e, {
180
+ value: ie
181
+ }),
182
+ groupEnd: P({}, e, {
183
+ value: se
184
+ })
185
+ });
186
+ }
187
+ A < 0 && d("disabledDepth fell below zero. This is a bug in React. Please file an issue.");
188
+ }
189
+ }
190
+ var M = S.ReactCurrentDispatcher, U;
191
+ function W(e, r, t) {
192
+ {
193
+ if (U === void 0)
194
+ try {
195
+ throw Error();
196
+ } catch (i) {
197
+ var n = i.stack.trim().match(/\n( *(at )?)/);
198
+ U = n && n[1] || "";
199
+ }
200
+ return `
201
+ ` + U + e;
202
+ }
203
+ }
204
+ var N = !1, V;
205
+ {
206
+ var Be = typeof WeakMap == "function" ? WeakMap : Map;
207
+ V = new Be();
208
+ }
209
+ function le(e, r) {
210
+ if (!e || N)
211
+ return "";
212
+ {
213
+ var t = V.get(e);
214
+ if (t !== void 0)
215
+ return t;
216
+ }
217
+ var n;
218
+ N = !0;
219
+ var i = Error.prepareStackTrace;
220
+ Error.prepareStackTrace = void 0;
221
+ var s;
222
+ s = M.current, M.current = null, We();
223
+ try {
224
+ if (r) {
225
+ var o = function() {
226
+ throw Error();
227
+ };
228
+ if (Object.defineProperty(o.prototype, "props", {
229
+ set: function() {
230
+ throw Error();
231
+ }
232
+ }), typeof Reflect == "object" && Reflect.construct) {
233
+ try {
234
+ Reflect.construct(o, []);
235
+ } catch (p) {
236
+ n = p;
237
+ }
238
+ Reflect.construct(e, [], o);
239
+ } else {
240
+ try {
241
+ o.call();
242
+ } catch (p) {
243
+ n = p;
244
+ }
245
+ e.call(o.prototype);
246
+ }
247
+ } else {
248
+ try {
249
+ throw Error();
250
+ } catch (p) {
251
+ n = p;
252
+ }
253
+ e();
254
+ }
255
+ } catch (p) {
256
+ if (p && n && typeof p.stack == "string") {
257
+ for (var a = p.stack.split(`
258
+ `), v = n.stack.split(`
259
+ `), u = a.length - 1, l = v.length - 1; u >= 1 && l >= 0 && a[u] !== v[l]; )
260
+ l--;
261
+ for (; u >= 1 && l >= 0; u--, l--)
262
+ if (a[u] !== v[l]) {
263
+ if (u !== 1 || l !== 1)
264
+ do
265
+ if (u--, l--, l < 0 || a[u] !== v[l]) {
266
+ var b = `
267
+ ` + a[u].replace(" at new ", " at ");
268
+ return e.displayName && b.includes("<anonymous>") && (b = b.replace("<anonymous>", e.displayName)), typeof e == "function" && V.set(e, b), b;
269
+ }
270
+ while (u >= 1 && l >= 0);
271
+ break;
272
+ }
273
+ }
274
+ } finally {
275
+ N = !1, M.current = s, Ve(), Error.prepareStackTrace = i;
276
+ }
277
+ var C = e ? e.displayName || e.name : "", O = C ? W(C) : "";
278
+ return typeof e == "function" && V.set(e, O), O;
279
+ }
280
+ function Le(e, r, t) {
281
+ return le(e, !1);
282
+ }
283
+ function Me(e) {
284
+ var r = e.prototype;
285
+ return !!(r && r.isReactComponent);
286
+ }
287
+ function B(e, r, t) {
288
+ if (e == null)
289
+ return "";
290
+ if (typeof e == "function")
291
+ return le(e, Me(e));
292
+ if (typeof e == "string")
293
+ return W(e);
294
+ switch (e) {
295
+ case m:
296
+ return W("Suspense");
297
+ case c:
298
+ return W("SuspenseList");
299
+ }
300
+ if (typeof e == "object")
301
+ switch (e.$$typeof) {
302
+ case f:
303
+ return Le(e.render);
304
+ case y:
305
+ return B(e.type, r, t);
306
+ case w: {
307
+ var n = e, i = n._payload, s = n._init;
308
+ try {
309
+ return B(s(i), r, t);
310
+ } catch {
311
+ }
312
+ }
313
+ }
314
+ return "";
315
+ }
316
+ var D = Object.prototype.hasOwnProperty, fe = {}, ce = S.ReactDebugCurrentFrame;
317
+ function L(e) {
318
+ if (e) {
319
+ var r = e._owner, t = B(e.type, e._source, r ? r.type : null);
320
+ ce.setExtraStackFrame(t);
321
+ } else
322
+ ce.setExtraStackFrame(null);
323
+ }
324
+ function Ue(e, r, t, n, i) {
325
+ {
326
+ var s = Function.call.bind(D);
327
+ for (var o in e)
328
+ if (s(e, o)) {
329
+ var a = void 0;
330
+ try {
331
+ if (typeof e[o] != "function") {
332
+ var v = Error((n || "React class") + ": " + t + " type `" + o + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof e[o] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
333
+ throw v.name = "Invariant Violation", v;
334
+ }
335
+ a = e[o](r, o, n, t, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
336
+ } catch (u) {
337
+ a = u;
338
+ }
339
+ a && !(a instanceof Error) && (L(i), d("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", n || "React class", t, o, typeof a), L(null)), a instanceof Error && !(a.message in fe) && (fe[a.message] = !0, L(i), d("Failed %s type: %s", t, a.message), L(null));
340
+ }
341
+ }
342
+ }
343
+ var Ne = Array.isArray;
344
+ function K(e) {
345
+ return Ne(e);
346
+ }
347
+ function Ke(e) {
348
+ {
349
+ var r = typeof Symbol == "function" && Symbol.toStringTag, t = r && e[Symbol.toStringTag] || e.constructor.name || "Object";
350
+ return t;
351
+ }
352
+ }
353
+ function qe(e) {
354
+ try {
355
+ return de(e), !1;
356
+ } catch {
357
+ return !0;
358
+ }
359
+ }
360
+ function de(e) {
361
+ return "" + e;
362
+ }
363
+ function ve(e) {
364
+ if (qe(e))
365
+ return d("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", Ke(e)), de(e);
366
+ }
367
+ var pe = S.ReactCurrentOwner, Je = {
368
+ key: !0,
369
+ ref: !0,
370
+ __self: !0,
371
+ __source: !0
372
+ }, be, he;
373
+ function Ge(e) {
374
+ if (D.call(e, "ref")) {
375
+ var r = Object.getOwnPropertyDescriptor(e, "ref").get;
376
+ if (r && r.isReactWarning)
377
+ return !1;
378
+ }
379
+ return e.ref !== void 0;
380
+ }
381
+ function ze(e) {
382
+ if (D.call(e, "key")) {
383
+ var r = Object.getOwnPropertyDescriptor(e, "key").get;
384
+ if (r && r.isReactWarning)
385
+ return !1;
386
+ }
387
+ return e.key !== void 0;
388
+ }
389
+ function Xe(e, r) {
390
+ typeof e.ref == "string" && pe.current;
391
+ }
392
+ function Qe(e, r) {
393
+ {
394
+ var t = function() {
395
+ be || (be = !0, d("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", r));
396
+ };
397
+ t.isReactWarning = !0, Object.defineProperty(e, "key", {
398
+ get: t,
399
+ configurable: !0
400
+ });
401
+ }
402
+ }
403
+ function He(e, r) {
404
+ {
405
+ var t = function() {
406
+ he || (he = !0, d("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", r));
407
+ };
408
+ t.isReactWarning = !0, Object.defineProperty(e, "ref", {
409
+ get: t,
410
+ configurable: !0
411
+ });
412
+ }
413
+ }
414
+ var Ze = function(e, r, t, n, i, s, o) {
415
+ var a = {
416
+ // This tag allows us to uniquely identify this as a React Element
417
+ $$typeof: E,
418
+ // Built-in properties that belong on the element
419
+ type: e,
420
+ key: r,
421
+ ref: t,
422
+ props: o,
423
+ // Record the component responsible for creating this element.
424
+ _owner: s
425
+ };
426
+ return a._store = {}, Object.defineProperty(a._store, "validated", {
427
+ configurable: !1,
428
+ enumerable: !1,
429
+ writable: !0,
430
+ value: !1
431
+ }), Object.defineProperty(a, "_self", {
432
+ configurable: !1,
433
+ enumerable: !1,
434
+ writable: !1,
435
+ value: n
436
+ }), Object.defineProperty(a, "_source", {
437
+ configurable: !1,
438
+ enumerable: !1,
439
+ writable: !1,
440
+ value: i
441
+ }), Object.freeze && (Object.freeze(a.props), Object.freeze(a)), a;
442
+ };
443
+ function er(e, r, t, n, i) {
444
+ {
445
+ var s, o = {}, a = null, v = null;
446
+ t !== void 0 && (ve(t), a = "" + t), ze(r) && (ve(r.key), a = "" + r.key), Ge(r) && (v = r.ref, Xe(r, i));
447
+ for (s in r)
448
+ D.call(r, s) && !Je.hasOwnProperty(s) && (o[s] = r[s]);
449
+ if (e && e.defaultProps) {
450
+ var u = e.defaultProps;
451
+ for (s in u)
452
+ o[s] === void 0 && (o[s] = u[s]);
453
+ }
454
+ if (a || v) {
455
+ var l = typeof e == "function" ? e.displayName || e.name || "Unknown" : e;
456
+ a && Qe(o, l), v && He(o, l);
457
+ }
458
+ return Ze(e, a, v, i, n, pe.current, o);
459
+ }
460
+ }
461
+ var q = S.ReactCurrentOwner, ge = S.ReactDebugCurrentFrame;
462
+ function x(e) {
463
+ if (e) {
464
+ var r = e._owner, t = B(e.type, e._source, r ? r.type : null);
465
+ ge.setExtraStackFrame(t);
466
+ } else
467
+ ge.setExtraStackFrame(null);
468
+ }
469
+ var J;
470
+ J = !1;
471
+ function G(e) {
472
+ return typeof e == "object" && e !== null && e.$$typeof === E;
473
+ }
474
+ function ye() {
475
+ {
476
+ if (q.current) {
477
+ var e = R(q.current.type);
478
+ if (e)
479
+ return `
480
+
481
+ Check the render method of \`` + e + "`.";
482
+ }
483
+ return "";
484
+ }
485
+ }
486
+ function rr(e) {
487
+ return "";
488
+ }
489
+ var Ee = {};
490
+ function tr(e) {
491
+ {
492
+ var r = ye();
493
+ if (!r) {
494
+ var t = typeof e == "string" ? e : e.displayName || e.name;
495
+ t && (r = `
496
+
497
+ Check the top-level render call using <` + t + ">.");
498
+ }
499
+ return r;
500
+ }
501
+ }
502
+ function _e(e, r) {
503
+ {
504
+ if (!e._store || e._store.validated || e.key != null)
505
+ return;
506
+ e._store.validated = !0;
507
+ var t = tr(r);
508
+ if (Ee[t])
509
+ return;
510
+ Ee[t] = !0;
511
+ var n = "";
512
+ e && e._owner && e._owner !== q.current && (n = " It was passed a child from " + R(e._owner.type) + "."), x(e), d('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', t, n), x(null);
513
+ }
514
+ }
515
+ function me(e, r) {
516
+ {
517
+ if (typeof e != "object")
518
+ return;
519
+ if (K(e))
520
+ for (var t = 0; t < e.length; t++) {
521
+ var n = e[t];
522
+ G(n) && _e(n, r);
523
+ }
524
+ else if (G(e))
525
+ e._store && (e._store.validated = !0);
526
+ else if (e) {
527
+ var i = Ce(e);
528
+ if (typeof i == "function" && i !== e.entries)
529
+ for (var s = i.call(e), o; !(o = s.next()).done; )
530
+ G(o.value) && _e(o.value, r);
531
+ }
532
+ }
533
+ }
534
+ function nr(e) {
535
+ {
536
+ var r = e.type;
537
+ if (r == null || typeof r == "string")
538
+ return;
539
+ var t;
540
+ if (typeof r == "function")
541
+ t = r.propTypes;
542
+ else if (typeof r == "object" && (r.$$typeof === f || // Note: Memo only checks outer props here.
543
+ // Inner props are checked in the reconciler.
544
+ r.$$typeof === y))
545
+ t = r.propTypes;
546
+ else
547
+ return;
548
+ if (t) {
549
+ var n = R(r);
550
+ Ue(t, e.props, "prop", n, e);
551
+ } else if (r.PropTypes !== void 0 && !J) {
552
+ J = !0;
553
+ var i = R(r);
554
+ d("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", i || "Unknown");
555
+ }
556
+ typeof r.getDefaultProps == "function" && !r.getDefaultProps.isReactClassApproved && d("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
557
+ }
558
+ }
559
+ function ar(e) {
560
+ {
561
+ for (var r = Object.keys(e.props), t = 0; t < r.length; t++) {
562
+ var n = r[t];
563
+ if (n !== "children" && n !== "key") {
564
+ x(e), d("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", n), x(null);
565
+ break;
566
+ }
567
+ }
568
+ e.ref !== null && (x(e), d("Invalid attribute `ref` supplied to `React.Fragment`."), x(null));
569
+ }
570
+ }
571
+ var Re = {};
572
+ function Te(e, r, t, n, i, s) {
573
+ {
574
+ var o = $e(e);
575
+ if (!o) {
576
+ var a = "";
577
+ (e === void 0 || typeof e == "object" && e !== null && Object.keys(e).length === 0) && (a += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");
578
+ var v = rr();
579
+ v ? a += v : a += ye();
580
+ var u;
581
+ e === null ? u = "null" : K(e) ? u = "array" : e !== void 0 && e.$$typeof === E ? (u = "<" + (R(e.type) || "Unknown") + " />", a = " Did you accidentally export a JSX literal instead of a component?") : u = typeof e, d("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", u, a);
582
+ }
583
+ var l = er(e, r, t, i, s);
584
+ if (l == null)
585
+ return l;
586
+ if (o) {
587
+ var b = r.children;
588
+ if (b !== void 0)
589
+ if (n)
590
+ if (K(b)) {
591
+ for (var C = 0; C < b.length; C++)
592
+ me(b[C], e);
593
+ Object.freeze && Object.freeze(b);
594
+ } else
595
+ d("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
596
+ else
597
+ me(b, e);
598
+ }
599
+ if (D.call(r, "key")) {
600
+ var O = R(e), p = Object.keys(r).filter(function(fr) {
601
+ return fr !== "key";
602
+ }), z = p.length > 0 ? "{key: someKey, " + p.join(": ..., ") + ": ...}" : "{key: someKey}";
603
+ if (!Re[O + z]) {
604
+ var lr = p.length > 0 ? "{" + p.join(": ..., ") + ": ...}" : "{}";
605
+ d(`A props object containing a "key" prop is being spread into JSX:
606
+ let props = %s;
607
+ <%s {...props} />
608
+ React keys must be passed directly to JSX without using spread:
609
+ let props = %s;
610
+ <%s key={someKey} {...props} />`, z, O, lr, O), Re[O + z] = !0;
611
+ }
612
+ }
613
+ return e === h ? ar(l) : nr(l), l;
614
+ }
615
+ }
616
+ function or(e, r, t) {
617
+ return Te(e, r, t, !0);
618
+ }
619
+ function ir(e, r, t) {
620
+ return Te(e, r, t, !1);
621
+ }
622
+ var sr = ir, ur = or;
623
+ $.Fragment = h, $.jsx = sr, $.jsxs = ur;
624
+ }()), $;
625
+ }
626
+ process.env.NODE_ENV === "production" ? Q.exports = dr() : Q.exports = vr();
627
+ var X = Q.exports;
628
+ function br() {
629
+ const [j, E] = we(!0), [F, h] = we(!0);
630
+ return cr(() => {
631
+ (async () => {
632
+ var T;
633
+ try {
634
+ const g = "https://api.qobo.dev";
635
+ console.warn("[QoboBanner] VITE_API_KEY not set, defaulting to visible"), h(!1);
636
+ return;
637
+ } catch (_) {
638
+ console.warn("[QoboBanner] Error fetching banner visibility, defaulting to visible:", _.message), E(!0);
639
+ } finally {
640
+ h(!1);
641
+ }
642
+ })();
643
+ }, []), !j && !F ? null : /* @__PURE__ */ X.jsxs(
644
+ "div",
645
+ {
646
+ className: "w-full bg-gradient-to-r from-cyan-400 to-blue-500 text-white py-2 px-4 text-center text-sm font-medium shadow-md",
647
+ style: {
648
+ backgroundColor: "#06B6D4",
649
+ color: "#FFFFFF",
650
+ padding: "0.5rem 1rem",
651
+ textAlign: "center",
652
+ fontSize: "0.875rem",
653
+ fontWeight: "500",
654
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
655
+ transition: "all 0.3s ease"
656
+ },
657
+ children: [
658
+ "Made with",
659
+ " ",
660
+ /* @__PURE__ */ X.jsx(
661
+ "span",
662
+ {
663
+ style: {
664
+ color: "#FF1744",
665
+ display: "inline-block",
666
+ margin: "0 0.25rem"
667
+ },
668
+ children: "❤️"
669
+ }
670
+ ),
671
+ " ",
672
+ "by",
673
+ " ",
674
+ /* @__PURE__ */ X.jsx(
675
+ "a",
676
+ {
677
+ href: "https://qobo.dev",
678
+ target: "_blank",
679
+ rel: "noopener noreferrer",
680
+ style: {
681
+ color: "#FFFFFF",
682
+ textDecoration: "underline",
683
+ fontWeight: "600",
684
+ cursor: "pointer"
685
+ },
686
+ className: "hover:text-cyan-100 transition-colors",
687
+ children: "qobo.dev"
688
+ }
689
+ )
690
+ ]
691
+ }
692
+ );
693
+ }
694
+ export {
695
+ br as QoboBanner,
696
+ br as default
697
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@qobo/banner",
3
+ "version": "1.0.0",
4
+ "description": "Shared Qobo banner component for all generated projects",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "require": "./dist/index.cjs"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "src"
16
+ ],
17
+ "scripts": {
18
+ "build": "vite build",
19
+ "dev": "vite",
20
+ "prepublish": "npm run build"
21
+ },
22
+ "dependencies": {
23
+ "react": "^18.2.0"
24
+ },
25
+ "peerDependencies": {
26
+ "react": "^18.2.0",
27
+ "react-dom": "^18.2.0"
28
+ },
29
+ "devDependencies": {
30
+ "@vitejs/plugin-react": "^4.2.1",
31
+ "vite": "^5.2.0"
32
+ },
33
+ "keywords": [
34
+ "qobo",
35
+ "banner",
36
+ "component",
37
+ "react"
38
+ ],
39
+ "author": "Qobo",
40
+ "license": "MIT",
41
+ "publishConfig": {
42
+ "access": "public",
43
+ "registry": "https://registry.npmjs.org/"
44
+ }
45
+ }
@@ -0,0 +1,111 @@
1
+ import React, { useState, useEffect } from 'react';
2
+
3
+ /**
4
+ * QoboBanner Component - Shared across all Qobo-generated projects
5
+ *
6
+ * Displays a banner with "Made with ❤️ by qobo.dev"
7
+ * Visibility controlled by backend API endpoint /api/show-banner
8
+ *
9
+ * The component automatically:
10
+ * - Fetches banner visibility on mount
11
+ * - Shows banner if showBanner: "true", hides if "false"
12
+ * - Defaults to visible on error
13
+ * - Links to https://qobo.dev in a new tab
14
+ * - Has consistent styling across all projects
15
+ */
16
+ export function QoboBanner() {
17
+ const [isVisible, setIsVisible] = useState(true); // Default to visible to prevent layout shift
18
+ const [isLoading, setIsLoading] = useState(true);
19
+
20
+ useEffect(() => {
21
+ // Fetch banner visibility from backend
22
+ const fetchBannerVisibility = async () => {
23
+ try {
24
+ // Get API key from environment
25
+ const API_KEY = import.meta.env.VITE_API_KEY;
26
+ const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'https://api.qobo.dev';
27
+
28
+ if (!API_KEY) {
29
+ console.warn('[QoboBanner] VITE_API_KEY not set, defaulting to visible');
30
+ setIsLoading(false);
31
+ return;
32
+ }
33
+
34
+ const response = await fetch(`${API_BASE_URL}/api/show-banner`, {
35
+ method: 'GET',
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ 'X-API-Key': API_KEY,
39
+ },
40
+ });
41
+
42
+ if (!response.ok) {
43
+ console.warn(`[QoboBanner] Failed to fetch banner visibility (${response.status}), defaulting to visible`);
44
+ setIsLoading(false);
45
+ return;
46
+ }
47
+
48
+ const data = await response.json();
49
+ const showBanner = data.data?.showBanner === 'true';
50
+ setIsVisible(showBanner);
51
+ console.log(`[QoboBanner] Banner visibility: ${showBanner}`);
52
+ } catch (error) {
53
+ console.warn('[QoboBanner] Error fetching banner visibility, defaulting to visible:', error.message);
54
+ // Default to visible on error
55
+ setIsVisible(true);
56
+ } finally {
57
+ setIsLoading(false);
58
+ }
59
+ };
60
+
61
+ fetchBannerVisibility();
62
+ }, []);
63
+
64
+ if (!isVisible && !isLoading) {
65
+ return null;
66
+ }
67
+
68
+ return (
69
+ <div
70
+ className="w-full bg-gradient-to-r from-cyan-400 to-blue-500 text-white py-2 px-4 text-center text-sm font-medium shadow-md"
71
+ style={{
72
+ backgroundColor: '#06B6D4',
73
+ color: '#FFFFFF',
74
+ padding: '0.5rem 1rem',
75
+ textAlign: 'center',
76
+ fontSize: '0.875rem',
77
+ fontWeight: '500',
78
+ boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
79
+ transition: 'all 0.3s ease',
80
+ }}
81
+ >
82
+ Made with{' '}
83
+ <span
84
+ style={{
85
+ color: '#FF1744',
86
+ display: 'inline-block',
87
+ margin: '0 0.25rem',
88
+ }}
89
+ >
90
+ ❤️
91
+ </span>{' '}
92
+ by{' '}
93
+ <a
94
+ href="https://qobo.dev"
95
+ target="_blank"
96
+ rel="noopener noreferrer"
97
+ style={{
98
+ color: '#FFFFFF',
99
+ textDecoration: 'underline',
100
+ fontWeight: '600',
101
+ cursor: 'pointer',
102
+ }}
103
+ className="hover:text-cyan-100 transition-colors"
104
+ >
105
+ qobo.dev
106
+ </a>
107
+ </div>
108
+ );
109
+ }
110
+
111
+ export default QoboBanner;
package/src/index.js ADDED
@@ -0,0 +1 @@
1
+ export { QoboBanner, default } from './QoboBanner.jsx';