fix: Login logo 401, link focus styles, payment/shipping active colors
## 1. Fix Logo 401 Error on Login ✅ **Issue:** Logo image returns 401 Unauthorized on login page **Root Cause:** `/store/settings` endpoint requires authentication **Solution:** Created public branding endpoint ```php // GET /woonoow/v1/store/branding (PUBLIC) public function get_branding() { return [ 'store_name' => get_option('blogname'), 'store_logo' => get_option('woonoow_store_logo'), 'store_icon' => get_option('woonoow_store_icon'), 'store_tagline' => get_option('woonoow_store_tagline'), ]; } ``` **Frontend:** Updated Login.tsx to use `/store/branding` instead **Result:** Logo loads without authentication ✅ --- ## 2. Override WordPress Link Focus Styles ✅ **Issue:** WordPress common.css applies focus/active styles to links **Solution:** Added CSS override ```css a:focus, a:active { outline: none !important; box-shadow: none !important; } ``` **Result:** Clean focus states, no WordPress interference --- ## 3. Active Color for Manual Payment Methods ✅ **Issue:** Manual payments use static gray icon, online payments use green/primary **Solution:** Applied same active color logic ```tsx <div className={`p-2 rounded-lg ${ gateway.enabled ? 'bg-green-500/20 text-green-500' : 'bg-primary/10 text-primary' }`}> <Banknote className="h-5 w-5" /> </div> ``` **Result:** - ✅ Enabled = Green background + green icon - ✅ Disabled = Primary background + primary icon - ✅ Consistent with online payments --- ## 4. Active Color for Shipping Icons ✅ **Issue:** Shipping icons always gray, no visual indicator of enabled state **Solution:** Applied active color to all shipping icons - Zone summary view - Desktop accordion view - Mobile accordion view ```tsx <div className={`p-2 rounded-lg ${ rate.enabled ? 'bg-green-500/20 text-green-500' : 'bg-primary/10 text-primary' }`}> <Truck className="h-4 w-4" /> </div> ``` **Result:** - ✅ Enabled shipping = Green icon - ✅ Disabled shipping = Primary icon - ✅ Consistent visual language across payments & shipping --- ## 5. Notification Strategy ✅ **Acknowledged:** Clean structure, ready for implementation --- ## Summary ✅ Public branding endpoint (no auth required) ✅ Logo loads on login page ✅ WordPress link focus styles overridden ✅ Manual payments have active colors ✅ Shipping methods have active colors ✅ Consistent visual language (green = active, primary = inactive) **Visual Consistency Achieved:** - Payments (manual & online) ✓ - Shipping methods ✓ - All use same color system ✓
This commit is contained in:
@@ -66,6 +66,13 @@
|
|||||||
* { @apply border-border; }
|
* { @apply border-border; }
|
||||||
body { @apply bg-background text-foreground; }
|
body { @apply bg-background text-foreground; }
|
||||||
h1, h2, h3, h4, h5, h6 { @apply text-foreground; }
|
h1, h2, h3, h4, h5, h6 { @apply text-foreground; }
|
||||||
|
|
||||||
|
/* Override WordPress common.css focus/active styles */
|
||||||
|
a:focus,
|
||||||
|
a:active {
|
||||||
|
outline: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Command palette input: remove native borders/shadows to match shadcn */
|
/* Command palette input: remove native borders/shadows to match shadcn */
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ export function Login() {
|
|||||||
});
|
});
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// Fetch branding
|
// Fetch branding (public endpoint - no auth required)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch((window.WNW_CONFIG?.restUrl || '') + '/store/settings')
|
fetch((window.WNW_CONFIG?.restUrl || '') + '/store/branding')
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
setBranding({
|
setBranding({
|
||||||
|
|||||||
@@ -302,11 +302,11 @@ export default function PaymentsPage() {
|
|||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{manualGateways.map((gateway: PaymentGateway) => (
|
{manualGateways.map((gateway: PaymentGateway) => (
|
||||||
<SortableGatewayItem key={gateway.id} gateway={gateway}>
|
<SortableGatewayItem key={gateway.id} gateway={gateway}>
|
||||||
<div className="border rounded-lg p-4">
|
<div className="border rounded-lg p-4 hover:border-primary/50 transition-colors">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="p-2 bg-muted rounded-lg">
|
<div className={`p-2 rounded-lg ${gateway.enabled ? 'bg-green-500/20 text-green-500' : 'bg-primary/10 text-primary'}`}>
|
||||||
<Banknote className="h-5 w-5 text-muted-foreground" />
|
<Banknote className="h-5 w-5" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 className="font-medium">{gateway.method_title || gateway.title}</h3>
|
<h3 className="font-medium">{gateway.method_title || gateway.title}</h3>
|
||||||
|
|||||||
@@ -342,7 +342,9 @@ export default function ShippingPage() {
|
|||||||
className="flex items-center justify-between gap-2 py-2 px-2 md:px-3 bg-muted/50 rounded-md"
|
className="flex items-center justify-between gap-2 py-2 px-2 md:px-3 bg-muted/50 rounded-md"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-1.5 md:gap-2 flex-1 min-w-0">
|
<div className="flex items-center gap-1.5 md:gap-2 flex-1 min-w-0">
|
||||||
<Truck className="h-3.5 w-3.5 md:h-4 md:w-4 text-muted-foreground flex-shrink-0" />
|
<div className={`p-1 rounded flex-shrink-0 ${rate.enabled ? 'bg-green-500/20 text-green-500' : 'bg-primary/10 text-primary'}`}>
|
||||||
|
<Truck className="h-3.5 w-3.5 md:h-4 md:w-4" />
|
||||||
|
</div>
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<span
|
<span
|
||||||
className="text-xs md:text-sm font-medium line-clamp-1"
|
className="text-xs md:text-sm font-medium line-clamp-1"
|
||||||
@@ -472,7 +474,9 @@ export default function ShippingPage() {
|
|||||||
<AccordionItem key={rate.id} value={String(rate.instance_id)} className="border rounded-lg mb-2">
|
<AccordionItem key={rate.id} value={String(rate.instance_id)} className="border rounded-lg mb-2">
|
||||||
<AccordionTrigger className="hover:no-underline px-4">
|
<AccordionTrigger className="hover:no-underline px-4">
|
||||||
<div className="flex items-center gap-3 flex-1">
|
<div className="flex items-center gap-3 flex-1">
|
||||||
<Truck className="h-4 w-4 text-muted-foreground" />
|
<div className={`p-2 rounded-lg ${rate.enabled ? 'bg-green-500/20 text-green-500' : 'bg-primary/10 text-primary'}`}>
|
||||||
|
<Truck className="h-4 w-4" />
|
||||||
|
</div>
|
||||||
<div className="flex-1 text-left">
|
<div className="flex-1 text-left">
|
||||||
<div className="font-medium" dangerouslySetInnerHTML={{ __html: rate.name }} />
|
<div className="font-medium" dangerouslySetInnerHTML={{ __html: rate.name }} />
|
||||||
<div className="flex items-center gap-2 text-sm text-muted-foreground mt-1">
|
<div className="flex items-center gap-2 text-sm text-muted-foreground mt-1">
|
||||||
@@ -684,7 +688,9 @@ export default function ShippingPage() {
|
|||||||
<AccordionItem key={rate.id} value={String(rate.instance_id)} className="border rounded-lg mb-2">
|
<AccordionItem key={rate.id} value={String(rate.instance_id)} className="border rounded-lg mb-2">
|
||||||
<AccordionTrigger className="hover:no-underline px-3 py-2">
|
<AccordionTrigger className="hover:no-underline px-3 py-2">
|
||||||
<div className="flex items-center gap-2 flex-1 min-w-0">
|
<div className="flex items-center gap-2 flex-1 min-w-0">
|
||||||
<Truck className="h-3.5 w-3.5 text-muted-foreground flex-shrink-0" />
|
<div className={`p-1.5 rounded-lg flex-shrink-0 ${rate.enabled ? 'bg-green-500/20 text-green-500' : 'bg-primary/10 text-primary'}`}>
|
||||||
|
<Truck className="h-3.5 w-3.5" />
|
||||||
|
</div>
|
||||||
<div className="flex-1 text-left min-w-0">
|
<div className="flex-1 text-left min-w-0">
|
||||||
<div className="font-medium text-sm line-clamp-1" dangerouslySetInnerHTML={{ __html: rate.name }} />
|
<div className="font-medium text-sm line-clamp-1" dangerouslySetInnerHTML={{ __html: rate.name }} />
|
||||||
<div className="flex items-center gap-2 text-xs text-muted-foreground mt-0.5">
|
<div className="flex items-center gap-2 text-xs text-muted-foreground mt-0.5">
|
||||||
|
|||||||
@@ -32,6 +32,15 @@ class StoreController extends WP_REST_Controller {
|
|||||||
* Register routes
|
* Register routes
|
||||||
*/
|
*/
|
||||||
public function register_routes() {
|
public function register_routes() {
|
||||||
|
// GET /woonoow/v1/store/branding (PUBLIC - for login page)
|
||||||
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/branding', [
|
||||||
|
[
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => [$this, 'get_branding'],
|
||||||
|
'permission_callback' => '__return_true', // Public endpoint
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
// GET /woonoow/v1/store/settings
|
// GET /woonoow/v1/store/settings
|
||||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/settings', [
|
register_rest_route($this->namespace, '/' . $this->rest_base . '/settings', [
|
||||||
[
|
[
|
||||||
@@ -78,6 +87,26 @@ class StoreController extends WP_REST_Controller {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get store branding (PUBLIC - for login page)
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request object
|
||||||
|
* @return WP_REST_Response Response object
|
||||||
|
*/
|
||||||
|
public function get_branding(WP_REST_Request $request) {
|
||||||
|
$branding = [
|
||||||
|
'store_name' => get_option('blogname', 'WooNooW'),
|
||||||
|
'store_logo' => get_option('woonoow_store_logo', ''),
|
||||||
|
'store_icon' => get_option('woonoow_store_icon', ''),
|
||||||
|
'store_tagline' => get_option('woonoow_store_tagline', ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = rest_ensure_response($branding);
|
||||||
|
$response->header('Cache-Control', 'max-age=300'); // Cache for 5 minutes
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get store settings
|
* Get store settings
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user