Add configurable CC cost for banner vehicle PDF/description view
- Add cc_per_banner_view setting to system_settings (default 0.1 CC) - Update car detail page to use dynamic CC value from settings - Add CC per Banner View field in admin settings page - Replace hardcoded 0.1 CC with configurable value 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ interface SystemSettings {
|
||||
cc_per_view: number;
|
||||
cc_signup_bonus: number;
|
||||
cars_per_cc: number;
|
||||
cc_per_banner_view: number;
|
||||
cache_ttl_hours: number;
|
||||
container_logistics_usd: number;
|
||||
shoring_cost_usd: number;
|
||||
@@ -56,6 +57,7 @@ export default function SettingsPage() {
|
||||
cc_per_view: 1,
|
||||
cc_signup_bonus: 3,
|
||||
cars_per_cc: 3,
|
||||
cc_per_banner_view: 0.1,
|
||||
cache_ttl_hours: 2,
|
||||
container_logistics_usd: 3600,
|
||||
shoring_cost_usd: 300,
|
||||
@@ -85,6 +87,7 @@ export default function SettingsPage() {
|
||||
cc_per_view: data.cc_per_view,
|
||||
cc_signup_bonus: data.cc_signup_bonus,
|
||||
cars_per_cc: data.cars_per_cc || 3,
|
||||
cc_per_banner_view: data.cc_per_banner_view ?? 0.1,
|
||||
cache_ttl_hours: data.cache_ttl_hours,
|
||||
container_logistics_usd: data.container_logistics_usd || 3600,
|
||||
shoring_cost_usd: data.shoring_cost_usd || 300,
|
||||
@@ -372,6 +375,22 @@ export default function SettingsPage() {
|
||||
/>
|
||||
<p className="mt-1 text-sm text-gray-500">Free CC for new users</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
CC per Banner View (PDF/Description)
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
max="10"
|
||||
step="0.1"
|
||||
value={formData.cc_per_banner_view}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, cc_per_banner_view: parseFloat(e.target.value) || 0.1 }))}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
|
||||
/>
|
||||
<p className="mt-1 text-sm text-gray-500">배너 차량 PDF/상세 정보 열람 비용 (기본값: 0.1 CC)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4 p-4 bg-blue-50 rounded-lg">
|
||||
|
||||
@@ -53,18 +53,20 @@ export default function CarDetailPage() {
|
||||
|
||||
// System settings
|
||||
const [showDealerCommentSetting, setShowDealerCommentSetting] = useState(true);
|
||||
const [ccPerBannerView, setCcPerBannerView] = useState(0.1);
|
||||
|
||||
useEffect(() => {
|
||||
if (params.id) {
|
||||
loadCar(Number(params.id));
|
||||
}
|
||||
// Fetch system settings for dealer comment visibility
|
||||
// Fetch system settings for dealer comment visibility and CC cost
|
||||
const fetchSettings = async () => {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/settings/`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
setShowDealerCommentSetting(data.show_dealer_comment ?? true);
|
||||
setCcPerBannerView(data.cc_per_banner_view ?? 0.1);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch settings:', error);
|
||||
@@ -172,7 +174,7 @@ export default function CarDetailPage() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ccBalance < 0.1) {
|
||||
if (ccBalance < ccPerBannerView) {
|
||||
alert(t.insufficientCC);
|
||||
return;
|
||||
}
|
||||
@@ -356,7 +358,7 @@ export default function CarDetailPage() {
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-lg font-bold">{t.promotedVehicle}</p>
|
||||
<p className="text-sm opacity-90">{t.promotedVehicleDesc}</p>
|
||||
<p className="text-sm opacity-90">{t.promotedVehicleDesc.replace('0.1', String(ccPerBannerView))}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -915,7 +917,7 @@ export default function CarDetailPage() {
|
||||
</ul>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<span className="text-2xl font-bold text-blue-600">0.1 CC</span>
|
||||
<span className="text-2xl font-bold text-blue-600">{ccPerBannerView} CC</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
@@ -927,7 +929,7 @@ export default function CarDetailPage() {
|
||||
? 'Login to Unlock'
|
||||
: purchasingPerformanceCheck
|
||||
? 'Purchasing...'
|
||||
: 'Pay 0.1 CC to Unlock'
|
||||
: `Pay ${ccPerBannerView} CC to Unlock`
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
@@ -959,7 +961,7 @@ export default function CarDetailPage() {
|
||||
</ul>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<span className="text-2xl font-bold text-blue-600">0.1 CC</span>
|
||||
<span className="text-2xl font-bold text-blue-600">{ccPerBannerView} CC</span>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
@@ -971,7 +973,7 @@ export default function CarDetailPage() {
|
||||
? 'Login to Unlock'
|
||||
: purchasingPerformanceCheck
|
||||
? 'Purchasing...'
|
||||
: 'Pay 0.1 CC to Unlock'
|
||||
: `Pay ${ccPerBannerView} CC to Unlock`
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user