Explorar o código

브랜드사 회원가입

DESKTOP-T61HUSC\user hai 4 meses
pai
achega
5cc648161f

+ 39 - 46
assets/scss/default.scss

@@ -146,7 +146,7 @@
         border-radius: 15px;
         padding:20px;
         margin-top:25px;
-        background: #f8f8f8;
+        background: #f0f4ff;
         &.type2{
           flex-direction: column;
           align-items: flex-start;
@@ -376,8 +376,7 @@
               cursor: pointer;
               border-bottom: 1px solid #f0f0f0;
               transition: all 0.3s ease;
-              display: grid;
-              grid-template-columns: 80px 120px 1fr 2fr 100px 120px;
+              display: flex;
               gap: 15px;
               align-items: center;
               
@@ -391,10 +390,10 @@
                 border-bottom: none;
               }
               
-              > span, > div {
+              > span, > div, > h3 {
                 font-size: 0.9rem;
                 
-                &:nth-child(1) { // SEQ
+                &.list--seq { // SEQ
                   font-weight: 600;
                   color: #667eea;
                   text-align: center;
@@ -404,7 +403,7 @@
                   font-size: 0.8rem;
                 }
                 
-                &:nth-child(2) { // CATEGORY
+                &.list--circle {
                   background: linear-gradient(135deg, #667eea, #764ba2);
                   color: white;
                   padding: 6px 12px;
@@ -413,62 +412,56 @@
                   font-weight: 500;
                   text-align: center;
                   white-space: nowrap;
+                  
+                  // 마감  
+                  &.status--off {
+                    background: linear-gradient(135deg, #727c89 0%, #8ca6ce 100%);
+                    color: white;
+                    box-shadow: 0 2px 6px rgba(145, 168, 200, 0.3);
+                  }
                 }
                 
-                &:nth-child(3) { // NICK_NAME + NAME + COM
+                &.list--writer { // NICK_NAME + NAME + COM
                   color: #666;
+                  font-weight: 500;
                   font-size: 0.9rem;
-                  
-                  strong {
-                    color: #333;
-                    font-weight: 600;
-                  }
                 }
                 
-                &:nth-child(4) { // TITLE
+                &.list--title { // TITLE
                   color: #333;
-                  font-weight: 500;
+                  font-weight: 600;
                   line-height: 1.4;
                   overflow: hidden;
                   text-overflow: ellipsis;
+                  width: 70%;
                   white-space: nowrap;
                 }
                 
-                &:nth-child(5) { // STATUS
-                  text-align: center;
-                  
-                  &.status-waiting {
-                    color: #ffffff;
-                    background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%);
-                    padding: 4px 8px;
-                    border-radius: 10px;
-                    font-size: 0.8rem;
-                    font-weight: 600;
-                    box-shadow: 0 2px 6px rgba(255, 107, 107, 0.3);
-                  }
+                &.list--ml {
+                  margin-left: auto;
                   
-                  &.status-processing {
-                    color: #ffffff;
-                    background: linear-gradient(135deg, #4ecdc4 0%, #44a39f 100%);
-                    padding: 4px 8px;
-                    border-radius: 10px;
-                    font-size: 0.8rem;
-                    font-weight: 600;
-                    box-shadow: 0 2px 6px rgba(78, 205, 196, 0.3);
-                  }
-                  
-                  &.status-completed {
-                    color: #ffffff;
-                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-                    padding: 4px 8px;
-                    border-radius: 10px;
-                    font-size: 0.8rem;
-                    font-weight: 600;
-                    box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);
-                  }
+                }
+                &.status-waiting {
+                  color: #ffffff;
+                  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%);
+                  padding: 4px 8px;
+                  border-radius: 10px;
+                  font-size: 0.8rem;
+                  font-weight: 600;
+                  box-shadow: 0 2px 6px rgba(255, 107, 107, 0.3);
+                }
+                
+                &.status-completed {
+                  color: #ffffff;
+                  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+                  padding: 4px 8px;
+                  border-radius: 10px;
+                  font-size: 0.8rem;
+                  font-weight: 600;
+                  box-shadow: 0 2px 6px rgba(102, 126, 234, 0.3);
                 }
                 
-                &:nth-child(6) { // REGDATE
+                &.list--date { // REGDATE
                   color: #999;
                   font-size: 0.8rem;
                   text-align: right;

+ 1 - 3
assets/scss/mode-w-m.scss

@@ -5853,7 +5853,7 @@ z
     align-items: center;
     padding: 1.25rem 1.88rem;
     width: 100%;
-    background-color: #0B318B;
+    background-color: rgba(255, 255, 255, 0.1);
     height: 4.75rem;
     z-index: 100;
     .login--header--l{
@@ -5861,7 +5861,6 @@ z
       gap: 0.9375rem;
       align-items: center;
       .logo{        
-        height: 2rem;        
         color:#fff;        
       }
       p{
@@ -6030,7 +6029,6 @@ z
         .logo{
           background: none;
           font-size: 1.5625rem;
-          color: #0b318b;
           font-weight: 700;
           letter-spacing: -0.04688rem;
           pointer-events: none;

+ 362 - 137
assets/scss/style.scss

@@ -730,7 +730,7 @@
 }
 
 .custom-input.v-text-field {
-  flex: 0 0 auto;
+  // flex: 0 0 auto;
   width: 100%;
   min-height: 3.63rem;
   padding: 0;
@@ -3506,176 +3506,401 @@ p.success-txt {
   align-items: center;
   justify-content: center;
   width: 100%;
-  height: 100%;
-  padding: 3.63rem 0;
-  background: #F2F6FF;
-  &.type--join{
-    overflow-y: auto;
-    .login-box {
-      height: auto;
-      padding:45px 0px!important;
-      background: #fff;
+  height: 100vh;
+  min-height: 700px;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  overflow: hidden;
+  
+  &::after {
+    content: '';
+    position: absolute;
+    top: 20%;
+    right: 10%;
+    width: 300px;
+    height: 300px;
+    border-radius: 50%;
+    background: linear-gradient(45deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));
+    animation: pulse 4s infinite ease-in-out;
+    z-index: 1;
+  }
+  
+  @keyframes float {
+    0% { transform: translate(-50%, -50%) rotate(0deg); }
+    100% { transform: translate(-50%, -50%) rotate(360deg); }
+  }
+  
+  @keyframes pulse {
+    0%, 100% { transform: scale(1) rotate(0deg); opacity: 0.5; }
+    50% { transform: scale(1.1) rotate(180deg); opacity: 0.8; }
+  }
+  
+  overflow-y: auto;
+  .login-box {
+    height: auto;
+    box-shadow: 0 25px 50px rgba(0,0,0,0.15);
+    &.type--join{
+      padding: 45px 0px!important;
+      background-color: #fff;
+      width: 30%;
+      max-width: 1000px;
+      padding: 3rem!important;
+      .login-r{
+        height: 100%;
+        overflow-x: hidden;
+        overflow-y: auto;
+        padding: 0;
+        .login-btn-wrap{
+          margin-bottom: 0;
+        }
+      }
+    }
+  }
+
+  // 게이트 페이지 스타일
+  .login--gate {
+    display: flex;
+    width: 100%;
+    height: 100vh;
+    z-index: 10;
+    
+    .inf--gate,
+    .ven--gate {
+      flex: 1;
+      position: relative;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      transition: all 0.3s ease;
+      cursor: pointer;
+      overflow: hidden;
+      
+      &::before {
+        content: '';
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        background: rgba(0,0,0,0.3);
+        z-index: 1;
+        transition: all 0.3s ease;
+      }
+      
+      .btn--contents {
+        position: relative;
+        z-index: 2;
+        text-align: center;
+        color: white;
+        transform: translateY(20px);
+        opacity: 0.8;
+        transition: all 0.3s ease;
+        
+        h2 {
+          font-size: 3.5rem;
+          font-weight: 300;
+          margin-bottom: 2rem;
+          text-transform: uppercase;
+          letter-spacing: 0.2em;
+        }
+        
+        .loc--btn {
+          background: rgba(255,255,255,0.1);
+          backdrop-filter: blur(10px);
+          border: 2px solid rgba(255,255,255,0.3);
+          color: white;
+          padding: 15px 30px;
+          border-radius: 50px;
+          font-weight: 500;
+          letter-spacing: 0.1em;
+          transition: all 0.3s ease;
+          
+          &:hover {
+            background: rgba(255,255,255,0.2);
+            transform: translateY(-2px);
+            box-shadow: 0 10px 25px rgba(0,0,0,0.2);
+          }
+        }
+      }
+      
+      &.actv {
+        &::before {
+          background: rgba(0,0,0,0.1);
+        }
+        
+        .btn--contents {
+          transform: translateY(0);
+          opacity: 1;
+          
+          h2 {
+            transform: scale(1.1);
+          }
+        }
+      }
+    }
+    
+    .inf--gate {
+      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+    }
+    
+    .ven--gate {
+      background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
     }
   }
 
+  .login--cock {
+    width: 100%;
+    height: 100vh;
+    display: flex;
+    flex-direction: column;
+    z-index: 10;
+  }
+
+  .login--header {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    height: 80px;
+    background: rgba(255,255,255,0.1);
+    backdrop-filter: blur(20px);
+    border-bottom: 1px solid rgba(255,255,255,0.1);
+    display: flex;
+    align-items: center;
+    padding: 0 2rem;
+    z-index: 100;
+
+    .login--header--l {
+      .logo {
+        color: white;
+        font-size: 1.5rem;
+        font-weight: 700;
+        letter-spacing: 0.1em;
+      }
+    }
+  }
 
   .login-box {
     display: flex;
-    height: 43.63rem;    
+    width: 100%;
+    max-width: 1200px;
+    margin: auto;
+    border-radius: 20px;
+    overflow: hidden;
+    box-shadow: 0 25px 50px rgba(0,0,0,0.15);
+    backdrop-filter: blur(20px);
+    z-index: 10;
 
     .login-l {
-      flex-shrink: 0;
-      width: 39.94rem;
-      background: #064F9E url("../img/bg_login.svg") no-repeat center / 100%;
+      flex: 1;
+      background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%);
+      backdrop-filter: blur(20px);
+      border: 1px solid rgba(255,255,255,0.1);
       display: flex;
       align-items: center;
-      flex-direction: column;
       justify-content: center;
+      position: relative;
+      overflow: hidden;
 
       .login-l-center {
-        width: 15.63rem;
-        height: 13.13rem;
-        background: #fff;
-        display: flex;
-        align-items: center;
-        flex-direction: column;
-        justify-content: center;
+        position: relative;
+        z-index: 2;
+        text-align: center;
+        padding: 3rem;
+        background: rgba(255,255,255,0.1);
+        backdrop-filter: blur(10px);
+        border-radius: 15px;
+        border: 1px solid rgba(255,255,255,0.2);
 
         .logo {
-          font-size: 0;
+          color: white;
+          font-size: 2.5rem;
+          font-weight: 700;
+          letter-spacing: 0.1em;
           display: block;
-          height: 1.25rem;
-          width: 100%;
-          background: url("../img/logo_login.svg") no-repeat center / auto 100%;
         }
 
         p {
-          margin: 0.75rem 0 0;
-          text-align: center;
-          color: #333;
-          letter-spacing: -0.02rem;
-          font-size: 1.19rem;
-          line-height: 1.19rem;
+          color: rgba(255,255,255,0.8);
+          font-size: 1rem;
+          font-weight: 300;
+          letter-spacing: 0.05em;
         }
       }
     }
 
     .login-r {
-      width: 36.25rem;
-      background: #fff;
-      padding: 0 6.25rem;
+      flex: 1;
+      background: rgba(255,255,255,0.95);
+      backdrop-filter: blur(20px);
+      padding: 3rem;
       display: flex;
       flex-direction: column;
       justify-content: center;
+      position: relative;
 
+      .custom-input.v-text-field .v-input__control .v-field__field .v-field__input{
+        border: none;
+        background-color: transparent;
+      }
 
       .mk--title{
-        font-size:35px;
+        font-size: 35px;
         font-weight: 900;
-        margin-bottom:45px;
+        margin-bottom: 45px;
+        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+        -webkit-background-clip: text;
+        background-clip: text;
+        -webkit-text-fill-color: transparent;
       }
       
       .tit-login {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        margin-bottom: 1.88rem;
+        margin-bottom: 2rem;
+        text-align: center;
 
-        > span{
-          font-size: 14px;
-          font-weight: bold;
-          i{
-            color:red;
-            font-style: normal;
-            margin-right: 3px;
-            position: relative;
-            top:2px;
-          }
-        }
         strong {
-          color: #333;
-          font-size: 1.38rem;
+          color: #2d3748;
+          font-size: 2rem;
           font-weight: 700;
-          line-height: 1.38rem;
-          display: block;
-        }
-
-        .lang-set {
-          width: 6.00rem;
-
-          .custom-select {
-            width: 6.00rem;
-          }
+          background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+          -webkit-background-clip: text;
+          background-clip: text;
+          -webkit-text-fill-color: transparent;
         }
       }
 
       .login-input-wrap {
-        width: 100%;
+        margin-bottom: 1.5rem;
 
         .txt-field-box {
-          margin-bottom: 0.63rem;
-          &:first-of-type {
-            margin-bottom: 0.63rem;
+          margin-bottom: 1rem;
+          position: relative;
+          display: flex;
+          
+          .custom-input {
+            .v-input__control {
+              .v-field {
+                background: rgba(255,255,255,0.8);
+                backdrop-filter: blur(10px);
+                border: 2px solid rgba(102, 126, 234, 0.2);
+                border-radius: 12px;
+                transition: all 0.3s ease;
+                
+                &:hover {
+                  border-color: rgba(102, 126, 234, 0.4);
+                  background: rgba(255,255,255,0.9);
+                }
+                
+                &.v-field--focused {
+                  border-color: #667eea;
+                  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
+                }
+              }
+            }
+          }
+          
+          .ico {
+            position: absolute;
+            left: 15px;
+            top: 50%;
+            transform: translateY(-50%);
+            width: 20px;
+            height: 20px;
+            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+            border-radius: 50%;
+            z-index: 10;
+          }
+          
+          .ico-eye {
+            position: absolute;
+            right: 15px;
+            top: 50%;
+            transform: translateY(-50%);
+            cursor: pointer;
+            color: #667eea;
+            font-size: 1.2rem;
+            z-index: 10;
+            transition: all 0.3s ease;
+            
+            &:hover {
+              color: #764ba2;
+              transform: translateY(-50%) scale(1.1);
+            }
           }
         }
       }
 
-      .login-radio {
-        margin-top: 1.25rem;
-      }
-
-      .login-otp {
-        display: flex;
-        gap: 0.63rem;
-        margin-top: 1.25rem;
-
-        .txt-field-box {
+      .login-btn-wrap {
+        margin-bottom: 1.5rem;
+        
+        .custom-btn {
           width: 100%;
+          height: 50px;
+          background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+          border: none;
+          border-radius: 12px;
+          color: white;
+          font-size: 1.1rem;
+          font-weight: 600;
+          letter-spacing: 0.05em;
+          box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
+          transition: all 0.3s ease;
+          
+          &:hover {
+            transform: translateY(-2px);
+            box-shadow: 0 12px 35px rgba(102, 126, 234, 0.4);
+          }
+          
+          &:active {
+            transform: translateY(0);
+          }
         }
-
-        .btn-blue-bor {
-          width: 8.31rem;
-          height: 3.63rem;
-          flex-shrink: 0;
-        }
-      }
-
-      .login-btn-wrap {
-        margin-top: 1.88rem;
       }
-
-      .login-chk {
-        margin: 1.25rem 0 0;
-      }
-
-      .login-find {
+      
+      .join--btn--wrap {
         display: flex;
-        align-items: center;
-        margin-top: 2.19rem;
-        padding-top: 2.19rem;
-        border-top: 0.06rem solid #EEEEEE;
         justify-content: center;
-
-        button {
-          display: flex;
-          align-items: center;
-          font-size: 0.88rem;
-          font-weight: 400;
-          color: #333;
-
-          &.blue-color {
-            &:after {
-              display: inline-block;
-              background: #E3E3E3;
-              width: 0.06rem;
-              height: 1rem;
-              content: "";
-              margin: 0 1rem;
-            }
+        gap: 1rem;
+        margin-bottom: 1.5rem;
+        
+        .text--btn {
+          background: none;
+          border: none;
+          color: #667eea;
+          font-size: 0.9rem;
+          font-weight: 500;
+          padding: 0.5rem 1rem;
+          border-radius: 8px;
+          transition: all 0.3s ease;
+          
+          &:hover {
+            background: rgba(102, 126, 234, 0.1);
+            color: #764ba2;
           }
-
-          &.blue-color {
-            color: #034EA2;
+        }
+      }
+      
+      .short--login--wrap {
+        display: flex;
+        justify-content: center;
+        gap: 1rem;
+        padding-top: 1.5rem;
+        border-top: 1px solid rgba(102, 126, 234, 0.2);
+        
+        .btn--google,
+        .btn--kakao,
+        .btn--naver {
+          width: 50px;
+          height: 50px;
+          border-radius: 50%;
+          border: 2px solid rgba(102, 126, 234, 0.2);
+          background-color: white;
+          transition: all 0.3s ease;
+          position: relative;
+          
+          &:hover {
+            transform: translateY(-2px);
+            box-shadow: 0 8px 25px rgba(0,0,0,0.1);
+            border-color: #667eea;
           }
         }
       }
@@ -3683,31 +3908,31 @@ p.success-txt {
   }
 
   .login-footer {
-    position: fixed;
+    position: absolute;
     bottom: 0;
     left: 0;
     right: 0;
-    width: 100%;
-    background: #fff;
+    height: 60px;
+    background: rgba(255,255,255,0.1);
+    backdrop-filter: blur(20px);
+    border-top: 1px solid rgba(255,255,255,0.1);
     display: flex;
-    justify-content: flex-end;
     align-items: center;
-    height: 3.63rem;
-    padding: 0 1.88rem;
-
-    p {
-      color: #333333;
-      opacity: 0.8;
-      font-size: 0.69rem;
-      font-weight: 400;
-    }
+    justify-content: space-between;
+    padding: 0 2rem;
+    z-index: 100;
 
-    .logo {
-      margin-left: 4.38rem;
-      width: 8.19rem;
-      height: 1.44rem;
-      background: url("../img/logo_foot.svg") no-repeat center / 100%;
-      font-size: 0;
+    .login--footer--l {
+      p {
+        color: rgba(255,255,255,0.8);
+        font-size: 0.8rem;
+        margin: 0;
+        
+        &:first-child {
+          font-weight: 500;
+          margin-bottom: 0.25rem;
+        }
+      }
     }
   }
 }

+ 1 - 0
backend/app/Config/Routes.php

@@ -9,6 +9,7 @@
   $routes->get('auth/callback', 'Auth::callback');
   $routes->post('auth/joinmember', 'Auth::join');
   $routes->post('auth/joinvendor', 'Auth::joinVendor');
+  $routes->post('auth/joinbrand', 'Auth::joinBrand');
   $routes->post('auth/withdrawal', 'Auth::withdrawal'); //구글 회원탈퇴 , 일반회원 탈퇴
   $routes->post('auth/kakaowithdrawal', 'Auth::kakaoWithdrawal'); //카카오 회웥탈퇴
   $routes->get('auth/kakaoLogin', 'Auth::kakaoLogin');

+ 69 - 5
backend/app/Controllers/Auth.php

@@ -15,7 +15,7 @@
   {
     private const FRONTEND_BASE_URL = "http://localhost:3000";
     
-  //private const FRONTEND_BASE_URL = 'https://shopdeli.mycafe24.com';
+    //private const FRONTEND_BASE_URL = 'https://shopdeli.mycafe24.com';
     protected $userModel;
     
     public function __construct()
@@ -289,10 +289,74 @@
         'message' => '회원가입이 완료되었습니다.'
       ])->setStatusCode(200);
     }
-    
-    
-    
-    //구글 로그인 환경 회원 탈퇴
+
+    public function joinBrand()
+      {
+          $postData = $this->request->getJSON(true);
+
+
+          // 필수값 추출
+          $id = $postData['ID'] ?? null;
+          $password = $postData['PASSWORD'] ?? null;
+          $name = $postData['NAME'] ?? null;
+          $company_name = $postData['COMPANY_NAME'] ?? null;
+          $company_number = $postData['COMPANY_NUMBER'] ?? null;
+          $hp = $postData['HP'] ?? null;
+          $email = $postData['EMAIL'] ?? null;
+
+
+
+          // 필수값 검증
+          if (empty($name) || empty($email)) {
+              return redirect()->back()->with('error', '필수 정보를 입력해 주세요.');
+          }
+
+          // insert용 데이터 준비
+          $insertData = [
+              'ID' => $id,
+              'PASSWORD' => $password,
+              'NAME' => $name,
+              'COMPANY_NAME' => $company_name,
+              'HP' => $hp,
+              'EMAIL' => $email,
+              'COMPANY_NUMBER' => $company_number
+          ];
+
+          if (!empty($password)) {
+              $insertData['PASSWORD'] = password_hash($password, PASSWORD_DEFAULT);
+          }
+
+          // DB 연결 및 INSERT
+          try {
+              $db = \Config\Database::connect();
+              $builder = $db->table('BRAND_LIST');
+              $result = $builder->insert($insertData);
+
+              if (!$result) {
+                  $error = $db->error();
+                  return $this->response->setJSON([
+                      'status' => 'fail',
+                      'message' => 'DB Error: '.$error['message']
+                  ])->setStatusCode(500);
+              }
+          } catch (\Throwable $e) {
+              return $this->response->setJSON([
+                  'status' => 'fail',
+                  'message' => 'Exception: ' . $e->getMessage()
+              ])->setStatusCode(500);
+          }
+
+
+          // 회원가입 성공 시, JSON 응답으로 결과 반환 (200 OK)
+          return $this->response->setJSON([
+              'status'  => 'success',
+              'message' => '회원가입이 완료되었습니다.'
+          ])->setStatusCode(200);
+      }
+
+
+
+      //구글 로그인 환경 회원 탈퇴
     public function withdrawal()
     {
       

+ 11 - 23
backend/app/Controllers/Item.php

@@ -19,40 +19,28 @@ class Item extends ResourceController
         $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
         $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
         $memberSeq = isset($request['MEMBER_SEQ']) ? $request['MEMBER_SEQ'] : null;
-        $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
 
-        // 쿼리 빌더
-        $builder = $db->table('ITEM_LIST')->where('DEL_YN', 'N');
+        // 쿼리 빌더 (VENDOR_LIST 조인 추가)
+        $builder = $db->table('ITEM_LIST I')
+            ->select('I.*, V.COMPANY_NAME')
+            ->join('VENDOR_LIST V', 'I.COMPANY_NUMBER = V.COMPANY_NUMBER', 'left')
+            ->where('I.DEL_YN', 'N');
 
         // 노출중, 비노출 여부 확인
-        if (!is_null($showYn) && $showYn !== '') {
-            $builder->where('SHOW_YN', $showYn);
-        }
-
-        $builder->where('TYPE', $itemType);
-
-        // INF_SEQ 조건 추가 (값이 있을 때만)
-        if (!empty($infSeq)) {
-            $builder->where('CONTACT_INF', $infSeq);
-        }
+        $builder->where('I.SHOW_YN', $showYn);
+        $builder->where('I.TYPE', $itemType);
 
         // 사용자 타입별 필터링
         if ($memberType === 'VENDOR' && !empty($companyNumber)) {
             // 벤더사의 경우: 자사 제품만 조회
-            $builder->where('COMPANY_NUMBER', $companyNumber);
+            $builder->where('I.COMPANY_NUMBER', $companyNumber);
         } elseif ($memberType === 'INFLUENCER' && !empty($memberSeq)) {
-            // 인플루언서의 경우: 파트너십이 체결된 벤더사의 제품만 조회
-            // VENDOR_INFLUENCER_PARTNERSHIP 테이블과 VENDOR_LIST를 통해 조인
-            $builder->select('ITEM_LIST.*, VIP.STATUS as PARTNERSHIP_STATUS');
-            $builder->join('VENDOR_LIST VL', 'ITEM_LIST.COMPANY_NUMBER = VL.COMPANY_NUMBER', 'inner');
-            $builder->join('VENDOR_INFLUENCER_PARTNERSHIP VIP', 'VL.SEQ = VIP.VENDOR_SEQ', 'inner');
-            $builder->where('VIP.INFLUENCER_SEQ', $memberSeq);
-            $builder->where('VIP.STATUS', 'APPROVED');
-            $builder->where('VIP.IS_ACTIVE', 'Y');
+            // 인플루언서의 경우: 공동구매 담당 제품만
+            $builder->where('I.CONTACT_INF', $memberSeq);
         }
 
         // 업데이트 날짜 기준으로 정렬
-        $builder->orderBy('ITEM_LIST.UDPDATE', 'DESC');
+        $builder->orderBy('I.REGDATE', 'DESC');
         $lists = $builder->get()->getResultArray();
 
         return $this->respond($lists, 200);

+ 3 - 0
backend/app/Models/LoginModel.php

@@ -23,6 +23,9 @@
         case 'influence':
           $tableName = 'USER_LIST';
           break;
+        case 'brand':
+          $tableName = 'BRAND_LIST';
+          break;
         default:
           throw new \InvalidArgumentException("Invalid login type provided: " . $loginType);
       }

+ 76 - 72
components/common/header.vue

@@ -90,7 +90,11 @@
     const currentUser = snsUser || authUser;
     let memberType = currentUser?.memberType || currentUser?.MEMBER_TYPE;
 
-    userName.value = currentUser?.NICK_NAME || currentUser?.companyName;
+    if (memberType === 'I'){
+      userName.value = currentUser?.NICK_NAME || currentUser?.name
+    } else {
+      userName.value =  currentUser?.companyName;
+    }
 
     // memberType이 없으면 URL로 판단
     if (!memberType) {
@@ -128,44 +132,44 @@
         {
           menuId: "menu01",
           parentMenuId: "menu01",
-          menuName: "제품 관리",
+          menuName: "공동구매",
           linkType: "/view/common/item",
         },
-        {
-          menuId: "menu02",
-          parentMenuId: "menu02",
-          menuName: "배송 관리",
-          linkType: "/view/common/deli",
-          subMenus: [
-            {
-              menuId: "menu02-1",
-              menuName: "배송 관리",
-              linkType: "/view/common/deli",
-            },
-            {
-              menuId: "menu02-2",
-              menuName: "배송중",
-              linkType: "/view/common/deli/shipping",
-            },
-            {
-              menuId: "menu02-3",
-              menuName: "배송완료",
-              linkType: "/view/common/deli/delivered",
-            },
-          ],
-        },
-        {
-          menuId: "menu03",
-          parentMenuId: "menu03",
-          menuName: "인플루언서 관리",
-          linkType: "/view/vendor/dashboard/influencer-requests",
-        },
-        {
-          menuId: "menu04",
-          parentMenuId: "menu04",
-          menuName: "정산 관리",
-          linkType: "/view/common/settlement",
-        },
+        // {
+        //   menuId: "menu02",
+        //   parentMenuId: "menu02",
+        //   menuName: "배송 관리",
+        //   linkType: "/view/common/deli",
+        //   subMenus: [
+        //     {
+        //       menuId: "menu02-1",
+        //       menuName: "배송 관리",
+        //       linkType: "/view/common/deli",
+        //     },
+        //     {
+        //       menuId: "menu02-2",
+        //       menuName: "배송중",
+        //       linkType: "/view/common/deli/shipping",
+        //     },
+        //     {
+        //       menuId: "menu02-3",
+        //       menuName: "배송완료",
+        //       linkType: "/view/common/deli/delivered",
+        //     },
+        //   ],
+        // },
+        // {
+        //   menuId: "menu03",
+        //   parentMenuId: "menu03",
+        //   menuName: "인플루언서 관리",
+        //   linkType: "/view/vendor/dashboard/influencer-requests",
+        // },
+        // {
+        //   menuId: "menu04",
+        //   parentMenuId: "menu04",
+        //   menuName: "정산 관리",
+        //   linkType: "/view/common/settlement",
+        // },
         {
           menuId: "menu05",
           parentMenuId: "menu05",
@@ -183,41 +187,41 @@
           menuName: "제품 관리",
           linkType: "/view/common/item",
         },
-        {
-          menuId: "menu02",
-          parentMenuId: "menu02",
-          menuName: "배송 관리",
-          linkType: "/view/common/deli",
-          subMenus: [
-            {
-              menuId: "menu02-1",
-              menuName: "배송 관리",
-              linkType: "/view/common/deli",
-            },
-            {
-              menuId: "menu02-2",
-              menuName: "배송중",
-              linkType: "/view/common/deli/shipping",
-            },
-            {
-              menuId: "menu02-3",
-              menuName: "배송완료",
-              linkType: "/view/common/deli/delivered",
-            },
-          ],
-        },
-        {
-          menuId: "menu03",
-          parentMenuId: "menu03",
-          menuName: "벤더 관리",
-          linkType: "/view/influencer/search",
-        },
-        {
-          menuId: "menu04",
-          parentMenuId: "menu04",
-          menuName: "정산 관리",
-          linkType: "/view/common/settlement",
-        },
+        // {
+        //   menuId: "menu02",
+        //   parentMenuId: "menu02",
+        //   menuName: "배송 관리",
+        //   linkType: "/view/common/deli",
+        //   subMenus: [
+        //     {
+        //       menuId: "menu02-1",
+        //       menuName: "배송 관리",
+        //       linkType: "/view/common/deli",
+        //     },
+        //     {
+        //       menuId: "menu02-2",
+        //       menuName: "배송중",
+        //       linkType: "/view/common/deli/shipping",
+        //     },
+        //     {
+        //       menuId: "menu02-3",
+        //       menuName: "배송완료",
+        //       linkType: "/view/common/deli/delivered",
+        //     },
+        //   ],
+        // },
+        // {
+        //   menuId: "menu03",
+        //   parentMenuId: "menu03",
+        //   menuName: "벤더 관리",
+        //   linkType: "/view/influencer/search",
+        // },
+        // {
+        //   menuId: "menu04",
+        //   parentMenuId: "menu04",
+        //   menuName: "정산 관리",
+        //   linkType: "/view/common/settlement",
+        // },
         {
           menuId: "menu05",
           parentMenuId: "menu05",

+ 42 - 40
pages/auth/join.vue

@@ -13,16 +13,10 @@
     <!-- login -->
     <div class="login-box type--join">
       <div class="login-r">
-        <h2 class="mk--title">{{ titleh }}</h2>
-        <!-- <div class="join--type">
-          <v-radio-group v-model="form.formValue0" row inline class="custom-radio type2">
-            <v-radio value="Y" label="인플루언스"></v-radio>
-            <v-radio value="N" label="벤더"></v-radio>
-          </v-radio-group>
-        </div> -->
+        <!-- <h2 class="mk--title"></h2> -->
         <div class="tit-login">
-          <strong>회원가입</strong>
-          <span><i>*</i>필수입력 항목</span>
+          <strong>{{ titleh }} 회원가입</strong>
+          <!-- <span><i>*</i>필수입력 항목</span> -->
         </div>
 
         <div v-show="form.formValue0 === 'Y'" class="login-input-wrap">
@@ -165,8 +159,7 @@
             ></v-text-field>
             <v-btn
               v-if="!useStore.getSnsTempData?.ID"
-              small
-              class="ml-2"
+              class="ml-2 custom-btn mini btn-white"
               @click="checkIdVendor"
               >중복확인</v-btn
             >
@@ -277,11 +270,17 @@
             >회원가입</v-btn
           >
           <v-btn
-            v-show="form.formValue0 === 'N'"
+            v-show="typeParam === 'vendor'"
             class="custom-btn btn-blue"
             @click.stop="joinMember('vendor')"
             >회원가입</v-btn
           >
+          <v-btn
+            v-show="typeParam === 'brand'"
+            class="custom-btn btn-blue"
+            @click.stop="joinMember('brand')"
+            >회원가입</v-btn
+          >
         </div>
       </div>
     </div>
@@ -299,9 +298,7 @@
   /************************
    *    import
    ************************/
-  import apiUrl from "@/composables/useApi";
-  import { useI18n } from "vue-i18n";
-  const { $log, $toast } = useNuxtApp();
+      const { $log, $toast } = useNuxtApp();
 
   /************************
    *    layout setting
@@ -313,7 +310,7 @@
   /************************
    *    전역
    ************************/
-  const titleh = ref("인플루언");
+  const titleh = ref("인플루언");
   const useStore = useAuthStore();
   const randomString = ref("");
 
@@ -480,7 +477,7 @@
     try {
       const response = await useAxios().post("/auth/checkId", {
         ID: formVendor.value.formValue1,
-        TYPE: "vendor",
+        TYPE: typeParam.value,
       });
 
       if (response.data.isDuplicate) {
@@ -511,12 +508,6 @@
           $toast.error("아이디를 입력해주세요.");
           return;
         }
-
-        const idRegex = /^[a-zA-Z0-9]{6,20}$/;
-        if (!idRegex.test(form.value.formValue1)) {
-          $toast.error("아이디는 영문, 숫자 조합 6~20자로 입력해주세요.");
-          return;
-        }
       }
     }
 
@@ -537,8 +528,19 @@
         GOOGLE_REFRESH_TOKEN: useStore.getSnsTempData?.GOOGLE_REFRESH_TOKEN || "",
         TYPE: useStore.getSnsTempData ? "1" : "0", // SNS 가입일경우 1, 일반회원 가입일경우 0
       };
-    } else {
+    } else if (id_type === "vendor") {
       _api = "/auth/joinvendor";
+      _req = {
+        ID: formVendor.value.formValue1,
+        PASSWORD: formVendor.value.formValue3,
+        COMPANY_NAME: formVendor.value.formValue4,
+        COMPANY_NUMBER: (randomString.value = generateRandomAlphanumeric(100)),
+        NAME: formVendor.value.formValue5,
+        HP: `${formVendor.value.formValue8}-${formVendor.value.formValue9}-${formVendor.value.formValue10}`,
+        EMAIL: formVendor.value.formValue12,
+      }
+    } else {
+      _api = "/auth/joinbrand";
       _req = {
         ID: formVendor.value.formValue1,
         PASSWORD: formVendor.value.formValue3,
@@ -586,30 +588,30 @@
       });
   };
 
+  /************************
+   *    반응형 변수
+   ************************/
+  const route = useRoute();
+  const typeParam = ref(route.query.type);
+
   /************************
    *    마운트
    ************************/
   onMounted(() => {
-    const route = useRoute();
-    const typeParam = route.query.type;
-    typeParam === "influence"
-      ? (form.value.formValue0 = "Y")
-      : (form.value.formValue0 = "N");
+    if(typeParam.value === "influence"){
+      (form.value.formValue0 = "Y");
+      titleh.value = "인플루언서"
+    } else if(typeParam.value === "vendor"){
+      (form.value.formValue0 = "N") ;
+      titleh.value = "벤더사"
+    } else {
+      (form.value.formValue0 = "N") ;
+      titleh.value = "브랜드사"
+    }
 
     if (useStore.getSnsTempData?.EMAIL) {
       form.value.formValue12 = useStore.getSnsTempData.EMAIL;
       form.value.formValue11 = "direct"; // 이메일 직접입력으로 설정
     }
   });
-
-  watch(
-    () => form.value.formValue0,
-    (newValue) => {
-      if (newValue === "Y") {
-        titleh.value = "인플루언서";
-      } else {
-        titleh.value = "벤더";
-      }
-    }
-  );
 </script>

+ 10 - 2
pages/index.vue

@@ -30,7 +30,6 @@
       <div class="login--header">
         <div class="login--header--l">
           <div class="logo">
-            <!-- prettier-ignore  -->
             SHOPDELI
           </div>
         </div>
@@ -109,6 +108,13 @@
               @click="loginAction(loginForm.userId, loginForm.passwd, 'vendor')"
               >로그인</v-btn
             >
+            <v-btn
+              v-else-if="loginForm.loginType == 'brand'"
+              class="custom-btn btn-blue"
+              @keyup.enter="loginAction(loginForm.userId, loginForm.passwd, 'brand')"
+              @click="loginAction(loginForm.userId, loginForm.passwd, 'brand')"
+              >로그인</v-btn
+            >
           </div>
           <div class="join--btn--wrap">
             <v-btn class="custom-btn text--btn">아이디 찾기</v-btn>
@@ -446,6 +452,8 @@
       loginForm.value.loginType = "influence";
     } else if (typeParam == "vendor") {
       loginForm.value.loginType = "vendor";
+    } else if (typeParam == "brand") {
+      loginForm.value.loginType = "brand"; 
     } else {
       loginVisible.value = "Y";
     }
@@ -493,7 +501,7 @@
   watch(
     () => route.query.type,
     (newType) => {
-      if (newType === "influence" || newType === "vendor") {
+      if (newType === "influence" || newType === "vendor" || newType === "brand") {
         loginForm.value.loginType = newType;
         loginVisible.value = "N"; // 로그인 폼 보이기
       } else {

+ 6 - 6
pages/view/common/cs/index.vue

@@ -82,12 +82,12 @@
           <div class="cs--list" v-if="csList.length > 0">
             <div v-for="(items, index) in paginatedItems" :key="index">
               <div class="list" @click="toItemDetail(items.SEQ)">
-                <span>{{ items.SEQ }}</span>
-                <span>{{ items.CATEGORY == 'D' ? '기능문의' : '기타문의' }}</span>
-                <span><strong>{{ items.NICK_NAME ? items.NICK_NAME : items.COMPANY_NAME }}</strong></span>
-                <span>{{ items.TITLE }}</span>
-                <span :class="getStatusClass(items.STATUS)">{{ items.STATUS == '0' ? "답변대기" : "답변완료" }}</span>
-                <span>{{ formatDate(items.REGDATE) }}</span>
+                <span class="list--seq">{{ items.SEQ }}</span>
+                <span class="list--circle">{{ items.CATEGORY == 'D' ? '기능문의' : '기타문의' }}</span>
+                <span class="list--writer">{{ items.NICK_NAME ? items.NICK_NAME : items.COMPANY_NAME }}</span>
+                <span class="list--title">{{ items.TITLE }}</span>
+                <span class="list--ml" :class="getStatusClass(items.STATUS)">{{ items.STATUS == '0' ? "답변대기" : "답변완료" }}</span>
+                <span class="list--date">{{ formatDate(items.REGDATE) }}</span>
               </div>
             </div>
           </div>

+ 52 - 67
pages/view/common/item/index.vue

@@ -70,7 +70,7 @@
     </div>
 
     <div class="data--list--wrap">
-      <div class="btn--actions--wrap">
+      <!-- <div class="btn--actions--wrap">
         <div class="left--sections">
           <v-btn class="custom-btn bdrs--10" :class="itemType == 'E' ? 'btn-pink' : 'btn-white'" @click="itemType = 'E'"
             ><i class="ico"></i>개별 배송</v-btn
@@ -84,55 +84,48 @@
             ><i class="ico"></i>제품 등록</v-btn
           >
         </div>
-      </div>
+      </div> -->
       <div class="item--list--wrap">
-        <div class="no--data" v-if="itemList.length == 0">
-          등록된 제품이 없습니다.
-        </div>
-        <div class="item--list" v-if="itemList.length > 0">
-          <div v-for="(items, index) in paginatedItems" :key="index" class="item">
-            <div v-if="itemType == 'E'" @click="toItemDetail(items.SEQ)" class="item-content">
-              <div class="item--img"><img v-if="items.THUMB_FILE" :src="`https://shopdeli.mycafe24.com/writable/uploads/item/thumb/${items.THUMB_FILE}`"></div>
-              <h3>{{ items.NAME }}</h3>
-              <p>공급가: {{ Number(items.PRICE1).toLocaleString() }}<br>판매가: {{ Number(items.PRICE2).toLocaleString() }}</p>
-              <span>등록일: {{ items.REGDATE.slice(0, 10) }}</span>
-              <span>업데이트 날짜: {{ items.UDPDATE.slice(0, 10) }}</span>
-              <div
-                v-if="items.STATUS == 1 || isRecentUpdate(items.UDPDATE)"
-                class="sold--out"
-                :class="{ 'blue--type': isRecentUpdate(items.UDPDATE) && items.STATUS != 1 }"
-              >
-                <span>
-                  {{ items.STATUS == 1 ? '품절' : '업데이트' }}
-                </span>
-              </div>
-            </div>
-            <div v-if="itemType == 'G'" @click="toItemDetail(items.SEQ)" class="item-content">
-              <div class="item--img"><img v-if="items.THUMB_FILE" :src="`https://shopdeli.mycafe24.com/writable/uploads/item/thumb/${items.THUMB_FILE}`"></div>
-              <h3>{{ items.NAME }}</h3>
-              <p>공급가: {{ Number(items.PRICE1).toLocaleString() }}<br>판매가: {{ Number(items.PRICE2).toLocaleString() }}</p>
-              <span>공동구매 기간</span>
-              <span>{{ items.ORDER_START_DATE.slice(0, 10) }} ~ {{ items.ORDER_END_DATE.slice(0, 10) }}</span><br></br>
-              <span>등록일: {{ items.REGDATE.slice(0, 10) }}</span>
-              <!-- <span>업데이트 날짜: {{ items.UDPDATE.slice(0, 10) }}</span> -->
-              <div
-                v-if="items.STATUS == 1 || isClosedOrder(items.ORDER_END_DATE)"
-                class="sold--out"
-              >
-                <span>
-                  종료
-                </span>
+        <div class="cs--list--wrap">
+          <div class="cs--header" v-if="memberType !== 'INFLUENCER'">
+            <h3>공동구매 등록</h3>
+            <v-btn class="custom-btn" @click="addLocated()">신규 등록</v-btn>
+          </div>
+          <div class="cs--header">
+            <h3>나의 공동구매</h3>
+          </div>
+          <div class="cs--list" v-if="itemList.length > 0">
+            <div v-for="(items, index) in paginatedItems" :key="index" class="">
+              <!-- <div v-if="itemType == 'E'" @click="toItemDetail(items.SEQ)" class="item-content">
+                <div class="item--img"><img v-if="items.THUMB_FILE" :src="`https://shopdeli.mycafe24.com/writable/uploads/item/thumb/${items.THUMB_FILE}`"></div>
+                <h3>{{ items.NAME }}</h3>
+                <p>공급가: {{ Number(items.PRICE1).toLocaleString() }}<br>판매가: {{ Number(items.PRICE2).toLocaleString() }}</p>
+                <span>등록일: {{ items.REGDATE.slice(0, 10) }}</span>
+                <span>업데이트 날짜: {{ items.UDPDATE.slice(0, 10) }}</span>
+                <div
+                  v-if="items.STATUS == 1 || isRecentUpdate(items.UDPDATE)"
+                  class="sold--out"
+                  :class="{ 'blue--type': isRecentUpdate(items.UDPDATE) && items.STATUS != 1 }"
+                >
+                  <span>
+                    {{ items.STATUS == 1 ? '품절' : '업데이트' }}
+                  </span>
+                </div>
+              </div> -->
+              <div v-if="itemType == 'G'" @click="toItemDetail(items.SEQ)" class="list">
+                <span class="list--seq">{{ items.SEQ }}</span>
+                <span class="list--writer">{{ items.COMPANY_NAME }}</span>
+                <h3 class="list--title">{{ items.NAME }}</h3>
+                <div class="list--circle list--ml" :class="[ items.STATUS == 0 ? 'status--on' : 'status--off' ]">
+                  {{ items.STATUS == 0 ? '진행중' : '마감' }}
+                </div>
+                <span class="list--date">{{ items.ORDER_START_DATE.slice(0, 10) }} ~ {{ items.ORDER_END_DATE.slice(0, 10) }}</span>
               </div>
             </div>
-            <div v-if="memberType === 'INFLUENCER'" class="item-actions">
-              <v-btn 
-                class="custom-btn btn-blue mini delivery-btn"
-                :disabled="items.STATUS == 1"
-                @click.stop="goToDeliveryDetail(items)"
-                :aria-label="`${items.NAME} 송장번호 등록`"
-              >
-                <i class="ico"></i>송장번호 등록
-              </v-btn>
+          </div>
+          <div class="cs--list" v-else>
+            <div class="no-data">
+              <h4>등록된 제품이 없습니다</h4>
             </div>
           </div>
         </div>
@@ -174,7 +167,7 @@ import dayjs from 'dayjs';
   /************************************************************************
 |    전역
  ************************************************************************/
-  const itemType = ref("E");
+  const itemType = ref("G");
   const memberType = useAtStore.auth.memberType;
   const searchModel = ref("");
   const selectedRange = ref('all');
@@ -196,7 +189,8 @@ import dayjs from 'dayjs';
   const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
   const router = useRouter();
   const pageId = computed(() => {
-    return memberType === 'INFLUENCER' ? '제품 관리 (파트너십)' : '제품 관리 (자사)';
+    return '공동구매 관리';
+    //return memberType === 'INFLUENCER' ? '제품 관리 (파트너십)' : '제품 관리 (자사)';
   });
   const itemList = ref([]);
   const itemsPerPage = 5;
@@ -283,27 +277,19 @@ import dayjs from 'dayjs';
   const itemListGet = async () => {
     let _req = {
       // Y : 노출, N : 비노출
-      SHOW_YN: "",
+      SHOW_YN: "Y",
       TYPE: itemType.value,
-      INF_SEQ: "",
+      INF_SEQ: useAtStore.auth.seq,
+      MEMBER_TYPE: memberType,
+      MEMBER_SEQ: useAtStore.auth.seq,
     };
 
-    if (memberType === "INFLUENCER") {
-      // 인플루언서의 경우: 파트너십이 체결된 제품만 조회 + 노출된 제품만
-      _req.SHOW_YN = "Y";
-      _req.MEMBER_TYPE = "INFLUENCER";
-      _req.MEMBER_SEQ = useAtStore.auth.seq;
-
-      if(itemType.value == 'G'){
-        _req.INF_SEQ = useAtStore.auth.seq;
-      }
-    } else {
-      // 벤더사의 경우: 자사 제품만 조회
-      _req.MEMBER_TYPE = "VENDOR";
+    if(memberType === "VENDOR"){
       _req.COMPANY_NUMBER = useAtStore.auth.companyNumber || "1";
-      console.log('벤더사 제품 조회 - COMPANY_NUMBER:', _req.COMPANY_NUMBER);
     }
 
+    console.log(_req);
+
     await useAxios()
       .post("/item/list", _req)
       .then((res) => {
@@ -318,7 +304,7 @@ import dayjs from 'dayjs';
       startDate: searchStartDate.value ? dayjs(searchStartDate.value).format('YYYY-MM-DD') : '',
       endDate: searchEndDate.value ? dayjs(searchEndDate.value).format('YYYY-MM-DD') : '',
       TYPE: itemType.value,
-      showYN: ""
+      showYN: "Y"
     };
     
     if (memberType === "INFLUENCER") {
@@ -370,8 +356,7 @@ import dayjs from 'dayjs';
 
   
   onMounted(() => {
-    // 스토어에서 값이 있으면 사용, 없으면 기본값 'E' 사용
-    itemType.value = useDtStore.boardInfo.itemType || 'E';
+    itemType.value = 'G'
     itemListGet();
 
     // 날짜 초기화