|
@@ -0,0 +1,50 @@
|
|
|
|
|
+import re
|
|
|
|
|
+
|
|
|
|
|
+path = r"d:\radionica3d\src\pages\Admin.vue"
|
|
|
|
|
+with open(path, 'r', encoding='utf-8') as f:
|
|
|
|
|
+ content = f.read()
|
|
|
|
|
+
|
|
|
|
|
+# Define the pattern to find the portfolio section
|
|
|
|
|
+# We'll use a broad pattern to find the div with the portfolio tab
|
|
|
|
|
+pattern = re.compile(r'(<!-- PORTFOLIO -->\s+<div v-else-if="activeTab === \'portfolio\'".*?</div>\s+</div>)', re.DOTALL)
|
|
|
|
|
+
|
|
|
|
|
+portfolio_replacement = """<!-- PORTFOLIO -->
|
|
|
|
|
+ <div v-else-if="activeTab === 'portfolio'" class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
|
|
|
|
|
+ <div v-for="pi in portfolioItems" :key="pi.id" class="group relative aspect-square bg-card/40 border border-border/50 rounded-2xl overflow-hidden hover:border-primary/30 transition-all">
|
|
|
|
|
+ <img :src="`http://localhost:8000/${pi.file_path}`" class="w-full h-full object-cover" />
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Status Overlay -->
|
|
|
|
|
+ <div class="absolute top-2 left-2 flex gap-1">
|
|
|
|
|
+ <span :class="`px-2 py-0.5 rounded-full text-[8px] font-bold uppercase ${pi.is_public ? 'bg-emerald-500 text-white shadow-glow' : 'bg-black/40 text-white/40'}`">
|
|
|
|
|
+ {{ pi.is_public ? 'Public' : 'Private' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span v-if="!pi.allow_portfolio" class="px-2 py-0.5 rounded-full text-[8px] font-bold uppercase bg-rose-500 text-white">
|
|
|
|
|
+ No Consent
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex flex-col items-center justify-center p-4 gap-3">
|
|
|
|
|
+ <div class="flex items-center gap-2">
|
|
|
|
|
+ <button @click="handleTogglePhotoPublic(pi.id, pi.is_public, pi.allow_portfolio)"
|
|
|
|
|
+ :class="`p-2 rounded-xl transition-all ${pi.is_public ? 'bg-emerald-500 text-white' : 'bg-white/10 text-white hover:bg-white/20'}`"
|
|
|
|
|
+ :title="pi.is_public ? t('admin.actions.makePrivate') : t('admin.actions.makePublic')">
|
|
|
|
|
+ <Eye v-if="pi.is_public" class="w-4 h-4" /><EyeOff v-else class="w-4 h-4" />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <a :href="`http://localhost:8000/${pi.file_path}`" target="_blank" class="p-2 bg-white/10 text-white hover:bg-white/20 rounded-xl transition-all">
|
|
|
|
|
+ <ExternalLink class="w-4 h-4" />
|
|
|
|
|
+ </a>
|
|
|
|
|
+ <button @click="handleDeletePhoto(pi.id)" class="p-2 bg-rose-500/20 text-rose-500 hover:bg-rose-500 hover:text-white rounded-xl transition-all">
|
|
|
|
|
+ <Trash2 class="w-4 h-4" />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <p v-if="pi.material_name" class="text-[9px] font-bold text-primary uppercase mt-1">{{ pi.material_name }}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>"""
|
|
|
|
|
+
|
|
|
|
|
+new_content = pattern.sub(portfolio_replacement, content)
|
|
|
|
|
+
|
|
|
|
|
+with open(path, 'w', encoding='utf-8') as f:
|
|
|
|
|
+ f.write(new_content)
|
|
|
|
|
+
|
|
|
|
|
+print("Replacement successful")
|